Can Inno Setup send key and mouse presses, if not, how can this be done using an Installer?

雨燕双飞 提交于 2019-12-10 11:25:40

问题


I'm a newbie to both [Microsoft Windows] installers and Inno Setup but I need to know if Inno Setup (or an equivalent) can be used automate the input to a GUI-based windows program, during install, e.g. by clicking on a menu and selecting a sub-item, for instance?

I'm aware of AutoIt and AutoHotkey, as well as NSIS, however Inno Setup comes highly recommended as a software packager/installer, and I also like the idea of learning a little Pascal programming, into the bargain ;)

Any ideas or thoughts are most welcome :-)


回答1:


I agree with @Deanna, the SendInput function is the best for simulating user input you can get. In the following script I've shown how to simulate mouse clicks on the absolute screen position (in pixels). As an example I'm trying to show Inno Setup's about box through the Help / About Inno Setup menu item (if you would have the same screen settings as me and have the Inno Setup IDE maximized, it may even hit that menu item. So here's just the mouse part (and only limited functionality you can get). Take it rather as a proof, that it's possible to simulate user input from 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;



回答2:


The best bet for this is to use the SendInput() API from a DLL that you then call from Inno Setup. This will allow full control of everything you can do manually in that application.



来源:https://stackoverflow.com/questions/14741933/can-inno-setup-send-key-and-mouse-presses-if-not-how-can-this-be-done-using-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!