skip to Main Content

I’m learning how to use WiX to create an installer for my projects, and would like to be able to reference my VS2019 C# project’s assembly information as populated from the project’s Properties > Application > Assembly Information button in my .wxs file.

I understand I can use add the project as a reference and then use a $(var.MyProject.???) declaration, but I have no idea where to find the list of viable dot notation properties for the project. Alternatly I know I can use ” with <Package Manufacturer="$(var.CompanyName)" .../> to save having to typing the data multiple times, but i’d still prefer to pull it from the project and have it in one place.

Image for Clarity

Thank you

SEO terms: wix assembly version. wix assembly information

2

Answers


  1. Chosen as BEST ANSWER

    For those who run into this in the future here's what it took to gain access to the assembly information from wix.

    Note at the time of posting I hadn't managed to return the entire data object as a single struct, but can at least output the values as strings.

    To make it easy to define the targeted assembly file, define a constant either via your node in the .wixproj file Or via the wixProj's Properties > Build > Define Preprocessor variables field: AssetPath=../MyReferencedProject/bin/$(Configuration)/MyAsset.exe;

    Next, place the below code into your .wixProj file. (Edit this with NotePad++ then reload the project in VS)

        <!--To modify your build process, add your task inside one of the targets below and uncomment it.
        Other similar extension points exist, see Wix.targets.-->
    
        <Target Name="BeforeBuild">
            <ExtractAsmInfo AsmPath="$([System.Text.RegularExpressions.Regex]::Match(&quot;;$(DefineConstants);&quot;, &quot;;AssetPath=(?&lt;path&gt;.*?);&quot;).Groups[&quot;path&quot;].Value)">
                <Output PropertyName="asmCompName" TaskParameter="AsmCompName" />
                <Output PropertyName="asmProdName" TaskParameter="AsmProdName" />
                <Output PropertyName="asmDesc" TaskParameter="AsmDesc" />
                <Output PropertyName="asmCopyright" TaskParameter="AsmCopyright" />
                <Output PropertyName="asmTrademarks" TaskParameter="AsmTrademarks" />
                <Output PropertyName="asmFileVersion" TaskParameter="AsmFileVersion" />
            </ExtractAsmInfo>
    
            <!--This is needed for the output to be accessible from your .wxs file as "!(wix.asmCompName)"-->
            <CreateProperty Value="asmCompName=$(asmCompName);$(WixVariables)">
                <Output TaskParameter="Value" PropertyName="WixVariables" />
            </CreateProperty>
            <CreateProperty Value="asmProdName=$(asmProdName);$(WixVariables)">
                <Output TaskParameter="Value" PropertyName="WixVariables" />
            </CreateProperty>
            <CreateProperty Value="asmDesc=$(asmDesc);$(WixVariables)">
                <Output TaskParameter="Value" PropertyName="WixVariables" />
            </CreateProperty>
            <CreateProperty Value="asmCopyright=$(asmCopyright);$(WixVariables)">
                <Output TaskParameter="Value" PropertyName="WixVariables" />
            </CreateProperty>
            <CreateProperty Value="asmTrademarks=$(asmTrademarks);$(WixVariables)">
                <Output TaskParameter="Value" PropertyName="WixVariables" />
            </CreateProperty>
            <CreateProperty Value="asmFileVersion=$(asmFileVersion);$(WixVariables)">
                <Output TaskParameter="Value" PropertyName="WixVariables" />
            </CreateProperty>
        </Target>
    
        <!--<Target Name="AfterBuild"></Target>-->
    
        <!--Extracts data from the assembly-->
        <UsingTask TaskName="ExtractAsmInfo" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)Microsoft.Build.Tasks.Core.dll">
            <ParameterGroup>
                <!--The assembly path-->
                <AsmPath ParameterType="System.String" Required="true" />
                <!--The return value. Note the return types are extremely limited-->
                <AsmCompName ParameterType="System.String" Output="true" />
                <AsmProdName ParameterType="System.String" Output="true" />
                <AsmDesc ParameterType="System.String" Output="true" />
                <AsmCopyright ParameterType="System.String" Output="true" />
                <AsmTrademarks ParameterType="System.String" Output="true" />
                <AsmFileVersion ParameterType="System.String" Output="true" />
            </ParameterGroup>
            <Task>
                <Reference Include="System.Xml" />
                <Reference Include="System.Xml.Linq" />
                <Using Namespace="System" />
                <Using Namespace="System.Xml.Linq" />
                <Using Namespace="System.Reflection" />
                <Using Namespace="System.Diagnostics" />
                <Code Type="Fragment" Language="cs">
                    <![CDATA[
                FileVersionInfo fileInfo = FileVersionInfo.GetVersionInfo(AsmPath);
                AsmCompName = fileInfo.CompanyName;
                AsmProdName = fileInfo.ProductName;
                AsmDesc = fileInfo.FileDescription;
                AsmCopyright = fileInfo.LegalCopyright;
                AsmTrademarks = fileInfo.LegalTrademarks;
                AsmFileVersion = fileInfo.FileVersion;
            ]]>
                </Code>
            </Task>
        </UsingTask>
    

    Finally, in your .wxs file, you can just use:

    <!--Note the use of an EXCLAMATION MARK and not Dollar Sign as well as the wix. instead of var.-->
    !(wix.asmProdName)
    !(wix.asmCompName)
    !(wix.asmDesc)
    !(wix.asmCopyright)
    !(wix.asmTrademarks)
    !(wix.asmFileVersion)
    
    <!--Example-->
    <Product Id="*" UpgradeCode="1129c4e2-e288-48d5-84dd-587aec927f26"
                 Name="!(wix.asmProdName) Installer" Manufacturer="!(wix.asmCompName)"
                 Language="1033" Version="!(wix.asmFileVersion)">
    
            <Package Id="*" Compressed="yes"
                     InstallerVersion="200" InstallPrivileges="elevated" InstallScope="perMachine"
                     Keywords="Installer" Languages="1033" Platform="x64" ReadOnly="no" ShortNames="no" SummaryCodepage="1252"
                     Description="The !(wix.asmDesc) and it's protocol installer."
                     Comments="!(wix.asmCopyright) | !(wix.asmTrademarks)" />
    ...
    </Product>
    

    Refs


  2. Light.exe: See the WiX light.exe documentation here: https://wixtoolset.org/documentation/manual/v3/overview/light.html#standard-binder-variables

    If you want to run with the version of your main assembly as the setup’s ProductVersion you should be able to just do:

    <Product Id="*" Name="MyProject" Version="!(bind.fileVersion.MyMain.exe)"
             Manufacturer="MyCorp" Language="1033" UpgradeCode="PUT-GUID-HERE">
    
     <..>
    
      <Component Feature="Main">
        <File Id="MyMain.exe" Source="MyMain.exe"></File>
      </Component>
    

    WiX Sample: Complete Github.com sample here.

    The fileLanguage and fileVersion are available for all versioned binaries. Dot NET assemblies support a number of further variables – see documentation (same link as at the top of the answer).

    Rob Mensching: WiX creator Mensching has an answer here. Essence: "You can drive your product version off of an assembly's version using "!(bind.assemblyVersion.FileId)". ... You can only specify binder variables in .wxs files. It's a binder (in light.exe) concept not an MSBuild (in MSBuild.exe reading .wixproj files) concept"

    Heath Stewart: Please check this blog for some information on .NET assembly values:
    https://devblogs.microsoft.com/setup/get-binder-variables-for-assemblies-without-installing-into-the-gac/Essence: "...to get binder variables for assemblies without installing into the GAC set File/@Assembly to “.net” or “win32”, then for the same file set File/@AssemblyApplication to the value for File/@Id"


    Links:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search