In Wix#, how to avoid creating a physical folder on the target system, when deploying only registry entries?

前端 未结 2 779
情歌与酒
情歌与酒 2020-12-22 10:10

I have several related Windows registry entries that I want packaged inside an MSI, so that 1) there is an uninstall process, and 2) The fact that these registry entries hav

相关标签:
2条回答
  • 2020-12-22 10:55

    You can achieve what you want by adding the <RemoveFolder> tag to your component within the directory you do not wish to keep. See the reference.

    The resulting MSI will be created by light with the warning LGHT1079 that you don't have any files, but can be ignored if this is the intent.

    Simple example XML showing the directory with a component that deletes the folder on install/uninstall and creates the registry keys, forcing delete on uninstall.

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

    You'd simply either use this name for your directory, or replace the Directory="TARGETDIR" with the name of your directory.

    The result after install is a registry key with no folder on the target machine. registry key path

    You'd have to figure out how to get that tag into your generated XML, but that's the effect you'd need.

    0 讨论(0)
  • 2020-12-22 11:08

    Using the Wix XML code Ryan J provided, plus the example "InjectXML" from the Wix# samples code, I was successful in generating the wxs file and getting a working MSI, all while still staying within the Wix# coding environment in Visual Studio.

    Here is the relevant .wxs XML that was being generated before, under the element:

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

    So what needs to happen is: 1) Remove the "" element, which is under Product/Directory/Directory/Component. Ryan J's example clearly showed that it goes under the "Component" that is associated with the first "Directory" to be created, which is in turn under the "TARGETDIR", in the XML that Wix# generates.

    2) Insert the element syntax, "", under the element Product/Directory/Directory/Component. While I believe it may also work to reference the Id "INSTALLDIR.EmptyDirectory"in this element, I used the Id "TARGETDIR" and it worked the way I wanted.

    Here is the resulting Wix# code that injects the XML as supplied by 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")));
            }

    0 讨论(0)
提交回复
热议问题