2013-07-14 62 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)調用中,因爲安裝程序在沒有安裝任何以前的產品的情況下執行得很好。 –

相關問題