2017-03-31 49 views
1

我们的应用程序现在本机支持64位,因此默认应安装在C:\Program Files目录下。出于这个原因,我们设置了这两个指令:Inno安装程序:保留现有的32位安装路径进行升级,对于新安装使用64位路径

ArchitecturesInstallIn64BitMode=x64 
DefaultDirName={pf}\{#ProductName} 

目前为止没有任何问题!

问题是,当我们的产品仍然只有32位时,我们确实有很多现有的产品安装,因此正确安装在C:\Program Files (x86)以下。

通常,Inno安装程序检测到一个存在的安装,并使用相同的安装路径(如果找到的话)。但是,当从32位模式更改为64位模式时,这似乎不起作用 - 可能是因为现在使用了不同的卸载注册表项。

如果应用程序已经安装(执行更新),并且只使用64位的新安装,是否还有办法告诉Inno Setup使用现有的32位安装路径?

回答

1

我不认为你可以让Inno Setup自动为你做这个。

但是,您可以在初始化安装程序时将32位注册表项复制到64位,以便所有Inno安装程序找到它。当然,如果安装被取消,你必须回滚副本。

#define AppId "My Program" 

[Setup] 
AppId={#AppId} 
DefaultDirName={pf}\My Program 
ArchitecturesInstallIn64BitMode=x64 
[Code] 

const 
    UninstallKey = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#AppId}_is1'; 

var 
    Rollback64Key: Boolean; 
    RootKey32: Integer; 
    RootKey64: Integer; 

procedure Copy32BitUninstallKeyTo64bit; 
var 
    I: Integer; 
    ValueNames: TArrayOfString; 
    ValueName: string; 
    ValueStr: string; 
    ValueDWord: Cardinal; 
    Success: Boolean; 
begin 
    if RegKeyExists(HKCU64, UninstallKey) or 
    RegKeyExists(HKLM64, UninstallKey) then 
    begin 
    Log('64-bit uninstall key found, leaving as it is'); 
    end 
    else 
    begin 
    if RegKeyExists(HKCU32, UninstallKey) then 
    begin 
     Log('32-bit HKCU uninstall key found, will copy it to the 64-bit key'); 
     RootKey32 := HKCU32; 
     RootKey64 := HKCU64; 
    end 
     else 
    if RegKeyExists(HKLM32, UninstallKey) then 
    begin 
     Log('32-bit HKLM uninstall key found, will copy it to the 64-bit key'); 
     RootKey32 := HKLM32; 
     RootKey64 := HKLM64; 
    end 
     else 
    begin 
     Log('No 32-bit uninstall key found'); 
     RootKey32 := 0; 
     RootKey64 := 0; 
    end; 

    if RootKey32 <> 0 then 
    begin 
     if not RegGetValueNames(RootKey32, UninstallKey, ValueNames) then 
     begin 
     Log('Cannot list 32-bit uninstall key values'); 
     end 
     else 
     begin 
     I := 0; 
     Success := True; 
     while (I < GetArrayLength(ValueNames)) and Success do 
     begin 
      ValueName := ValueNames[I]; 
      if RegQueryStringValue(RootKey32, UninstallKey, ValueName, ValueStr) then 
      begin 
      if not RegWriteStringValue(RootKey64, UninstallKey, ValueName, ValueStr) then 
      begin 
       Log(Format('Error copying "%s" string value', [ValueName])); 
       Success := False; 
      end 
       else 
      begin 
       Log(Format('Copied "%s" string value', [ValueName])); 
      end; 
      end 
      else 
      if RegQueryDWordValue(RootKey32, UninstallKey, ValueName, ValueDWord) then 
      begin 
      if not RegWriteDWordValue(RootKey64, UninstallKey, ValueName, ValueDWord) then 
      begin 
       Log(Format('Error copying "%s" dword value', [ValueName])); 
       Success := False; 
      end 
       else 
      begin 
       Log(Format('Copied "%s" dword value', [ValueName])); 
      end; 
      end 
      else 
      begin 
      { All uninstall values written by Inno Setup are either string or dword } 
      Log(Format('Value "%s" is neither string nor dword', [ValueName])); 
      Success := False; 
      end; 

      I := I + 1; 
     end; 

     if Success then 
     begin 
      Log('Copied 32-bit uninstall key to 64-bit'); 
      Rollback64Key := True; 
     end 
      else 
     begin 
      if not RegDeleteKeyIncludingSubkeys(RootKey64, UninstallKey) then 
      begin 
      Log('Failed to copy 32-bit uninstall key to 64-bit, ' + 
       'and also failed to rollback the changes'); 
      end 
      else 
      begin 
      Log('Failed to copy 32-bit uninstall key to 64-bit, rolled back the changes'); 
      end; 
     end; 
     end; 
    end; 
    end; 
end; 

function InitializeSetup(): Boolean; 
begin 
    if IsWin64 then 
    begin 
    Copy32BitUninstallKeyTo64bit; 
    end; 

    Result := True; 
end; 

procedure CurStepChanged(CurStep: TSetupStep); 
begin 
    if CurStep = ssPostInstall then 
    begin 
    if Rollback64Key then 
    begin 
     Log('Installation finished, removing obsolete 32-bit key'); 
     Rollback64Key := False; 

     if not RegDeleteKeyIncludingSubkeys(RootKey32, UninstallKey) then 
     begin 
     Log('Failed to remove obsolete 32-bit uninstall key'); 
     end 
     else 
     begin 
     Log('Removed obsolete 32-bit uninstall key'); 
     end; 
    end; 
    end; 
end; 

procedure DeinitializeSetup(); 
begin 
    if Rollback64Key then 
    begin 
    Log('Installation cancelled, rolling back cloned 64-bit uninstall key'); 

    if not RegDeleteKeyIncludingSubkeys(RootKey64, UninstallKey) then 
    begin 
     Log('Failed to roll back cloned 64-bit uninstall key'); 
    end 
     else 
    begin 
     Log('Rolled back cloned 64-bit uninstall key'); 
    end; 
    end; 
end; 

(测试与创新安装的Unicode版本,但应该在ANSI版本工作太)

+1

感谢非常快速回复,马丁!我会直接测试它。 –

+0

再次感谢您的快速回复:您是对的,我现在也确定安装程序将删除过时的32位卸载密钥,它也能正常工作。只剩下一个问题:当试图用新的64位版本升级旧的32位版本时,用户现在获得“目录已存在”消息,这显然没有多大意义。你有什么想法如何抑制这个无用的消息?再次感谢您! –

+1

好吧,现在是时候停止黑客行为,并将32位密钥复制到64位密钥,以使所有内容都能正常工作。看到我的更新答案。 –