Один MSI для установки правильного 32 или 64-битного приложения C#
У меня есть приложение C#, которое разработано для платформ x86 (32-разрядных) и x64 (64-разрядных). Моя система сборки в настоящее время выводит два установщика MSI, по одному для каждой платформы. В случае, если это имеет значение, мое приложение C# включает панель инструментов панели задач Windows, что означает, что установленная DLL должна быть загружена процессом explorer.exe.
Можно ли создать единственный установщик MSI, который установит правильную версию моего приложения в зависимости от того, является ли текущая ОС 64-битной ОС?
В настоящее время это достигается с помощью http://dotnetinstaller.codeplex.com/ для создания EXE-файла, который выполняет проверку архитектуры и затем запускает правильный MSI. Однако я бы предпочел подход, основанный исключительно на MSI.
2 ответа
Нет, это невозможно. См. Хит Стюарт: Различные пакеты требуются для разных архитектур процессоров. Единственный способ справиться с этим с помощью MSI - с помощью начальной загрузки в соответствии с тем, что вы описываете. Если вам просто нужно было поместить файл или ключ или два в 64-разрядное расположение, можно (но не рекомендуется) сделать это в настраиваемом действии, но изменение целевой установки и использование встроенной поддержки файлов MSI выиграло ' т работа.
Вы могли бы обойти проблему. Упакуйте 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 для тестов, которые будут поддерживать окно командной строки для просмотра сообщений)
Вы можете прочитать больше о пользовательских действиях, путь установки может быть передан аргументами.