如何在安装新版本期间让ClickOnce卸载旧版本?

时间:2014-09-25 00:12:07

标签: .net clickonce inno-setup uninstall

我已成功将ClickOnce设置打包成Inno Setup安装脚本,因此我可以将其作为单个EXE文件部署到我的客户。这个过程很好,而且相对无痛。

现在我想要部署我的应用程序的新版本。我已经更新了版本,在Visual Studio 2013中发布了更改并再次使用Inno Setup将它们打包。安装过程正常,但我的应用程序的旧版本仍然安装,文件关联仍然指向旧版本。

所以基本上我想知道是否可以让ClickOnce触发旧版本的卸载(如果存在),如果存在,该怎么办?是否有可能让Inno Setup帮助解决这个问题,因为它实际上没有进行安装?

更新

我一直在做进一步的研究,看起来Inno Setup可能会触发先前安装的ClickOnce应用程序的卸载。我可以在

下的注册表中看到卸载密钥
/Microsoft/Windows/CurrentVersion/Uninstall/<some random looking hex code>

如果有办法知道上面的十六进制代码是什么,那么我应该在Inno Setup中触发卸载。但是,我查看了我的解决方案和部署文件,但我找不到任何引用。有没有办法知道这个价值是多少?或者它只是在安装时随机生成,我们无法知道它会是什么?

更新2:

我发现下面的代码(稍微修改一下)似乎检测到我使用ClickOnce安装的旧版本(假设GUID在安装之间是静态的)。

[Code]
function GetUninstallString: string;
var
    sUnInstPath: string;
    sUnInstallString: String;
begin
    Result := '';
    sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\<hex value>'); //Your application's 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's 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;

我现在遇到的问题是,当它检测到条目时,EXEC实际上并没有成功运行uninstall命令。字符串看起来像这样:

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

如果我从命令提示符运行它,它可以正常工作,但是从Inno Setup中没有任何反应。我检查了返回的结果代码并为其检索了SysErrorMessage。它是:

系统找不到指定的文件。

我猜它找不到MyApp.application文件。我已经尝试在参数中添加一个工作目录,但它仍然无效。

更新3:

看起来ClickOnce可能已将应用程序安装到windows文件夹中(我不知道为什么会发生这种情况)。这可能是卸载字符串从命令提示符,但不是从Inno安装程序工作的原因吗?如果是这样,有办法解决这个问题吗?

更新4:

好的,“找不到文件”错误太模糊了。我不知道应用程序在哪里查找,甚至不知道它找不到哪个文件。有没有办法从Inno Setup获取更多信息来调试此问题?使用Inno Setup执行时可能导致此命令失败的原因是什么?为什么它在命令提示符下工作?

更新5:

由于我无法解决这个问题,我决定采用临时解决方法。我没有尝试自动触发卸载,而是修改了版本检查,只是提醒用户必须先卸载以前的版本才能继续。

这并不理想,但希望这个问题会在未来的版本中消失。特别是因为现在看起来我们将从ClickOnce转移到让Inno Setup处理整个安装过程。

0 个答案:

没有答案