单个 MSI 安装正确的 32 或 64 位 c# 应用程序

Posted

技术标签:

【中文标题】单个 MSI 安装正确的 32 或 64 位 c# 应用程序【英文标题】:Single MSI to install correct 32 or 64 bit c# application 【发布时间】:2011-04-13 02:28:03 【问题描述】:

我有一个为 x86(32 位)和 x64(64 位)平台构建的 C# 应用程序。我的构建系统当前输出​​两个 MSI 安装程序,每个平台一个。万一有所不同,我的 C# 应用程序包含一个 Windows 任务栏工具栏,这意味着安装的 DLL 必须由 explorer.exe 进程加载。

是否可以根据当前操作系统是否为 64 位操作系统来生成单个 MSI 安装程序来安装我的应用程序的正确版本?

这目前已通过使用http://dotnetinstaller.codeplex.com/ 生成执行架构检查然后启动正确的 MSI 的 EXE 来实现。不过,我更喜欢纯基于 MSI 的方法。

【问题讨论】:

相关:How do I conditionally install a file with WiX based on the target machine (32bit or 64bit)? 【参考方案1】:

不,这是不可能的。请参阅 Heath Stewart 的 Different Packages are Required for Different Processor Architectures 帖子。使用 MSI 处理此问题的唯一方法是使用您所描述的引导程序。如果您只需要将文件或密钥或两个放在 64 位位置,可以(但不推荐)在自定义操作中执行此操作,但更改目标安装位置并使用内置 MSI 文件支持将不会没用。

【讨论】:

【参考方案2】:

你可以解决这个问题。在第三个部署项目下打包 2 个安装程序。创建一个自定义操作来检查正在运行的操作系统版本,然后让安装程序调用正确的安装程序。

类似这样的:

[RunInstaller(true)]
public partial class MyInstaller: Installer

    String installerPath;

    public MyInstaller()
    
        InitializeComponent();       
        if (Is64Bit())//running as 64-bit
        
            installerPath= @"installfolder\my64bitsetup.exe";
        
        else
        
            installerPath= @"installfolder\my32bitsetup.exe";
        
    

    [SecurityPermission(SecurityAction.Demand)]
    public override void Install(IDictionary stateSaver)
    
        base.Install(stateSaver);
    

    [SecurityPermission(SecurityAction.Demand)]
    public override void Commit(IDictionary savedState)
    
        base.Commit(savedState);
        MyInstall();
    

    [SecurityPermission(SecurityAction.Demand)]
    public override void Rollback(IDictionary savedState)
    
        base.Rollback(savedState);
    

    [SecurityPermission(SecurityAction.Demand)]
    public override void Uninstall(IDictionary savedState)
    
        base.Uninstall(savedState);
        base.Commit(savedState);
    

    private void MyInstall()
    
         ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd.exe", "/c " + installerPath);
        RunProcess(procStartInfo);
    

    private void RunProcess(ProcessStartInfo procStartInfo)
    
        Process proc = new Process();
        proc.StartInfo = procStartInfo;
        proc.Start();
        proc.WaitForExit();
    

[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);

private bool Is64Bit()

    return (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()));


private bool Is32BitProcessOn64BitProcessor()

    bool retVal;
    IsWow64Process(Process.GetCurrentProcess().Handle, out retVal);
    return retVal;

好吧,那很长……

无论如何,在 Commit 中您可以确定安装程序已经解压,只要确保您有正确的路径即可。 (您可以将 cmd 命令从 /c 更改为 /k 以进行测试,这将使命令提示符窗口保持活动状态,以便您查看消息)

您可以阅读更多关于自定义操作的信息,安装路径可以通过参数传递。

【讨论】:

以上是关于单个 MSI 安装正确的 32 或 64 位 c# 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

数据库安装操作失败并显示试图加载格式不正确的程序

int 是 64 位 C# 中的 64 位整数吗?

C# 编译为 32/64 位,或任何 cpu? [复制]

MSI - 有条件地注册 DLL

mysql安装配置教程

带有 32 位 VB6 COM 对象的 64 位 C#