Announcement

Collapse
No announcement yet.

Using WIX Extensions

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using WIX Extensions

    Hi there,

    So there are a few standard extensions that I'd like to use in my installer project, but I don't see how to use them. For example, I would like to use the Firewall extension to create a rule on install.

    How do I achieve this? I assume it's possible as the product page says it supports extensions.

    Nick.

  • #2
    Hello, thank you for trying out MSI Factory. You can use WiX extensions with MSI Factory, but there is support in the IDE only for the IIS extension. Others still can be used, using WiX fragments, which is relatively simple, once you understand the concept.

    I will show you how to use the WixFirewallExtension in this sample project. To keep things as simple as possible, this project has only a single file, named Demo.exe:

    Click image for larger version

Name:	SCRN-2017-05-19-03.png
Views:	352
Size:	27.7 KB
ID:	297828

    This executable actually does not have any network features, but it works just to show the use of the WiX extension.

    Now, if you check the documentation of the extension you want to use, you know that he FirewallException element must be used as a child of a Component or a File. I will use it as a child of a File - "the file", which is Demo.exe.

    Now, to make things easier to understand, I suggest that you use the option Build > Generate WiX Files, and inspect the WiX source code of the main file, setup.wxs. You will find this code:

    Code:
    <Component Id="Demo.exe" Guid="2457F97C-2BD6-4B54-BF7A-627B44B67F7A">
    <File Id="Demo.exe" Name="Demo.exe" DiskId="1" KeyPath="yes" Source="$(var.ProjectFolder)\Demo.exe" />
    </Component>
    Here we need to insert the XML fragment for the firewall rule, so the resulting WiX code reads like this:

    Code:
    <Component Id="Demo.exe" Guid="2457F97C-2BD6-4B54-BF7A-627B44B67F7A">
    <File Id="Demo.exe" Name="Demo.exe" DiskId="1" KeyPath="yes" Source="$(var.ProjectFolder)\Demo.exe">
    [highlight]<fire:FirewallException Id="FWX1" Name="My Program" Port="8080" Protocol="tcp" />[/highlight]
    </File>
    </Component>
    This is done using the Build > Settings > Fragments dialog, where we will add a file named firewall-exception.wxs.

    Click image for larger version

Name:	SCRN-2017-05-19-05.png
Views:	316
Size:	13.5 KB
ID:	297829

    If you double-click this file, you will see the fragment's Properties dialog, which shows where a fragment should be inserted, and the actual XML.

    Here is the location: Last Child of /Wix/Fragment/DirectoryRef/Component[@Id="Demo.exe"]/File
    And this is the code:
    Code:
    <FirewallException xmlns="http://schemas.microsoft.com/wix/FirewallExtension" Id="FWX1" Name="My Program" Port="8080" Protocol="tcp" Scope="any" />
    If you check the sample XML I posted above, you will see that this is the code which was injected into the WiX source.

    When you run the installer, you will see that the firewall is actually being configured as part of the deployment:

    Click image for larger version

Name:	SCRN-2017-05-19-02.png
Views:	302
Size:	10.3 KB
ID:	297830

    And if you check the Windows firewall settings, you will see that the "My Program" was added, and is allowed to use the port 8080 with the TCP protocol, exactly as specified in the XML fragment.

    Click image for larger version

Name:	SCRN-2017-05-19-01.png
Views:	286
Size:	10.1 KB
ID:	297831

    In order to compile the project, you need to add the extension to the compiler and linker in Build > Settings > Options. I am attaching a zip file with the required files. You can decompress this in an empty folder and build there directly.

    Ulrich

    Comment


    • #3
      Excellent thanks, I'm back onto this task after a while of working on other things so this is extremely helpful, thanks. Sorry for the delay.

      Comment


      • #4
        I've followed your instructions above, and it seems as though it's not looking i nthe right wxs file for the element that it needs to insert the fragment into.

        If I output the WXS, I get,

        ---

        Checking for orphaned folders...
        Setting language to English-US for this build.
        Checking output folders

        Building main setup .wxs file (foobar.wxs)

        Adding user interface
        ...generating main UI wxs file (msifactui.wxs)
        ...adding file to build: ...\Temp\msifactui.wxs
        ...adding language files:
        ...using language: English-US
        Adding merge modules
        > Module: Microsoft_VC120_CRT_x86 ($(var.ProjectFolder)\..\Prerequisite\Microsoft_VC 120_CRT_x86.msm)
        > ERROR: Could not find fragment insertion tag: /Wix/Fragment/DirectoryRef[@Id="BINDIR"]/Component[@Id="foobar"]/File
        Error 2000: > ERROR: Could not find fragment insertion tag: /Wix/Fragment/DirectoryRef[@Id="BINDIR"]/Component[@Id="
        foobar
        "]/File

        Error 2000: XML error

        Build FAILED! Error: 2000 - XML error

        ---

        So at this point, or the file it's looking in does not have this component declared, but I don't see from your instructions above what I could be doing incorrectly here. As mentioned above I have verified that my XPath can find the correct elements, the last one that it finds (last child) is the exe that I want it associated with, so all good there.

        Any ideas?

        Comment


        • #5
          You explicitly say
          setup.wxs above, my version if setup.wxs, let's say foobar,wxs hasnt been generated by the time it attempts to appent the fragment, so is it doing this in memory or something? If I remove the fragment and build the output, then do the xpath search on my foobar.wxs, I can find the element fine.

          Comment


          • #6
            Sorry for the typos, no way to edit posts????

            Comment


            • #7
              Try to build the WiX source files (Build > Generate WiX Files). You should see the generated source files which are used during the compilation.

              Ulrich

              Comment


              • #8
                That's also producing this same error.

                Comment


                • #9

                  It's almost as if it's doing it too early, if I look at your sample, it seems to follow a different flow,

                  ---


                  Adding user interface
                  ...generating main UI wxs file (msifactui.wxs)
                  ...adding file to build: D:\Temp\Build Files\msifactui.wxs
                  ...adding language files:
                  ...using language: English-US

                  Saving main setup .wxs file as 'C:\Users\nickp\Downloads\Firewall-Sample\sample-setup.msi'

                  Compiling 'D:\Temp\Build Files\sample-setup.wxs'
                  Windows Installer XML Toolset Compiler version 3.9.1208.0
                  Copyright (c) Outercurve Foundation. All rights reserved.


                  ---

                  Your sample clearly says "Saving main setup .wxs", but mine doesn't it attempts to insert the fragment before this has been written. Both build and generate wix are producing exactly the same errors as a result.

                  Comment


                  • #10
                    this is the part that's added to my project file to enable this (that isn't working)

                    ---

                    <FragmentInclude SourceFile="$(var.ProjectFolder)\firewallconfig.wx s" CopyToOutputFolder="yes">
                    <Insertions>
                    <Insertion InsertType="1">
                    <TargetXMLPath>/Wix/Fragment/DirectoryRef[@Id="BINDIR"]/Component[@Id="SERVICE"]/File</TargetXMLPath>
                    <TextToInsert><![CDATA[<FirewallException xmlns="http://schemas.microsoft.com/wix/FirewallExtension" Id="FirewallRule" Name="Service.FirewallRule" Scope="any" Port="9998" Protocol="tcp" />]]></TextToInsert>
                    </Insertion>
                    </Insertions>
                    </FragmentInclude>

                    ---

                    The wxs file "firewallconfig.wxs" is the same as yours

                    ---

                    <?xml version="1.0" encoding="utf-8"?>
                    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:fire="http://schemas.microsoft.com/wix/FirewallExtension" />

                    ---

                    Comment


                    • #11
                      I guess that you are not inserting the fragment at the correct location. When you get "ERROR: Could not find fragment insertion tag", the search location is incorrect.
                      I cannot help you with the excerpts you are posting - if you want me to look into this, please post a zip with the whole set of files required to build the MSI.

                      Ulrich

                      Comment


                      • #12
                        Hey Ulrich,

                        It's quite a large installer, so I don't think you would appreciate the amount of data that I would have to send you, but I could try and cut it down severely and then email it to you perhaps? I can't upload to here unfortunately.

                        Comment


                        • #13
                          Interestingly I have just discovered that if I remove all components except for the one that I want to attach the firewall element too, it works, so it's something to do with my components. Just investigating further...

                          Comment


                          • #14
                            Does it have to be the kaypath component? As mine isn't, but if I remove the existing keypath component, it works.

                            Comment


                            • #15
                              There are at least two ways to make this work. The first option is to specify the Fragment to be used, in order to locate the proper insertion location. Set the search string as

                              /Wix/Fragment[2]/DirectoryRef/Component/File[@Id="Seiki.NotificationService.exe"]

                              like shown here:

                              Click image for larger version

Name:	SCRN-2018-07-07-01.png
Views:	297
Size:	14.6 KB
ID:	300589

                              The fragment insertion will then be performed properly. You have three Fragments in the Wix source, and pointing where to insert the code helps. If you don't want to do this, you could simply point to the File to be used. For this, set the search to

                              //File[@Id="Seiki.NotificationService.exe"]

                              as shown here:

                              Click image for larger version

Name:	SCRN-2018-07-07-02.png
Views:	247
Size:	13.8 KB
ID:	300590

                              Again, this will compile properly, the fragment will be inserted once the file with the given Id is located.

                              Ulrich

                              Comment

                              Working...
                              X