2013-06-03 3 views
3

синопсис моего вопроса:установки Windows: Динамические Ключи реестра/Значения

Можно ли использовать свои собственные, пользовательские переменные (так, что вы можете использовать [TARGETDIR]) на экране реестру Проект установки Windows в VS2010? В частности, мне нужно сохранить сильное имя и версию сборки в реестре, чтобы зарегистрировать COM-объект на машине без установки пользователя с правами администратора.

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

Вот специфика, и то, что я пробовал:

Недавно мой работодатель начал слепо удаление прав администратора всех сотрудников из своих машин.

Я создал класс C#, открытый для COM, который я использовал на нескольких моих рабочих станциях, которые больше не могут быть зарегистрированы, потому что у меня больше нет соответствующих разрешений в HKEY_CLASSES_ROOT.

Через Googling я узнал, как зарегистрировать все соответствующие ключи под HKCU *, но теперь я хотел бы реализовать это в своем проекте развертывания.

Я понимаю, как использовать экран реестра в Windows Setup, но есть специальные ключи/значения, которые необходимо сохранить (установить папку, имя сборки, версию).

Я мог бы использовать настраиваемое действие, но в идеале я хочу, чтобы Windows Setup управляла моими параметрами реестра, потому что (a) это лучше, чем я при автоматическом удалении всех надлежащих ключей/значений при удалении, (b) во время установка, изменения реестра являются транзакционными & откат при ошибке установки и (в) логика для установки/удаления ключа реестра/транзакций уже написана Microsoft, и мне не придется переписывать ее самостоятельно.

Проект был в VS2008 до сегодняшнего дня, но я только что обновил его до VS2010, поэтому, возможно, что-то изменилось с 2008 по 2010 год, что может позволить такое поведение.

Таким образом, вместо использования специального действия есть ли лучший способ сделать это?

EDIT: я нашел this ответ, который, кажется, предположить, что вы можете получить доступ к «реестра» стол Windows Install в вашей установки проекта. Я не уверен, как сделать доступ к нему. Раньше я напоминал, что вы можете получить доступ к базам данных MSI из специального внешнего инструмента (Orca), но я не знаю, можете ли вы получить доступ к этим таблицам в своем проекте установки.

EDIT 2: А, я могу быть на что-то; возможно, событие после сборки:


* Run Regasm дважды - один раз с/кодовую и один раз без; оба раза с параметром/regfile.Затем объедините оба файла вместе (удалите дубликаты) и замените все ссылки HKCR на HKCU \ Software \ Classes.

ответ

1

Да, это можно сделать *.

Сначала создайте исполняемый файл Console, который будет запущен как часть события после сборки проекта установки Windows. Это изменяет таблицу Registry в файле MSI, который был создан VS2010.

Примечание: вы должны добавить ссылку на «Библиотека объектов установщика Microsoft Windows» под COM, чтобы этот код был подкомпилирован.

using System; 
using WindowsInstaller; 
using System.Runtime.InteropServices; 
using System.Reflection; 

namespace Post_Setup_Scripting 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 
      if (args.Length != 2) 
      { 
       Console.WriteLine("Incorrect args."); 
       return; 
      } 

      //arg 1 - path to MSI 
      string PathToMSI = args[0]; 
      //arg 2 - path to assembly 
      string PathToAssembly = args[1]; 

      Type InstallerType; 
      WindowsInstaller.Installer Installer; 
      InstallerType = Type.GetTypeFromProgID("WindowsInstaller.Installer"); 
      Installer = (WindowsInstaller.Installer)Activator.CreateInstance(InstallerType); 

      Assembly Assembly = Assembly.LoadFrom(PathToAssembly); 
      string AssemblyStrongName = Assembly.GetName().FullName; 
      string AssemblyVersion = Assembly.GetName().Version.ToString(); 

      string SQL = "SELECT `Key`, `Name`, `Value` FROM `Registry`"; 
      WindowsInstaller.Database Db = Installer.OpenDatabase(PathToMSI, WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeDirect); 
      WindowsInstaller.View View = Db.OpenView(SQL); 
      View.Execute(); 
      WindowsInstaller.Record Rec = View.Fetch(); 
      while (Rec != null) 
      { 
       for (int c = 0; c <= Rec.FieldCount; c++) 
       { 
        string Column = Rec.get_StringData(c); 
        Column = Column.Replace("[AssemblyVersion]", AssemblyVersion); 
        Column = Column.Replace("[AssemblyStrongName]", AssemblyStrongName); 
        Rec.set_StringData(c, Column); 
        View.Modify(MsiViewModify.msiViewModifyReplace, Rec); 
        Console.Write("{0}\t", Column); 
        Db.Commit(); 
       } 
       Console.WriteLine(); 
       Rec = View.Fetch(); 
      } 
      View.Close(); 

      GC.Collect(); 
      Marshal.FinalReleaseComObject(Installer); 

      Console.ReadLine(); 
     } 
    } 
} 

«Переменные», которые мы собираемся использовать на экране реестра Windows Setup, заменяются в этих строках вышеуказанного кода; это может быть адаптировано к любым элементам, которые необходимы.

string Column = Rec.get_StringData(c); 
Column = Column.Replace("[AssemblyVersion]", AssemblyVersion); 
Column = Column.Replace("[AssemblyStrongName]", AssemblyStrongName); 

Во-вторых, создайте REG-файл, содержащий ключи реестра, которые вы хотите создать при установке. В приведенном выше коде мы модифицируем базу данных MSI в пост-сборке, заменив все экземпляры [AssemblyVersion] версией сборки и [AssemblyStrongName] на сильное имя сборки.

[HKEY_CURRENT_USER\Software\Classes\Record\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\[AssemblyVersion]] 
"Class"="MyClass.MyClass" 
"Assembly"="[AssemblyStrongName]" 
"RuntimeVersion"="v2.0.50727" 
"CodeBase"="[TARGETDIR]MyClass.dll" 

В-третьих, импортировать файл .reg в экран реестра программы установки Windows в VS2010, щелкнув правой кнопкой мыши «реестра на целевой машине», и нажать кнопку «Импорт».

Наконец, вызовите после сборки исполняемого файла в свойстве "PostBuildEvent" проекта установки:

"C:\Path\To\Exe\Post-Setup Scripting.exe" [Path to MSI] [Path To DLL to extract strong name/version] 

* Это немного отличается от использования [TARGETDIR], потому что [TARGETDIR] получает разрешено во время установки, и эти «переменные» будут решены во время сборки. Для моего решения мне нужно было решить во время сборки, потому что мой номер версии увеличивается с каждой сборкой.

Смежные вопросы