0

I'm not exactly sure that setting a delay is what will solve this problem, but it's my best guess. So here goes:

I'm using Inno Setup to wrap a Squirrel-built installer, using Inno to build a self-extractor (no uninstall). Squirrel handles the actual install/uninstall configurations. The reason I'm using Inno at all is that I need to set the SQUIRREL_TEMP user environment variable, prior to running the Squirrel-built installer, so as to override Squirrel's default installation path.

I'm able to set this variable successfully, using the code below. The trouble appears to be that the environment refresh call runs asynchronously, allowing the Squirrel-built installer to start prior to the actual refresh. Thus the installer isn't seeing that variable.

As you can see, I've tried calling SendTextMessageTimeout() with a timeout of as long as 30 seconds, but altering that value never changes anything.

The odd thing is that sometimes (rarely) it works. Intermittently, maybe 1 out of 20-30 times, the installer is able to pick up the value I've specified.

I've tried variations of the two approaches found in this Q&A, but both suffer from the problem. The logs don't contain anything helpful toward this.

How can I pause to allow sufficient time for the refresh to occur before the Squirrel-built installer runs?

--Setup.iss--

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "MyApp"
#define MyAppVersion "1.0"
#define MyAppPublisher "Company"
#define MyAppURL "https://www.company.com/"
#define MyAppExeName "MyApp Setup.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{2F651F6A-6F25-4B73-BC69-C2DC1E04420F}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
CreateAppDir=no
Uninstallable=no
; Remove the following line to run in administrative install mode (install for all users.)
PrivilegesRequired=lowest
OutputBaseFilename={#MyAppExeName}
OutputDir=D:\MyApp\bin\Output
SetupIconFile=D:\MyApp\Resources\Icons\MyApp.ico
Compression=lzma
SolidCompression=yes
WizardStyle=modern
SetupLogging=yes

[Messages]
ReadyLabel2b=Click Install to install and run the application.

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Files]
Source: "D:\MyApp\bin\Deploy\Setup.exe"; DestDir: "{tmp}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Run]
Filename: "{tmp}\Setup.exe"; WorkingDir: {tmp}; BeforeInstall: SetVariableAndRefresh

[Code]
const
  SMTO_ABORTIFHUNG = 2;
  WM_WININICHANGE = $001A;

type
  WPARAM = UINT_PTR;
  LPARAM = INT_PTR;
  LRESULT = INT_PTR;
  
function SendTextMessageTimeout(hWnd: HWND; Msg: UINT;
  wParam: WPARAM; lParam: PAnsiChar; fuFlags: UINT;
  uTimeout: UINT; out lpdwResult: DWORD): LRESULT;
  external 'SendMessageTimeoutA@user32.dll stdcall';  
  
procedure SetVariable;
begin
  RegWriteStringValue(HKCU, 'Environment', 'SQUIRREL_TEMP', ExpandConstant('{localappdata}\Company'))
end;

procedure RefreshEnvironment;
var
  S: AnsiString;
  MsgResult: DWORD;
begin
  S := 'Environment';
  SendTextMessageTimeout(HWND_BROADCAST, WM_WININICHANGE, 0, PAnsiChar(S), SMTO_ABORTIFHUNG, 30000, MsgResult);
end;

procedure SetVariableAndRefresh;
begin
  SetVariable;
  RefreshEnvironment;
end;

--Log--

2020-07-14 18:04:27.574   Log opened. (Time zone: UTC-08:00)
2020-07-14 18:04:27.574   Setup version: Inno Setup version 6.0.5 (u)
2020-07-14 18:04:27.574   Original Setup EXE: D:\MyApp\bin\Output\MyApp Setup.exe
2020-07-14 18:04:27.574   Setup command line: /SL5="$2F1E3E,4626978,911872,D:\MyApp\bin\Output\MyApp Setup.exe" 
2020-07-14 18:04:27.574   Windows version: 10.0.18363  (NT platform: Yes)
2020-07-14 18:04:27.574   64-bit Windows: Yes
2020-07-14 18:04:27.574   Processor architecture: x64
2020-07-14 18:04:27.574   User privileges: None
2020-07-14 18:04:27.577   Administrative install mode: No
2020-07-14 18:04:27.578   Install mode root key: HKEY_CURRENT_USER
2020-07-14 18:04:27.578   64-bit install mode: No
2020-07-14 18:04:27.584   Created temporary directory: C:\Users\Work\AppData\Local\Temp\is-LT2DN.tmp
2020-07-14 18:04:27.594   -- DLL function import --
2020-07-14 18:04:27.594   Function name: SendMessageTimeoutA
2020-07-14 18:04:27.594   DLL name: user32.dll
2020-07-14 18:04:27.594   Dest DLL name: user32.dll
2020-07-14 18:04:27.594   Importing the DLL function.
2020-07-14 18:04:27.594   Successfully imported the DLL function. Delay loaded? No
2020-07-14 18:04:29.801   Found 1 files to register with RestartManager.
2020-07-14 18:04:29.801   Calling RestartManager's RmGetList.
2020-07-14 18:04:29.812   RmGetList finished successfully.
2020-07-14 18:04:29.812   RestartManager found no applications using one of our files.
2020-07-14 18:04:29.839   Starting the installation process.
2020-07-14 18:04:29.845   -- File entry --
2020-07-14 18:04:29.845   Dest filename: C:\Users\Work\AppData\Local\Temp\is-LT2DN.tmp\Setup.exe
2020-07-14 18:04:29.847   Time stamp of our file: 2020-07-14 17:10:22.000
2020-07-14 18:04:29.847   Installing the file.
2020-07-14 18:04:30.297   Successfully installed the file.
2020-07-14 18:04:30.299   -- Registry entry --
2020-07-14 18:04:30.299   Key: HKEY_CURRENT_USER\Environment
2020-07-14 18:04:30.299   Value name: SQUIRREL_TEMP
2020-07-14 18:04:30.299   Creating or opening the key.
2020-07-14 18:04:30.299   Creating or setting the value.
2020-07-14 18:04:30.299   Successfully created or set the value.
2020-07-14 18:04:30.300   Installation process succeeded.
2020-07-14 18:04:31.990   -- Run entry --
2020-07-14 18:04:31.990   Run as: Current user
2020-07-14 18:04:31.990   Type: Exec
2020-07-14 18:04:31.990   Filename: C:\Users\Work\AppData\Local\Temp\is-LT2DN.tmp\Setup.exe
2020-07-14 18:04:40.221   Process exit code: 0
2020-07-14 18:04:40.242   Need to restart Windows? No
2020-07-14 18:04:49.285   Deinitializing Setup.
2020-07-14 18:04:49.333   Log closed.
InteXX
  • 6,135
  • 6
  • 43
  • 80
  • 1
    Why are you writing the variable to registry, if it is only a temporary one? Use `SetEnvironmentVariable`. See the @TLama's answer at https://stackoverflow.com/q/21708140/850848. – Martin Prikryl Jul 15 '20 at 05:12
  • I was writing to the user-scoped environment variable key (`HKCU\Environment`) in hopes of setting `SQUIRREL_TEMP` prior to running `Setup.exe`. That only worked very sporadically. TLama also states: "a notification about the environment changes is performed after the [Run] section is processed," which is why I'd previously skipped the version with `SetEnvironmentVariable{#AW}@kernel32.dll`. However, I tried it just now and it works. It sets the variable as process-scoped instead of user-scoped, so Squirrel's ability to see it is unexpected. But as long as it works I'm in a good mood. Thanks. – InteXX Jul 15 '20 at 11:00
  • 1
    If you'd like to post your suggestion as an answer, I'll be happy to accept it. You inspired me to have another look at it, and now the problem is solved. – InteXX Jul 15 '20 at 11:02
  • You are welcome. Alternatively, [my solution with `set`](https://stackoverflow.com/q/21708140/850848#43392128) will also work in your scenario (without `postinstall`). – Martin Prikryl Jul 15 '20 at 11:12
  • Looks good, I'll give that one a try as well. – InteXX Jul 15 '20 at 12:01

0 Answers0