There is a solution (Solution). There are 4 projects in it. One main, three minor. The main project uses types from minor and vice versa. In short, they are all intertwined. How does all this compile into one .EXE file for distribution?

UPD Since it seems that not everyone understood what it was about, then I will try to supplement my question.

Here is a small example: The solution Explorer shows that two projects have been added to the Solution. The App2 project depends on the App1 project. App1 added to References. enter image description here

Corresponding dependencies are also spelled out. enter image description here

If you simply compile this Solution, then at the output we get two files - App2.exe and App1.dll. Thus, in order for the application to work, say on another computer, you need to rewrite these two files there. Otherwise a runtime error will occur. Something like Could not load file or assembly. Cannot find the file specified . So I would like to compile the application in such a way that in the end only one file is obtained - App2.exe. And to distribute this application could be a single file. And the file App1.dll was built into it.

  • 3
    And what exactly is the problem? Why it is impossible to deploy one .exe and three .dll? - VladD
  • It is possible, but I would like a single file, if possible. - Mikhail Danshin
  • one
    Immediately compile into one common exe can not. But you can merge several dll / exe into one after the assembly. See answers by reference. - PashaPash
  • 2
    Or, alternatively, you can pour your dll as resources - but I would advise you the option with ilmerge - this is the normal official (tm) method, and not a self-written crutch. - PashaPash
  • one
    Yes, ILMerge helped. Added to Post-build events this line "$ (SolutionDir) ILMerge \ ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe "" $ (TargetDir) $ (TargetName) .exe "" $ (TargetDir) .dll "/ target: exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 / wildcards * Works great! - Mikhail Danshin

3 answers 3

Possible solutions:

Merge builds into one after compilation

Several assemblies can be glued to one after compilation using the ILMerge utility.

She is on NuGet.org :

Install-Package ilmerge 

Call format:

 ilmerge /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" /lib:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies" /targetplatform:v4 /out:out.dll mydll1.dll mydll2.dll 

before using the path it is worth correcting for the current

Similar utilities - il-repack , Mono.Merge

Inclusion of DLL in EXE in the form of Embedded Resource with the substitution of the standard loading mechanism:

  1. Add bin\someassembly.dll to exe project via Add Existing Item / arrow on Add / Add as Link, set Build Type = Embedded Resource
  2. Add someassembly project to References. Set reference to Copy Local = false - to avoid copying to bin.
  3. Process CurrentDomain_AssemblyResolve :

     using System; using System.Reflection; using System.Windows.Forms; namespace WindowsFormsApplication7 { static class Program { [STAThread] static void Main() { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { var assemblyName = new AssemblyName(args.Name).Name; if (assemblyName == "someassembly") { using (var stream = typeof(Program).Assembly.GetManifestResourceStream( "WindowsFormsApplication7." + assemblyName + ".dll")) { byte[] assemblyData = new byte[stream.Length]; stream.Read(assemblyData, 0, assemblyData.Length); return Assembly.Load(assemblyData); } } else { return null; } } } } 

This is a minimal working example. If it does not work, run under the debugger. Most likely you did not guess with the name of the resource, and GetManifestResourceStream returns null . Make sure that the type of the item is set in the Embedded Resource (and not just in the Resource). You can view the names of all available resources directly in the debugger, by calling

 typeof(Program).Assembly.GetManifestResourceNames() 

The project entirely on githaba, on the example of SevenZipSharp: https://github.com/PashaPash/SevenZipSharp-Embedded

Enable assemblies as resources, automatic option

Install the Costura.Fody package via nuget and get one exe on exit.

 > PM> Install-Package Costura.Fody 

Alternatives:

    I will correct myself, the small utility from Microsoft - ILMerge will help you to solve the problem. I will add that there is a good article on this topic.

      There is also a crutch method: create a new project and add all existing code files to it, then compile.

      • @cyadvert, why not? That is the answer. - Qwertiy
      • one
        You can add files as a link - and, by the way, not such a crutch method. - PashaPash
      • @PashaPash, I do not know what you mean by link. The studio will allow you to include the same files in several projects. - Qwertiy
      • @LEQADA, guilty, guys, honestly - the finger twitched ... Well this is Qwertiy message - I don’t even check, I wanted to skip it ... I missed it - cyadvert
      • 2
        @Qwertiy add exiting item copies the file to the current project by default. But in the dialogue itself there is an arrow on the button, on which a dropdown falls out with the second option - add as link. Which does not copy, but simply links the existing file - PashaPash