2013-07-14 60 views
2

在Inno Setup中卸载相关产品我们公司已从使用InstallShield Express切换到使用Inno Setup(5.5.2版本)。我们已经使用InstallShield进行了多年的旧安装,但始终依靠InstallShield的升级代码GUID来处理先前版本的卸载。如何使用InstallShield升级代码GUID

我需要能够从我们新的Inno Setup安装程序中卸载任何以前的InstallShield安装版本。

经过一番研究,看起来我需要调用MsiEnumRelatedProducts(),然后卸载找到的任何产品。

我发现此链接http://www.microsofttranslator.com/bv.aspx?from=de&to=en&a=http%3A%2F%2Fwww.inno-setup.de%2Fshowthread.php%3Fs%3D415e3895fda3e26e42739b004c0f51fb%26t%3D2857(原文为德文http://www.inno-setup.de/showthread.php?s=415e3895fda3e26e42739b004c0f51fb&t=2857)。看起来他非常接近,但他从未发布他的最终解决方案。

代码,他说作品(但崩溃对我来说):

type 
    TProductBuf = array[0..39] of char; 

function MsiEnumRelatedProducts(lpUpgradeCode:string; 
    dwReserved, iProductIndex:cardinal; 
    var lpProductBuf:TProductBuf) : cardinal; 
external '[email protected] setuponly stdcall'; 

function InitializeSetup : boolean; 
var 
    ret, i, j : cardinal; 
    ProductBuf : TProductBuf; 
    ProductCode : string; 

begin 
    Result := true; 
    i := 0; 
    repeat 
    ret := MsiEnumRelatedProducts('{#UPGRADE_CODE}', 0, i, ProductBuf); 
    if ret=0 then 
    begin 
     ProductCode := ''; 
     for j := 0 to 39 do 
     begin 
     if ProductBuf[j] = #0 then 
      break; 
     ProductCode := ProductCode + ProductBuf[j]; 
     end; 
     Result := uninstallOther(ProductCode); 
    end; 
    i := i+1; 
    until ret <> 0; 
end; 

他说,这使得它更容易?

SetLength(ProductCode, Pos(#0, ProductCode) - 1); 

我是Pascal脚本编程的新手,我在整个SetLength()部分卡住了。在他所说的功能中它取代了什么,但是崩溃了?

因为其他人说,切换到字符串,我应该摆脱这样的:

type 
    TProductBuf = array[0..39] of char; 

如果有人能告诉我在英语的最终工作的功能,这将是真棒!

在此先感谢!

编辑: 我使用ANSI版本的Inno Setup Compiler。

回答

1

这是一个未经测试的翻译,它应该在消息框中打印出相关产品的GUID。该代码应符合ANSI以及用InnoSetup的统一版本工作:

[Code] 
#ifdef UNICODE 
    #define AW "W" 
#else 
    #define AW "A" 
#endif 

#define UPGRADE_CODE "<your upgrade here>" 

const 
    ERROR_SUCCESS = $00000000; 
    ERROR_NOT_ENOUGH_MEMORY = $00000008; 
    ERROR_INVALID_PARAMETER = $00000057; 
    ERROR_NO_MORE_ITEMS = $00000103; 
    ERROR_BAD_CONFIGURATION = $0000064A; 

function MsiEnumRelatedProducts(lpUpgradeCode: string; dwReserved: DWORD; 
    iProductIndex: DWORD; lpProductBuf: string): UINT; 
    external 'MsiEnumRelatedProducts{#AW}@msi.dll stdcall'; 

function InitializeSetup: Boolean; 
var 
    I: Integer; 
    ProductBuf: string; 
begin 
    Result := True; 

    I := 0; 
    SetLength(ProductBuf, 39); 

    while MsiEnumRelatedProducts('{#UPGRADE_CODE}', 0, I, ProductBuf) = ERROR_SUCCESS do 
    begin 
    MsgBox(ProductBuf, mbInformation, MB_OK); 
    I := I + 1; 
    SetLength(ProductBuf, 39); 
    end; 
end; 
+0

对不起它已经采取了一些时间来找回这一点,但我是出于个人原因了一下。 –

+0

没问题:-)也许我应该回到这篇文章并测试它。到目前为止,我已经至少修正了原始代码中的ANSI/Unicode不匹配。您正在导入Unicode版本的函数,但传递了ANSI字符串(因为'string'代表ANSI InnoSetup中的ANSI字符串)。 – TLama

+0

我打完CR之前发布。感谢您的代码示例,但我仍然遇到了一个问题。 user32.dll的导入应该是我修复的msi.dll。之后,我在MsiEnumRelatedProducts循环中的某处收到两个Access Violation错误。我得到其中两个,但我只安装了一个以前的产品。我必须猜测它是在SetLength(ProductBuf,39)调用中,因为安装程序在没有安装任何以前的产品的情况下执行得很好。 –

相关问题