简体   繁体   English

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

[英]Single MSI to install correct 32 or 64 bit c# application

I have a C# application which is built for both x86 (32 bit) and x64 (64 bit) platforms. 我有一个C#应用程序,它是为x86(32位)和x64(64位)平台构建的。 My build system currently outputs two MSI installers, one for each platform. 我的构建系统目前输出两个MSI安装程序,每个平台一个。 In case it makes a difference, my C# application includes a windows taskbar toolbar which means that the installed DLL must be loaded by the explorer.exe process. 如果它有所不同,我的C#应用​​程序包括一个Windows任务栏工具栏,这意味着必须由explorer.exe进程加载已安装的DLL。

Is it possible to produce a single MSI installer which will install the correct version of my application depending on whether the current OS is a 64 bit OS? 是否可以生成单个MSI安装程序,它将根据当前操作系统是否为64位操作系统安装正确版本的应用程序?

This has currently been achieved by using http://dotnetinstaller.codeplex.com/ to produce an EXE which performs the architecture check and then launches the correct MSI. 目前,这已通过使用http://dotnetinstaller.codeplex.com/生成EXE来实现,该EXE执行体系结构检查,然后启动正确的MSI。 However, I would prefer a purely MSI based approach. 但是,我更喜欢纯粹的基于MSI的方法。

No, this is not possible. 不,这是不可能的。 See Heath Stewart's Different Packages are Required for Different Processor Architectures post. 请参阅Heath Stewart的不同处理器架构所需不同包 The only way to handle this with MSI is with a bootstrap along the lines of what you describe. 使用MSI处理此问题的唯一方法是使用您描述的引导程序。 If you just needed to put a file or key or two in a 64-bit location, it's possible (but not recommended) to do that in a custom action, but changing the target installation location and using built-in MSI file support won't work. 如果您只需要将文件或一两个密钥放在64位位置,则可以(但不建议)在自定义操作中执行此操作,但更改目标安装位置并使用内置MSI文件支持赢得了'工作。

You could work around the problem. 你可以解决这个问题。 Pack the 2 installers under third deployment project. 在第三个部署项目下打包2个安装程序。 Create a custom action that checks the running OS version, then make the installer call the right installer. 创建一个自定义操作,检查正在运行的操作系统版本,然后让安装程序调用正确的安装程序

Something like this: 像这样的东西:

[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;
}

Ok, that was long... 好的,那很久......

Anyway, in the Commit you can be sure that the installers are already unpacked, just make sure you have the right path. 无论如何,在提交中你可以确定安装程序已经解压缩,只需确保你有正确的路径。 (You can change the cmd command from /c to /k for testings, that will keep the command prompt window alive for you to see the messages) (您可以将cmd命令从/ c更改为/ k进行测试,这将使命令提示符窗口保持活动状态,以便您查看消息)

You can read some more about custom actions, the installation path can be passed by arguments. 您可以阅读有关自定义操作的更多信息,可以通过参数传递安装路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM