I'm writing a function that will install a required component for my appliance, which is built upon PowerShell. If a specific version of PowerShell is not found, I want the installer to help the user install it. The problem I'm running into is how to appropriately call the offline installer for installation. Here is the code I have, which is a generic function (I am using the InnoSetup Dependency Installer):
function SmartExec(product : TProduct; var resultcode : Integer): boolean;
begin
if (LowerCase(Copy(product.File, Length(product.File) - 2, 3)) = 'exe') then begin
Result := Exec(product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
end else begin
Result := ShellExec('', product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
end;
end;
I have tried using the following:
function SmartExec(product : TProduct; var resultcode : Integer): boolean;
begin
if (LowerCase(Copy(product.File, Length(product.File) - 2, 3)) = 'exe') then begin
Result := Exec(product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
end else if (LowerCase(Copy(product.File, Length(product.File) - 2, 3)) = 'msu') then begin
Result := ShellExec('', 'wusa.exe ' + product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
end else begin
Result := ShellExec('', product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
end;
end;
When I compile and test the installer, I'm greeted with:
I am passing /quiet /norestart
as parameters to the MSU file, which execute perfectly from a command prompt.
The installation file is downloaded to %tmp%
for the current user, and I see the file.
Any help or comments?
The .msu
extension is associated with wusa.exe
, so the existing branch ShellExec('', product.File, ...)
should do the job. You should not need to add a specific msu
branch.
Anyway, the specific branch can help with the debugging, so it's worth trying.
The second parameter of ShellExec
function is a FileName
, while you pass in wusa.exe xxx.msu
, what is not a valid file name.
This should work:
Result := ShellExec('', 'wusa.exe', product.File + ' ' + product.Parameters, ...);
Though using the ShellExec
to run an executable is an overkill, use plain Exec
function instead:
Result := Exec('wusa.exe', product.File + ' ' + product.Parameters, ...);
When the Exec
returns False
, the ResultCode
is a Windows error code explaining why the execution failed. You are getting code 3, what is ERROR_PATH_NOT_FOUND
(The system cannot find the path specified.).
So it looks like the path you are using (product.File
) is not valid.
Make sure you pass in a full path to the .msu
, not just a filename.
Try logging the path before calling the Exec
and check if the file exists. You can use:
Log(Format('Path is [%s], Exists = %d', [product.File, Integer(FileExists(product.File))]));