0

MSI 内にパッケージ化したい関連する Windows レジストリ エントリがいくつかあるため、1) アンインストール プロセスがあり、2) これらのレジストリ エントリが特定のコンピュータに適用されているという事実は、[プログラムの追加と削除] エントリによって文書化されます。 .

問題は、Wix# でこれをうまく実行できることですが、すべてのレジストリ エントリが "Dir" ブロック内にある場合にのみ MSI をビルドすることができ、物理フォルダーを実際に作成することになります。 '望まない、ターゲット システム上。

一時的な回避策として、ダミーの「Temp」フォルダーを指定して、Dir ブロックを使用することにしました。インストーラーは実際にフォルダーを作成しますが、これは望ましくありません。私が望むのは、レジストリ エントリを適用することだけです。

WiX のドキュメントでは、基本的に、ターゲット システムでアクションを実行するようにインストーラーに指示するものとして、その基礎となる構成体である TargetDir について説明しています。http://wixtoolset.org/documentation/manual/v3/howtos/files_and_registry/write_a_registry_entry.htmlを参照してください。

そのネイティブ WiX XML の例では、ターゲット システム上に不要なフォルダーが作成されないように見えます。必要なレジストリ エントリのみが適用されます。レジストリ エントリを適用し、ターゲット システムに実際のフォルダを作成する必要を回避するために、どの Wix# 構文構造を使用できますか?

これまでに見たすべての Wix# サンプルには、必要かどうかに関係なく、ターゲット システムに実際のフォルダーを作成するという副作用があるようです。

レジストリ エントリの .reg ファイルを取得し、それらを熱で .wxs ファイルに収集し、キャンドルとライトで msi にビルドすることで、おそらくこれを実行できることを私は知っています。私は本当にこれを C#/Wix# の世界に留めようとしています。C# は、私の組織で十分に理解されているスキル セットです。WiXはそうではありません。(Wix# は WiX の機能の上に構築されており、WiX と Windows インストーラーのある程度の理解が不可欠であることを認めます。XML の代わりに C# を使用できることは、完全に論理的なことではなく、コンフォート ゾーンのことです。) 現在、これらのタイプのレジストリ設定タスクの多くは手動で行っており、追跡も簡単で信頼性の高いアンインストールもありません。

/// <summary>
/// Configure the Event Log on a Windows (server) to have MyApplication Log settings and record an entry for it in Programs and Features.
/// Note that this program creates the Windows Installer MSI that accomplishes this.  
/// This program creates a WiX XML file that is then compiled by the WiX Toolkit (Candle and Light) into the MSI file.
/// </summary>
internal class Script
{
    public static void Main()
    {
        // Define a new Installer Project object
        var project = new Project("SetupMyApplicationEventLog" ,
        // Provide dummy "Temp" install directory to satisfy WiX# Syntactical requirement. There are no actual files being installed.
        new Dir(@"Temp"),
            /*
                * Event Log Registration Entries, translated from .reg file
            */
            // First, add the root level key of the tree of keys

            //[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\MyApplication Log]
            //"EventMessageFile"="C:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\EventLogMessages.dll"
            new RegValue(
                RegistryHive.LocalMachine,
                @"SYSTEM\CurrentControlSet\Services\Eventlog\MyApplication Log",
                "",
                "") { AttributesDefinition = "Component:Win64=yes" },

            //[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\MyApplication Log\STV.DSD.HQSYS.SERVICE2]
            //"EventMessageFile"="C:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\EventLogMessages.dll"
            new RegValue(
                RegistryHive.LocalMachine,
                @"SYSTEM\CurrentControlSet\Services\Eventlog\MyApplication Log\" + "STV.DSD.HQSYS.SERVICE2",
                "EventMessageFile",
                "C:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\EventLogMessages.dll") { AttributesDefinition = "Component:Win64=yes" },

            //[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\MyApplication Log\STV.VFS.ONLINE]
            //"EventMessageFile"="C:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\EventLogMessages.dll"
            new RegValue(
                RegistryHive.LocalMachine,
                @"SYSTEM\CurrentControlSet\Services\Eventlog\MyApplication Log\" + "STV.VFS.ONLINE",
                "EventMessageFile",
                "C:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\EventLogMessages.dll") { AttributesDefinition = "Component:Win64=yes" } );

        // Set the properties of the setup project

        // Set UI to minimal; there are no choices to be made here.
        project.UI = WUI.WixUI_ProgressOnly;
        project.Manufacturer = "STV";
        project.OutFileName = "SetupMyApplicationEventLog";
        project.GUID = new Guid("037C625A-609C-4C2C-9689-62A075B88AD7");
        // Assign version # to setup MSI property of type System.Version 
        project.Version = new Version(4, 0, 0, 0);

        // Add the Win64 attribute to the package, to force a 64-bit MSI to be created
        project.Package.AttributesDefinition = "Platform=x64";

        // Trigger the MSI file build
        Compiler.BuildMsi(project);

        //// Also create the .wxs file so we can see what was sent to WiX to build the MSI
        Compiler.BuildWxs(project);

        Console.WriteLine("productVersion=" + project.Version);
        Console.ReadLine();
    }
}

}

4

2 に答える 2

0

<RemoveFolder>保持したくないディレクトリ内のコンポーネントにタグを追加することで、目的を達成できます。リファレンスを参照してください。

結果の MSI は、ファイルがないlightという警告とともに作成されますが、これが意図されている場合は無視できます。LGHT1079

インストール/アンインストール時にフォルダーを削除し、レジストリ キーを作成し、アンインストール時に強制的に削除するコンポーネントを含むディレクトリを示す XML の簡単な例。

<Directory Id="TARGETDIR" Name="SourceDir">
    <Component Id="ApplicationRegistry" Guid="YOUR-GUID-HERE">
         <RemoveFolder Id="RemoveTarget" Directory="TARGETDIR" On="both"/> 
         <RegistryKey Root="HKCU"
              Key="Software\Microsoft\[ProductName]"
              ForceDeleteOnUninstall="yes">
                <RegistryValue Type="integer" Name="SomeIntegerValue" Value="1" KeyPath="yes"/>
                <RegistryValue Type="string" Value="Default Value"/>
         </RegistryKey>
    </Component>
</Directory>

この名前をディレクトリに使用するか、をディレクトリの名前に置き換えるだけDirectory="TARGETDIR"です。

インストール後の結果は、ターゲット マシン上にフォルダーのないレジストリ キーです。 レジストリ キー 道

そのタグを生成された XML に取り込む方法を理解する必要がありますが、それが必要な効果です。

于 2014-10-25T18:54:20.117 に答える
0

Ryan J が提供した Wix XML コードと、Wix# サンプル コードのサンプル「InjectXML」を使用して、Visual Studio の Wix# コーディング環境にとどまりながら、wxs ファイルを生成し、機能する MSI を取得することに成功しました。

要素の下に、以前に生成された関連する .wxs XML を次に示します。

<Directory Id="TARGETDIR" Name="SourceDir" >
  <Directory Id="INSTALLDIR" Name="%Temp%">
    <Component Id="INSTALLDIR.EmptyDirectory" Guid="037c625a-609c-4c2c-9689-62a075b88ae9">
      <CreateFolder />
    </Component>

1) Product/Directory/Directory/Component の下にある "" 要素を削除します。Ryan J の例は、Wix# が生成する XML で、作成される最初の「ディレクトリ」に関連付けられた「コンポーネント」の下にあることを明確に示しています。これは、「TARGETDIR」の下にあります。

2) エレメント構文 "" をエレメント Product/Directory/Directory/Component の下に挿入します。この要素で Id "INSTALLDIR.EmptyDirectory" を参照することもできると思いますが、ID "TARGETDIR" を使用したところ、希望どおりに機能しました。

これは、Ryan J.

    internal class Script
    {
        public static void Main()
        {
            // Define a new Installer Project object
            var project = new Project("SetupMyApplicationEventLog" ,
            // Provide dummy "Temp" install directory to satisfy WiX# Syntactical requirement. There are no actual files being installed.
            new Dir(@"TempDeleteMe"),
...
            // Hook up a delegate to the "WixSourceGenerated" event, fires when .wxs file is fully created
            Compiler.WixSourceGenerated += InjectXMLElement;
            // Trigger the MSI file build
            Compiler.BuildMsi(project);
...

        /// Insert XML elements and attributes into the generated .wxs file
        static void InjectXMLElement(System.Xml.Linq.XDocument document)
        {
            // Remove the <CreateFolder /> tag from Directory element -- we don't want to create it
            var createFolderElement = document.Root.Select("Product/Directory/Directory/Component/CreateFolder");
            createFolderElement.Remove();
            // To cause the folder to not be created on the target system, add this element:
            // <RemoveFolder Id="RemoveTarget" Directory="TARGETDIR" On="both"/>
            var componentElement = document.Root.Select("Product/Directory/Directory/Component");
            
            componentElement.Add(new XElement("RemoveFolder",
                       new XAttribute("Id", "RemoveTarget"),
                       new XAttribute("Directory", "TARGETDIR"),
                       new XAttribute("On","both")));
        }

于 2014-10-28T03:47:30.200 に答える