How do I get ClickOnce to uninstall the old version while installing the new version?

I was able to successfully package my ClickOnce installation into an Inno Setup install script so that I can deploy it as a single EXE file to my clients. This process works great and is relatively painless.

Now I have a new version of my application that I want to deploy. I updated the version, posted the changes to Visual Studio 2013 and repackaged them using Inno Setup. The installation process works great, except that the old version of my app stays installed and the file associations still point to this old version.

So, basically, I want to know if it is possible to force ClickOnce to initiate the deletion of the old version if it exists, and if so, how to do it? Is it possible to get Inno Setup to help with this, given that it doesn't actually perform the installation?

UPDATE:

I've done some additional research and it looks like Inno Setup can trigger uninstall for a previously installed ClickOnce application. I see the delete key in the registry under

/Microsoft/Windows/CurrentVersion/Uninstall/<some random looking hex code>

      

If there is a way to find out what the hex code above is, then I should run the uninstall in Inno Setup. However, I have looked at my solution and deployment files and I cannot find any links to it. Is there a way to find out what this value is? Or is it just randomly generated during installation and we don't know what it will be?

UPDATE 2:

I found the code below that (with some minor modifications) detects that my old version is installed using ClickOnce (assuming the GUID is static between installations).

[Code]
function GetUninstallString: string;
var
    sUnInstPath: string;
    sUnInstallString: String;
begin
    Result := '';
    sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\<hex value>'); //Your application GUID/ID
    sUnInstallString := '';
    RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
    Result := sUnInstallString;
end;

function IsUpgrade: Boolean;
begin
    Result := (GetUninstallString() <> '');
end;

function InitializeSetup(): Boolean;
var
    V: Integer;
    iResultCode: Integer;
    sUnInstallString: string;
begin

    Result := True; // In case when no previous version is found

    if RegValueExists(HKEY_CURRENT_USER,'Software\Microsoft\Windows\CurrentVersion\Uninstall\<hex value>', 'UninstallString') then  //Your application GUID/ID
    begin
        V := MsgBox(ExpandConstant('An old version was detected. Do you want to uninstall it?'), mbInformation, MB_YESNO); //Custom message if the application is installed
        if V = IDYES then
        begin
            sUnInstallString := GetUninstallString();
            sUnInstallString := RemoveQuotes(sUnInstallString);
            Log(sUnInstallString);
            Exec(ExpandConstant(sUnInstallString), '', '', SW_SHOW, ewWaitUntilTerminated, iResultCode);
            Result := True; //If you want to proceed after uninstall
        end
        else
            Result := False; //When older version present and not uninstalled
        end;
    end;
end;

      

Now the problem is that while it detects a write, EXEC doesn't actually execute the delete command. The line looks something like this:

rundll32.exe dfshim.dll,ShArpMaintain MyApp.application, Culture=neutral, PublicKeyToken=27f9444c7c87407a, processorArchitecture=msil

      

If I run this from the command line, it works fine, but nothing happens from within Inno Setup. I checked the returned result code and got a SysErrorMessage for it. It:

The system cannot find the file specified.

My guess is that it cannot find the MyApp.application file. I tried adding the working directory to the arguments, but it still doesn't work.

UPDATE 3:

It looks like ClickOnce can install the application to the Windows folder (I don't know why this might have happened). Maybe that's why the uninstall line works from the command line, but not from Inno Setup? If so, is there a way to get around this?

UPDATE 4:

Okay, the file not found error is too vague. I have no idea where the application is looking, or even what file it is looking for that it cannot find. Is there a way to get more information from Inno Setup to debug this issue? What can cause this command to fail when executed with Inno Setup? Why does this work from the command line?

UPDATE 5:

Since I was unable to resolve this issue, I decided to go with a temporary workaround. Instead of trying to automatically uninstall, I changed the version check to simply warn the user that the previous version must be uninstalled before they can continue.

It's not ideal, but hopefully this problem will go away with future versions. Especially since it now looks like we'll be moving from ClickOnce to Inno Setup for the entire installation process.

+3


source to share





All Articles