Can Inno Setup send keystrokes and mouse presses, if not, how can this be done using the installer?

I'm new to [Microsoft Windows] and Inno Setup installations , but I need to know if Inno Setup (or equivalent) can be used to automate GUI-based input to a windowed program, during installation, for example by clicking on the menu and by selecting a subitem?

I know AutoIt and AutoHotkey as well as NSIS , however Inno Setup is highly recommended as a software package / installer and I also like the idea of ​​learning a little Pascal programming in a deal;)

Any ideas or thoughts are appreciated :-)

+3


source to share


2 answers


I agree with @Deanna, the function SendInput

is the best one you can get to simulate user input. In the following script, I have shown how to simulate mouse clicks at the absolute screen position (in pixels). As an example, I am trying to show the Inno Setup window through the window using the Help / About Inno Setup menu item (if you had the same screen settings as mine and had the maximum IDE Inno Setup setup, it might even touch that menu item here is just part of the mouse (and only limited functionality you can get) Take it more as proof that it is 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;

      

+3


source


Your best bet is to use the API SendInput()

from a DLL that you call from Inno Setup. This will give you complete control over everything that you can do manually in this application.



+1


source







All Articles