How to bundle dependency .dll files with main prod

2019-08-27 05:10发布

问题:

I am creating a wix installer for a .NET project with many dependencies. Currently, I have a working .msi installer, but as expected all the dependency .dll's (as well as a resources folder) are placed in the same directory as the installed application rather than being bundled with it.

Reading the answer to WIX Bundle Creation, it seems possible to keep my Product as is in one file and have another file with a Bundle referencing this product, but I cannot seem to find any examples of this.

Is there a simple way to do this? I've included the outline of the product code below.

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:ui="http://schemas.microsoft.com/wix/UIExtension">  
    <Product Id="*" Name="#####" Language="1033" Version="1.0.0.0" Manufacturer="..." UpgradeCode="...">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Platform="x64"/>

    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
    <UIRef Id="WixUI_InstallDir" />

        <MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate EmbedCab="yes"/>

        <Feature Id="ProductFeature" Title="alphaInstaller" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
            <ComponentGroupRef Id="ProductMenuComponents" />
            <ComponentGroupRef Id="DependencyComponents"/>
            <ComponentGroupRef Id="ResourcesComponents"/>
        </Feature>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
         <Directory Id="ProgramMenu64Folder">
            ...
        </Directory>
    </Fragment>

    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
          <Component Id="CMP_alphaGUISetup" Win64="yes">
             <File Id="FILE_alphaGUIApplication.exe" Source="$(var.alphaGUI.TargetPath)" KeyPath="yes"></File>
          </Component>
        </ComponentGroup>
    <ComponentGroup Id="ProductMenuComponents" Directory="ApplicationProgramsFolder">
      <Component Id="ApplicationShortcut" Guid="..." >
        <Shortcut .../>
        <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
        <RegistryValue .../>
      </Component>
    </ComponentGroup>
    <ComponentGroup Id="DependencyComponents" Directory="INSTALLFOLDER" Source=...>
      <Component Id="log4net">
        <File Name="log4net.dll" />
      </Component>
        ...
    </ComponentGroup>
    <ComponentGroup Id="ResourcesComponents" Directory="ResourcesFolder" Source=...>
      <Component Id="logo.ico">
        ...
    </ComponentGroup>
    </Fragment>
</Wix>

回答1:

Single-file-deployment?: I am a little unsure if this is what you ask, but it seems you want to embed all dlls within a single .NET executable file?


Ilmerge.exe: This is not my area of expertise, but there is this answer: Embedding DLLs in a compiled executable that you can check out. The tool Ilmerge.exe - how-to (also see answer below). Mock-up:

ILMerge.exe /target:winexe /out:All.exe Main.exe one.dll two.dll

I have never used this. I would be very surprised if it worked for all cases. Obviously. Worth a try? Test merged binary using virustotal.com (release mode binary) to determine if you trigger any malware warnings.

Resource File Embedding: You can also embed resource files such as images, html templates and other things within a .NET executable, if that is what you want. Just the tersest mock-up I could find (source):

  • Add file TestFile.txt as embedded resource: Project Menu >> Properties >> Resources >> Add Existing file.

  • Code access: string queryFromResourceFile = Properties.Resources.Testfile.ToString();

Shared Project: There is the elusive "Shared Project" for .NET projects / C# type that gets compiled into your main executable at build time. Not sure when this project type came along. It is present in VS2017.

Single Project Option: You could also obviously move all code files into the same project and compile an executable that way. I wouldn't do this unless you intend to keep all source files in one project permanently. Otherwise you get a very silly build process? I guess all options should be mentioned, so we remember or acknowledge why they are bad.

Further Options?: I am sure there are further options. Probably some flags for the compiler that I am unaware of. Please add if you know of any. Found this somewhat crazy approach on youtube (setting dll resources to be embedded inside the Visual Studio project, and then add code to read the embedded assembly). I wonder how anti-virus software judges the latter? Test using virustotal.com (release mode binary). Same goes for binaries merged with Ilmerge.exe I guess.


Links:

  • How to merge multiple assemblies into one?
  • Embedding DLLs in a compiled executable


回答2:

Please add the Media Element to your WXS file right below the package element and that should fix it.

<Media Id="1" Cabinet="simple.cab" EmbedCab="yes" />


标签: .net wix 64-bit