Один MSI для установки правильного 32 или 64-битного приложения c # - PullRequest
11 голосов
/ 16 сентября 2010

У меня есть приложение на C #, которое разработано для платформ x86 (32-битная) и x64 (64-битная).Моя система сборки в настоящее время выводит два установщика MSI, по одному для каждой платформы.В случае, если это имеет значение, мое приложение C # включает панель инструментов панели задач Windows, что означает, что установленная DLL должна быть загружена процессом explorer.exe.

Возможно ли создать единственный установщик MSI, который установитправильная версия моего приложения в зависимости от того, является ли текущая ОС 64-битной ОС?

В настоящее время это достигается путем использования http://dotnetinstaller.codeplex.com/ для создания EXE-файла, который выполняет проверку архитектуры и затем запускает правильный MSI.Однако я бы предпочел подход, основанный исключительно на MSI.

Ответы [ 2 ]

7 голосов
/ 23 декабря 2010

Вы можете обойти эту проблему. Упакуйте 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 для тестов, которые будут поддерживать окно командной строки для просмотра сообщений)

Вы можете прочитать больше о пользовательских действиях, путь установки может быть передан аргументами.

7 голосов
/ 16 сентября 2010

Нет, это невозможно.См. Хит Стюарт * Различные пакеты требуются для различных архитектур процессоров пост.Единственный способ справиться с этим с помощью MSI - с помощью начальной загрузки в соответствии с тем, что вы описываете.Если вам просто нужно поместить файл или ключ или два в 64-разрядное расположение, можно (но не рекомендуется) сделать это в настраиваемом действии, но изменение целевой установки и использование встроенной поддержки файлов MSI выигралот работа.

...