Inno Setup 可以发送按键和鼠标按键,如果不能,如何使用安装程序来完成?
Posted
技术标签:
【中文标题】Inno Setup 可以发送按键和鼠标按键,如果不能,如何使用安装程序来完成?【英文标题】:Can Inno Setup send key and mouse presses, if not, how can this be done using an Installer? 【发布时间】:2013-02-07 01:15:11 【问题描述】:我是 [Microsoft Windows] 安装程序和 Inno Setup 的新手,但我需要知道是否可以使用 Inno Setup(或等效程序)在安装期间自动输入基于 GUI 的 Windows 程序,例如例如,通过单击菜单并选择子项?
我知道AutoIt 和AutoHotkey 以及NSIS,但是强烈推荐使用 Inno Setup 作为软件包/安装程序,我也喜欢学习一点 Pascal 编程的想法,讨价还价;)
欢迎任何想法或想法:-)
【问题讨论】:
如果你想控制 InnoSetup 安装程序,就去做吧。它是一个标准的 Windows 应用程序(通常运行提升,对于您提到的 GUI 自动化程序应该不是问题)。如果您要通过安装程序控制某些应用程序,那么您要么是黑客,要么您做错了什么:-) 在后一种情况下,请详细说明您这样做的意图,以便我们改进您的设计。跨度> @TLama - 没有黑客,只需要启动/配置一个没有命令行/配置文件/注册表条目的应用程序。通常,用户会手动启动应用程序,我们只是试图帮助非技术用户。理想情况下,如果应用程序的 GUI 可以被静默调用(是的,我知道这听起来确实有点骇人听闻),那就太好了,这个应用程序只是作为另一个应用程序的“加密狗”,但需要处于运行和配置状态在主应用程序启动之前。我可能看错了,需要在安装后设计一个单独的自动化(???) 如果需要,您可以从 Inno 启动 AutoIt 脚本。但正如 TLama 所说,这种事情通常是不得已而为之——最好找到合适的设置位置或参数来自动安装重新打包的应用程序。 【参考方案1】:我同意@Deanna,SendInput
函数是模拟用户输入的最佳选择。在下面的脚本中,我展示了如何在绝对屏幕位置(以像素为单位)上模拟鼠标点击。例如,我试图通过 Help / About Inno Setup 菜单项显示 Inno Setup 的 about 框(如果您的屏幕设置与我相同并且 Inno Setup IDE 最大化,它可能甚至点击那个菜单项。所以这里只是鼠标部分(你只能获得有限的功能)。把它作为一个证据,它可以模拟来自 Inno Setup 的用户输入:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName=pf\My Program
OutputDir=userdocs:Inno Setup Examples Output
[code]
const
SM_CXSCREEN = 0;
SM_CYSCREEN = 1;
INPUT_MOUSE = 0;
MOUSEEVENTF_MOVE = $0001;
MOUSEEVENTF_LEFTDOWN = $0002;
MOUSEEVENTF_LEFTUP = $0004;
MOUSEEVENTF_RIGHTDOWN = $0008;
MOUSEEVENTF_RIGHTUP = $0010;
MOUSEEVENTF_MIDDLEDOWN = $0020;
MOUSEEVENTF_MIDDLEUP = $0040;
MOUSEEVENTF_VIRTUALDESK = $4000;
MOUSEEVENTF_ABSOLUTE = $8000;
type
TMouseInput = record
Itype: DWORD;
dx: Longint;
dy: Longint;
mouseData: DWORD;
dwFlags: DWORD;
time: DWORD;
dwExtraInfo: DWORD;
end;
function GetSystemMetrics(nIndex: Integer): Integer;
external 'GetSystemMetrics@user32.dll stdcall';
function SendMouseInput(nInputs: UINT; pInputs: TMouseInput;
cbSize: Integer): UINT;
external 'SendInput@user32.dll stdcall';
function SendMouseClick(Button: TMouseButton; X, Y: Integer): Boolean;
var
Flags: DWORD;
Input: TMouseInput;
ScreenWidth: Integer;
ScreenHeight: Integer;
begin
Result := False;
Flags := MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_VIRTUALDESK or MOUSEEVENTF_MOVE;
ScreenWidth := GetSystemMetrics(SM_CXSCREEN);
ScreenHeight := GetSystemMetrics(SM_CYSCREEN);
Input.Itype := INPUT_MOUSE;
Input.dx := Round((X * 65536) / ScreenWidth);
Input.dy := Round((Y * 65536) / ScreenHeight);
case Button of
mbLeft: Input.dwFlags := Flags or MOUSEEVENTF_LEFTDOWN;
mbRight: Input.dwFlags := Flags or MOUSEEVENTF_RIGHTDOWN;
mbMiddle: Input.dwFlags := Flags or MOUSEEVENTF_MIDDLEDOWN;
end;
Result := SendMouseInput(1, Input, SizeOf(Input)) = 1;
if Result then
begin
Input.Itype := INPUT_MOUSE;
Input.dx := Round((X * 65536) / ScreenWidth);
Input.dy := Round((Y * 65536) / ScreenHeight);
case Button of
mbLeft: Input.dwFlags := Flags or MOUSEEVENTF_LEFTUP;
mbRight: Input.dwFlags := Flags or MOUSEEVENTF_RIGHTUP;
mbMiddle: Input.dwFlags := Flags or MOUSEEVENTF_MIDDLEUP;
end;
Result := SendMouseInput(1, Input, SizeOf(Input)) = 1;
end;
end;
procedure InitializeWizard;
begin
if MsgBox('Are you sure you want to let the installer click ' +
'somewhere on your screen ? TLama warned you :-)', mbConfirmation,
MB_YESNO) = IDYES then
begin
if not SendMouseClick(mbLeft, 242, 31) then
MsgBox(SysErrorMessage(DLLGetLastError), mbError, mb_Ok);
if not SendMouseClick(mbLeft, 382, 263) then
MsgBox(SysErrorMessage(DLLGetLastError), mbError, mb_Ok);
end;
end;
【讨论】:
谢谢你,真的,我唯一的问题是你提到了绝对像素位置,我认为我真正需要的是更具声明性的东西,即单击菜单 X,选择选项 Y,所以我不必关心项目实际在屏幕上的位置。正如我所说,我一般是安装程序的新手,所以我可能会以错误的方式解决这个问题。我真的想要一个多合一的工具,但也许我应该只使用 Inno Setup 来安装软件,而使用 AutoIt 之类的工具来实现 UI 自动化。你和@Deanna 怎么说? 不幸的是,我不知道任何库,它会作为独立的(所以我们可以将它导入到 InnoSetup 中)并且能够做你想做的事情。从 Windows 的角度来看,开发这种自动化软件将是一项非常艰巨的任务。但回到你的第一条评论。你说过你需要配置某个应用程序,所以我假设这个应用程序以某种方式保存了配置。你不能吗?更改此配置。并要求用户使用类似 Your application config has been updated and my application requires you restart it. 之类的消息重新启动它。 您实际上可以使用 AutoIt 来执行安装工作并将整个脚本打包成可执行文件。因此,最好将 AutoIt 与它的 FileInstall 功能和 Control...-功能一起使用。有关好的示例,请参阅这些函数的文档。而且 AutoIt 有一个基本的代码结构,所以它可能是您正在寻找的解决方案。 @Johannes,但是您可以使用嵌入式 AutoIt 分发设置吗?我的意思是,这合法吗? 这取决于您要重新打包的程序的许可证...我怎么知道? ;-) 您可以让脚本将设置提取到您的临时文件夹并在后台运行它(使用带有@SW_HIDE 的 WinSetState,然后使用一些 Control...-Functions 来自动安装),然后执行进一步的步骤,例如单击某处如前所述。【参考方案2】:最好的办法是使用 DLL 中的 SendInput()
API,然后从 Inno Setup 调用该 API。
这将允许您完全控制您可以在该应用程序中手动执行的所有操作。
【讨论】:
以上是关于Inno Setup 可以发送按键和鼠标按键,如果不能,如何使用安装程序来完成?的主要内容,如果未能解决你的问题,请参考以下文章