There appears to be no information on this anywhere that I can find and I'd rather not wait until it happens again before I can start to piece things together. Unfortunately, therefore, this is a slightly broader question than I would normally like to post, but as I have yet to pin down the cause, reproduce it, collect complete details and document it fully, I can only wait until it next occurs to be able collect and provide further information. So, based on what I do know, I am hoping someone might be able to shed some light on this.
It seems that in some cases, Inno Setup will require a restart to complete that requires an Administrator to login following that restart. I believe it is related to file registrations, possibly in System32
, that couldn't be done at the time of the install due to other changes already pending.
On the occasions this has happened there have been (I think) three randomly named (similar to the randomly generated {temp}
constant) files in the Windows
directory that I (retrospectively, after some thought) assume must be tied to a RunOnce
Registry key (which I will look for the next time I see this happen), that I (again) assume run following login as an Administrator to complete the installation. It appears that they do not run until an Administrator logs in, leaving the installation in an incomplete state if a standard user logs in. Once an Administrator logs in these files disappear and the installed application works as expected, rather than giving a:
Class not Registered
error that appears when the application is run before an Administrator logs in and allows the installation to complete fully.
What I want to do is find a way to ensure the installation completes fully, regardless of the privileges of the user that logs in after reboot, as if the application is centrally deployed (e.g. via SCCM), there will be no Administrator available to login at the PC and the application won't run until one does (which defeats the point of using something like SCCM). I am actually quite surprised that Inno Setup does not take care of this automatically, by setting the files to run as the SYSTEM
account on next logon or some similar method.
If someone can explain roughly what is happening here, how to find out the names of the files (I could possibly do this by reading the RunOnce
Registry key, but I would need to know the name of the value I need to read) and what needs to be done to run them and complete the installation, I should be able to take care of this by, for example, using a Scheduled Task to run as SYSTEM
at logon, or some other method.
You are correct in your assumptions.
When Inno Setup needs to register some files, but it also figures out, that it needs to restart the machine to complete some installations, it will defer the registration until after the restart. Even if the actual file, that needs to be registered, was successfully installed.
Inno Setup will create a registry key like:
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\RunOnce]
"InnoSetupRegFile.0000000001"="\"C:\\WINDOWS\\is-NGP70.exe\" /REG /REGSVRMODE"
And files like:
C:\Windows\is-NGP70.exe
C:\Windows\is-NGP70.lst
C:\Windows\is-NGP70.msg
Where the .lst
file contains list of files to be registered:
[s.]C:\Program Files (x86)\My Program\MyClass.dll
Note that the is-???
name is random, and is not same as the temporary folder of the installer.
In a log file, you will see:
2016-10-22 18:13:06.439 Delaying registration of all files until the next logon since a restart is needed.
2016-10-22 18:13:06.441 Registration executable created: C:\Users\martin\AppData\Local\Temp\is-NGP70.exe
Indeed, when the installer is run with Administrator privileges, the is-???.exe
will silently do nothing, when a non-Administrator logs in.
But if you run the installer with non-Administrator privileges, the files will be written to %TEMP%
; the key to HKCU\...\RunOnce
; and a /REGU
switch is used instead of the /REG
switch; and the registration will proceed for any user.
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce]
"InnoSetupRegFile.0000000001"="\"C:\\Users\\user\\AppData\\Local\\Temp\\is-S5KU2.exe\" /REGU /REGSVRMODE"
To easily test the scenario, just create a simple installer that registers any .dll
and set the AlwaysRestart=yes
:
[Setup]
AlwaysRestart=yes
[Files]
Source: "MyClass.dll"; DestDir: "{app}"; Flags: regserver
If the restart is needed due to other files, not the file that needs registration, you may consider registering the .dll
in Code
using the RegisterServer
function, to avoid the delayed registration.
RegisterServer(Is64Bit, ExpandConstant('{app}\MyClass.dll'), False);
For an example of using the above statement, see How to remove Abort from Inno Setup regserver error?
Alternatively, as you already suggested yourself, you can use Window Scheduler to schedule a "onlogon" task with Administrator privileges to run the is-???.exe
file.
See How to make the program run on startup with admin permission with Inno Setup?
You might use the [Run]
section entry to run the schtasks
(as my answer to the above question shows), as the section is processed only after the RunOnce
entry is created. But you will also need to remove the RunOnce
entry. And that you cannot do in the [Registry]
section, as that has been processed already. You will need to code this in a Pascal Script. Then it's probably better to do both in the code.
You can run the schtasks
(using the Exec
function) and remove the entry (using the RegDeleteValue
function) from the CurStepChanged(ssPostInstall)
event function.
You will also need to delete the task. Maybe you can use the /Z
switch to "mark the task for deletion after its final run". But I'm not sure this can be combined with the /SC onlogon
. If not, you need to run schtasks /Delete
as part of the task.