Thursday, February 17, 2011

How to use IlMerge in a Setup Project?

I have use IlMerge to merge all the dlls of my projects in one exe. I use a targets file which is referenced in the "import" of the main csproj.

The ExecCommand in the targets is:

  <Exec Command="&quot;$(ProgramFiles)\Microsoft\Ilmerge\Ilmerge.exe&quot; /out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(IlmergeAssemblies->'&quot;%(FullPath)&quot;', ' ')" />

This works.

But then I have a Setup Project, when it builds, it ignores the "import" and it doesn't merge the dlls. How can I use the targets file with the Setup Project?

I have tried writing this same code for Ilmerge in the Post-build event (in properties of the project) of the main project but it gives me error code 1.

From stackoverflow
  • I'd recommend that you check out the ILMerge MSBuild task. It will take away the complexity of specifying the exact command line arguments as you are doing now.

    On your specific issue, other than the error code 1, are you getting any other error message as a result? Comment, and I'll edit my response as best I can.

    netadictos : See my answer, it was too long to put a comment.
  • I have tried the ILMerge MSBuild Task but I get another error which is the following: Error 1 The "ILMerge.MSBuild.Tasks.ILMerge" task could not be loaded from the assembly ILMerge.MSBuild.Tasks. Could not load file or assembly 'ILMerge, Version=2.8.626.0, Culture=neutral, PublicKeyToken=736440c9b414ea16' or one of its dependencies. Confirm that the declaration is correct, and that the assembly and all its dependencies are available. That is to say it cannot find the IlMerge, but it is installed. I have put it in the GAC, and no result. The lines in my csproj are:

     <UsingTask TaskName="ILMerge.MSBuild.Tasks.ILMerge" AssemblyName="ILMerge.MSBuild.Tasks" />
      <ItemGroup>
        <MergeAsm Include="$(OutputPath)$(TargetFileName)" />
        <MergeAsm Include="$(OutputPath)xx.dll" />
        <MergeAsm Include="$(OutputPath)xxx.dll" />
    </ItemGroup>
    <Target Name="AfterBuild">
        <ILMerge InputAssemblies="@(MergeAsm)" OutputFile="$(OutputPath)nameofproject.exe" TargetKind="SameAsPrimaryAssembly" />
      </Target>
    

    I have also tried with this line in a lot of diferent ways:

    <UsingTask TaskName="ILMerge.MSBuild.Tasks.ILMerge" AssemblyName="ILMerge.MSBuild.Tasks, Version=1.0.0.0, Culture=neutral, PublicKeyToken=682f805726f4d42e" />
    

    And:

    <UsingTask TaskName="ILMerge.MSBuild.Tasks.ILMerge" AssemblyName="g:\Pr\x\xx\ILMerge.MSBuild.Tasks.dll" />
    

    I have put the ilmerge.exe in the same path as the last one. No result.

    Please help.

    Anyway this will solve the problem that when i build the Setup Project it doesn't merge the dlls?

    Marcus Griep : Because of licensing issues, ILMerge itself isn't "merged" into ILMerge.*.Tasks. You'll need to have the ILMerge.exe assembly either in probe-able path, such as in the same folder as ILMerge.MSBuild.Tasks. Give that a try.
    netadictos : Not working. I have tried all the ways. Could you send me an example by mail or something? Another thing. My problem happens when i build the setup project. I have seen that it has a postbuildevent, but as i said i don't know how to write the command like the one in the targets file.
    netadictos : Look at my answer for the final solution i have done.
  • My solution has been this: I put the import in csproj for the Ilmerge targets file which is this:

    <Project 
     DefaultTargets="Build" 
     xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
     <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
    
     <Target Name="AfterBuild">
       <CreateItem Include="@(ReferencePath)" Condition="'%(CopyLocal)'=='true'">
           <Output TaskParameter="Include" ItemName="IlmergeAssemblies"/>
       </CreateItem>
    
       <Message Text="MERGING: @(IlmergeAssemblies->'%(Filename)')" Importance="High" /> 
    
      <Exec Command="&quot;$(ProgramFiles)\Microsoft\Ilmerge\Ilmerge.exe&quot; /out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(IlmergeAssemblies->'&quot;%(FullPath)&quot;', ' ') /log:ILMerge.log" /> 
    
     </Target>
    
     <Target Name="_CopyFilesMarkedCopyLocal"/>
    
    </Project>
    

    Then in the setup project i don't include my exe as primary output, i include it as a file, and its localized resources and content.

    This works I think, but it is a pity that i couldn't execute the postbuild event of my application (the ilmerge process) before packing it into the setup exe.

0 comments:

Post a Comment