Windows Setup: Dynamic Registry Keys/Values

依然范特西╮ 提交于 2019-12-06 04:06:02

Yes, this can be done*.

First, create a Console executable that will be run as part of a post-build event of the Windows Setup project. This modifies the Registry table in the MSI file that has been built by VS2010.

Note: You must add a reference to "Microsoft Windows Installer Object Library" under COM, for the below code to compile.

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();
        }
    }
}

The "variables" that we are going to use in the Windows Setup Registry screen get replaced in these lines of the above code; this could be adapted to any items that are necessary.

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

Second, create a .reg file that contains the registry keys you want to create upon install. In the code above, we modify the MSI database in the post-build by replacing all instances of [AssemblyVersion] with the assembly version, and [AssemblyStrongName] with the assembly's strong name.

[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"

Third, import the .reg file into the Windows Setup registry screen in VS2010 by right-clicking "Registry On Target Machine", and clicking "Import".

Finally, call the post-build executable in the "PostBuildEvent" property of the setup project:

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

* This is a little different than using [TARGETDIR], because [TARGETDIR] gets resolved at install time, and these "variables" will get resolved at build time. For my solution, I needed to resolve at build time, because my version number increments with each build.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!