How do I uninstall related products in Inno Setup using an InstallShield Upgrade Code GUID

巧了我就是萌 提交于 2019-12-01 08:11:18

问题


Our company has switched from using InstallShield Express to using Inno Setup (5.5.2 version). We've got years of old installs utilizing InstallShield, but have always relied on InstallShield's Upgrade Code GUID to handle the uninstall of the previous version.

I need to be able to uninstall any previous InstallShield installed version from our new Inno Setup installer.

After some research it looks like I need to call MsiEnumRelatedProducts() and then uninstall any found products.

I found this link http://www.microsofttranslator.com/bv.aspx?from=de&to=en&a=http%3A%2F%2Fwww.inno-setup.de%2Fshowthread.php%3Fs%3D415e3895fda3e26e42739b004c0f51fb%26t%3D2857 (original in German http://www.inno-setup.de/showthread.php?s=415e3895fda3e26e42739b004c0f51fb&t=2857). It looks like he got pretty close, but he never posts his final solution.

Code he says works (but crashes for me):

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

function MsiEnumRelatedProducts(lpUpgradeCode:string;
  dwReserved, iProductIndex:cardinal; 
  var lpProductBuf:TProductBuf) : cardinal;
external 'MsiEnumRelatedProductsW@msi.dll 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;

He says this makes it easier?

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

I'm new to Pascal scripting and I'm getting stuck on the whole SetLength() part. What does it replace in the function he says works, but crashes?

Since the other persons says to switch to string, should I get rid of this:

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

If anyone could show me a final working function in English, it would be awesome!!!

Thanks in advance!

Edit: I am using the ANSI version of the Inno Setup Compiler.


回答1:


Here's an untested translation, which should just print out the related product GUIDs in message boxes. The code should work with ANSI as well as with Unicode versions of 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;


来源:https://stackoverflow.com/questions/17643974/how-do-i-uninstall-related-products-in-inno-setup-using-an-installshield-upgrade

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!