1

Execute/Run the following Inno code and I got error message. The file "c:\xxxx-runtime\unins000.exe" does exist.

Error message:

Unable to execute file:
"c:\xxxx-runtime\unins000.exe"
CreateProcess failed; code 267.
The directory name is invalid.

Inno code shown below:

[UninstallRun]
Filename: "{code:ARGetUninstallString}";
;Filename: {code:ARGetUninstallString};   -- same result

[Code]
function ARGetUninstallString(p: String): String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\xxxx_is1');
  sUnInstallString := '';
  if not RegQueryStringValue(HKEY_LOCAL_MACHINE, sUnInstPath, 'UninstallString', sUnInstallString) then
    RegQueryStringValue(HKEY_CURRENT_USER, sUnInstPath, 'UninstallString', sUnInstallString);
  Result := sUnInstallString;
end;

However, It works fine IF I replace

[UninstallRun]
Filename: "{code:ARGetUninstallString}";

With

[UninstallRun]
Filename: "c:\xxxx-runtime\unins000.exe";

Would any Inno expert knows what the issue is?

cnm
  • 113
  • 11
  • Note how in all existing questions about this topic, the `UninstallString` is split to program path and arguments. With program path being wrapped in double quotes, that need to be removed. – Martin Prikryl Jul 13 '18 at 16:31
  • Thanks for comment, Martin. I found the problem - In my script [Run] section, I install an application which will write to Registry. The [UninstallRun] actually executes during setup, at this time the application in [Run] section has not been executed and so the reg is not being updated. The sUnInstallString (or Result) contains the empty string. I am still trying to find a solution. – cnm Jul 16 '18 at 14:31

2 Answers2

0

As you have found yourself, {code:} constant is evaluated on install time.

So instead, implement your code completely in [Code] section, not using [UninstallRun] section.

[Code]

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usPostUninstall { or usUninstall } then
  begin
    { Use RegQueryStringValue and Exec here }
  end;
end;

Though you need to fix your code that resolves command-line for uninstaller. Note how in all existing questions about this topic, the UninstallString is split to program path and arguments. With program path being wrapped in double quotes, that need to be removed.

See Executing UninstallString in Inno Setup.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
0

The following is my solution, basically execute the xxxxx-runtime.exe in the [code] section before getting the path from the reg. Following is source code:

[Files]              
Source: ".\xxxxx-runtime.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall

[UninstallRun]
Filename: {code:GetUninstallString}; BeforeInstall: SetUninstallString; RunOnceId: {code:GetUninstallString}

[Code]
var
uninstallString: String;

function getUninstallString(p: String): String;
begin
  Result := uninstallString;
end;

// execute xxxxx-runtime.exe
procedure exe();
var
  iResultCode: Integer;
begin
  Exec(ExpandConstant('{tmp}\xxxxx-runtime.exe'), '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode);
end;

procedure SetUninstallString();
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  exe();
  sUnInstPath := ExpandConstant('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\xxxxx_is1');
  sUnInstallString := '';
  if not RegQueryStringValue(HKEY_LOCAL_MACHINE, sUnInstPath, 'UninstallString', sUnInstallString) then
    RegQueryStringValue(HKEY_CURRENT_USER, sUnInstPath, 'UninstallString', sUnInstallString);
  uninstallString := RemoveQuotes(sUnInstallString);
end;
cnm
  • 113
  • 11