Embed DLL in EXE file of Console Application

S

shapper

Hello,

I created a C# Console Application (Publish) that uses a C# library
(FOD.dll).

When I build the Console Application I get two files: Publish.exe and
FOD.dll.

Is it possible to embed the DLL file into the EXE file so I don't get
two files?

I am using VS 2010.

Thank You,

Miguel
 
S

shapper

* shapper said:
Is it possible to embed the DLL file into the EXE file so I don't get
two files?

Try this:
<http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx>

Regards,
Felix

--
 Felix Palmen       (Zirias)  + [PGP] Felix Palmen <[email protected]>
 web:  http://palmen-it.de/ |            http://palmen-it.de/pub.txt
 my open source projects:     |   Fingerprint: ED9B 62D0 BE39 32F9 2488
 http://palmen-it.de/?pg=pro +                5D0C 8177 9D80 5ECF F683

Hello,

I downloaded it and placed ILMerge into my project path and added the
following to my Post Build Event Command Line:

$(SolutionDir)ILMerge /out:$(TargetDir)Publish.exe $(TargetPath) $
(TargetDir)FOD.dll

And I keep having the following error:

The command "C:\Users\MDM\Projects\FOD\ILMerge /out:C:\Users\MDM
\Projects\FOD\Publish.exe C:\Users\MDM\Projects\FOD\Publish.exe C:
\Users\MDM\Projects\FOD\FOD.dll" exited with code 9009.

Any idea what might be wrong?

I tried a few variations but I keep getting the error 9009.

Thank You,
Miguel
 
A

Arne Vajhøj

I created a C# Console Application (Publish) that uses a C# library
(FOD.dll).

When I build the Console Application I get two files: Publish.exe and
FOD.dll.

Is it possible to embed the DLL file into the EXE file so I don't get
two files?

I am using VS 2010.

The ilmerge utility should be able to merge them.

But it seems a bit of waste to me to:
- first split the code in two to build both an EXE and a DLL
- then merge the two together

The point in having the DLL should be that it can be updated
separately and be reused by other EXE.

Arne
 
S

shapper

The ilmerge utility should be able to merge them.

But it seems a bit of waste to me to:
- first split the code in two to build both an EXE and a DLL
- then merge the two together

The point in having the DLL should be that it can be updated
separately and be reused by other EXE.

Arne

This is more a redistribution issue.

I mean, I have some base DLL's that I use in most of my projects.

But in this particular project, a Console Application, I would like to
be able to redistribute only the EXE file.
This is why I am trying to merge the DLL with that EXE file. Just in
this case.

I have been trying many options on Post Build Event Command Line but I
keep having an error:

When I Build the Console Application I get two files, Publish.exe and
FOD.Net.dll, which I want to merge.

On Post-Build event command line I have the following:
“C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe” /log:"$
(TargetDir)ILMerge.log" /out:"$(TargetDir)PublishMerged.exe" "$
(TargetDir)Publish.exe" "$(TargetDir)FOD.Net.dll"

But I keep getting an error:
The command "“C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe” /
log:"C:\Users\MDM\Projects\__Publish\bin\Release\ILMerge.log" /out:"C:
\Users\MDM\Projects\__Publish\bin\Release\PublishMerged.exe" "C:\Users
\MDM\Projects\__Publish\bin\Release\Publish.exe" "C:\Users\MDM\Projects
\__Publish\bin\Release\FOD.Net.dll"" exited with code 1.

And on Release folder I get a file PublishMerged.exe but with 0KB

Any idea?
 
K

kndg

[...]
And I keep having the following error:

The command "C:\Users\MDM\Projects\FOD\ILMerge /out:C:\Users\MDM
\Projects\FOD\Publish.exe C:\Users\MDM\Projects\FOD\Publish.exe C:
\Users\MDM\Projects\FOD\FOD.dll" exited with code 9009.

Any idea what might be wrong?

Are you sure the above error is exactly as shown to you? (I found it
wierd because normally Visual Studio will output the build to debug or
release folder...) Ilmerge, for example, does not like whitespace in
file path, so you would have to surround it with quotes. Here is the
command that is always works for me.

ilmerge /wildcards /t:exe /out:"$(SolutionDir)$(TargetFileName)"
"$(TargetPath)" "$(TargetDir)*.dll"

I have add ILMerge installation folder to my environment path, so I can
access it anywhere.

Regards.
 
K

kndg

The ilmerge utility should be able to merge them.

But it seems a bit of waste to me to:
- first split the code in two to build both an EXE and a DLL
- then merge the two together

The point in having the DLL should be that it can be updated
separately and be reused by other EXE.

Arne

Usually I will merge all my dll into one big file, but occasionally I do
with executable also. Is it just for convenience when I can just merge
all the required library and have it as one file to send to my friend
for demo purpose.
 
A

Arne Vajhøj

This is more a redistribution issue.

I mean, I have some base DLL's that I use in most of my projects.

But in this particular project, a Console Application, I would like to
be able to redistribute only the EXE file.
This is why I am trying to merge the DLL with that EXE file. Just in
this case.

That argument come up occasionally.

It does have some merit, so let us just say that you need to do it.
I have been trying many options on Post Build Event Command Line but I
keep having an error:

When I Build the Console Application I get two files, Publish.exe and
FOD.Net.dll, which I want to merge.

On Post-Build event command line I have the following:
“C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe” /log:"$
(TargetDir)ILMerge.log" /out:"$(TargetDir)PublishMerged.exe" "$
(TargetDir)Publish.exe" "$(TargetDir)FOD.Net.dll"

But I keep getting an error:
The command "“C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe” /
log:"C:\Users\MDM\Projects\__Publish\bin\Release\ILMerge.log" /out:"C:
\Users\MDM\Projects\__Publish\bin\Release\PublishMerged.exe" "C:\Users
\MDM\Projects\__Publish\bin\Release\Publish.exe" "C:\Users\MDM\Projects
\__Publish\bin\Release\FOD.Net.dll"" exited with code 1.

And on Release folder I get a file PublishMerged.exe but with 0KB

Any idea?

Given that this part of a special packaging, then I would probably
just merge manually before delivering to the people needing the
single EXE.

Arne
 
A

Arne Vajhøj

Usually I will merge all my dll into one big file, but occasionally I do
with executable also. Is it just for convenience when I can just merge
all the required library and have it as one file to send to my friend
for demo purpose.

It happens.

But it is not really how DLL's are intended to be used.

Arne
 
F

Felix Palmen

Just as a related question:

When building native applications (using mingw-gcc, but I guess the same
would apply to VS C/C++), I can instruct the linker to do static
linking, so I get just one .exe in the first place. I do this for
example to link the SDL libs as I don't expect them to be present on a
normal windows box and I don't want to redistribute the DLLs.

Is there /any/ way to link a managed app statically, too? The approach
of merging the assemblies later has some drawbacks (like, e.g., no
support for WPF).

Regards,
Felix
 
F

Felix Palmen

* Peter Duniho said:
But in truth you may do your customers a disservice with static linking.
It causes the executable to be much larger than it otherwise could
have been, and if more than one process uses a particular library, it
causes the in-memory footprint to be larger too (because each process
winds up with its own copy…in most cases, DLL code in memory can be
shared between processes).

In this particular case, I was talking about a little cross-platform
native-code game I'm developing and as it uses SDL along with
dependencies (libpng, zlib) which are quite common on unix platforms,
but not commonly used on windows, I decided to link statically /only/
for windows. The binary is still less than 600K :)
I'm not exactly sure what you mean by "no support for WPF", but you
wouldn't want to statically link WPF into your program anyway. It's huge.

Uhm no, of course not. I'm talking about linking an application that
/uses/ WPF with some own DLLs. ILMerge's website states this isn't
supported.

Of course, those same DLLs are deployed to the GAC on our internal
machines where some backend services do their work. I'm just creating a
little frontend client using WPF for one -- hmm -- "special" customer
and thought about delivering it as an .exe without the need to install
something (except .NET4 runtime, of course). If this isn't possible,
I'll probably build another .msi for them.

Regards,
Felix
 
A

Arne Vajhøj

Just as a related question:

When building native applications (using mingw-gcc, but I guess the same
would apply to VS C/C++), I can instruct the linker to do static
linking, so I get just one .exe in the first place. I do this for
example to link the SDL libs as I don't expect them to be present on a
normal windows box and I don't want to redistribute the DLLs.

Is there /any/ way to link a managed app statically, too? The approach
of merging the assemblies later has some drawbacks (like, e.g., no
support for WPF).

If the code exists in the form of netmodules then you can
do something.

But if the code only exists in the form of DLL's then ILMERGE
is the only way.

And practically all libraries only exists as DLL's (there are
no LIB's in .NET and netmodules are not common at all).

So ...

Arne

PS: I would expect that the WPF problem is due to some
fundamental problem not due to a bug in the ILMERGE
tool meaning that any merging will have the problem.
 
A

Arne Vajhøj

Arne said:
If the code exists in the form of netmodules then you can
do something. [...]

What can be used to merge modules? I know you can create a multi-file
assembly, but that's just a placeholder assembly that refers to the
individual module files. Is there a way to get all the module files into
the same assembly?

Yes.

Use link instead of al.

Requires .NET 2.0.

Arne
 
S

shapper

Arne said:
If the code exists in the form of netmodules then you can
do something. [...]
What can be used to merge modules? I know you can create a multi-file
assembly, but that's just a placeholder assembly that refers to the
individual module files. Is there a way to get all the module files into
the same assembly?

Yes.

Use link instead of al.

Requires .NET 2.0.

Arne

I have been trying to solve this but no luck. Let me explain what I
have:

I am using ILMerge to merge the following files: Build.exe,
FlyOnDreams.Net.dll and Ionic.Zip.dll.

- Build.exe > Net 4.0 Console Application
- FlyOnDreams.Net.dll > Net 4.0 Library. It contains classes with
helpers methods.
It depends only on NET Framework
libraries.
- Ionic.Zip.dll > A Net Zip library (http://dotnetzip.codeplex.com/)

I used the following config file (From ILMerge site):

<?xml version ="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<requiredRuntime safemode="true" imageVersion="v4.0.30319"
version="v4.0.30319"/>
</startup>
</configuration>

And the following Windows Batch File:
ILMerge /log:ILMerge.log /target:exe /out:BuildMerged.exe Build.exe
FlyOnDreams.Net.dll Ionic.Zip.dll

The BuildMerged.exe is built successfully but it crashes when I run
it.

I debugged it and get the following error:
Could not load type 'System.Func`2' from assembly 'mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

I checked the Log and I think the problem might be here:

“Location for referenced assembly 'System.Core' is 'C:\Windows
\Microsoft.Net\assembly\GAC_MSIL\System.Core
\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll'
There were errors reported in System.Core's metadata.
Could not resolve type reference: [mscorlib]System.Func`2.
Could not resolve type reference: [mscorlib]System.Func`3.
Could not resolve type reference:
[System]System.Collections.Generic.ISet`1.
Location for referenced assembly 'System' is 'C:\Windows
\Microsoft.NET\Framework64\v2.0.50727\System.dll'
There were no errors reported in System's metadata.
Location for referenced assembly 'System.Drawing' is 'C:\Windows
\Microsoft.NET\Framework64\v2.0.50727\System.Drawing.dll'
There were no errors reported in System.Drawing's metadata.
Location for referenced assembly 'System.Data.Entity' is 'C:\Windows
\Microsoft.Net\assembly\GAC_MSIL\System.Data.Entity
\v4.0_4.0.0.0__b77a5c561934e089\System.Data.Entity.dll'
There were errors reported in System.Data.Entity's metadata.
Could not resolve type reference:
[mscorlib]System.Runtime.TargetedPatchingOptOutAttribute.
Could not resolve member reference:
System.Runtime.TargetedPatchingOptOutAttribute::.ctor.
ILMerge: Done.”

I am using ILMerge version 2.10.0526. The latest version.

But again, the Merged File is created, and in log I read
“ILMerge:Done”.

What might be wrong?

Finally, here it is the full log:

ILMerge version 2.10.526.0
Copyright (C) Microsoft Corporation 2004-2006. All rights reserved.
ILMerge /log:ILMerge.log /target:exe /out:BuildMerged.exe Build.exe
FlyOnDreams.Net.dll Ionic.Zip.dll
Set platform to 'v2', using directory 'C:\Windows\Microsoft.NET
\Framework64\v4.0.30319\..\v2.0.50727' for mscorlib.dll
Running on Microsoft (R) .NET Framework v4.0.30319
mscorlib.dll version = 4.0.0.0
The list of input assemblies is:
Build.exe
FlyOnDreams.Net.dll
Ionic.Zip.dll
Trying to read assembly from the file 'C:\Users\Miguel\Projects\Fly On
Dreams\Architecture\Client\Project\Build.exe'.
Successfully read in assembly.
There were no errors reported in Build's metadata.
Trying to read assembly from the file 'C:\Users\Miguel\Projects\Fly On
Dreams\Architecture\Client\Project\FlyOnDreams.Net.dll'.
Can not find PDB file. Debug info will not be available for assembly
'FlyOnDreams.Net.dll'.
Successfully read in assembly.
There were no errors reported in FlyOnDreams.Net's metadata.
Trying to read assembly from the file 'C:\Users\Miguel\Projects\Fly On
Dreams\Architecture\Client\Project\Ionic.Zip.dll'.
Can not find PDB file. Debug info will not be available for assembly
'Ionic.Zip.dll'.
Successfully read in assembly.
There were no errors reported in Ionic.Zip's metadata.
Checking to see that all of the input assemblies have a compatible
PeKind.
Build.PeKind = ILonly, Requires32bits
FlyOnDreams.Net.PeKind = ILonly
Ionic.Zip.PeKind = ILonly
All input assemblies have a compatible PeKind value.
AssemblyResolver: Assembly 'FlyOnDreams.Net' is referencing assembly
'System'.
AssemblyResolver: Attempting referencing assembly's directory.
AssemblyResolver: Did not find assembly in referencing assembly's
directory.
AssemblyResolver: Attempting input directory.
AssemblyResolver: Did not find assembly in input directory.
AssemblyResolver: Attempting user-supplied directories.
AssemblyResolver: No user-supplied directories.
AssemblyResolver: Attempting framework directory.
Can not find PDB file. Debug info will not be available for assembly
'System'.
Resolved assembly reference 'System' to 'C:\Windows\Microsoft.NET
\Framework64\v4.0.30319\..\v2.0.50727\System.dll'. (Used framework
directory.)
AssemblyResolver: Assembly 'FlyOnDreams.Net' is referencing assembly
'System.Drawing'.
AssemblyResolver: Attempting referencing assembly's directory.
AssemblyResolver: Did not find assembly in referencing assembly's
directory.
AssemblyResolver: Attempting input directory.
AssemblyResolver: Did not find assembly in input directory.
AssemblyResolver: Attempting user-supplied directories.
AssemblyResolver: No user-supplied directories.
AssemblyResolver: Attempting framework directory.
Can not find PDB file. Debug info will not be available for assembly
'System.Drawing'.
Resolved assembly reference 'System.Drawing' to 'C:\Windows
\Microsoft.NET\Framework64\v4.0.30319\..
\v2.0.50727\System.Drawing.dll'. (Used framework directory.)
AssemblyResolver: Assembly 'FlyOnDreams.Net' is referencing assembly
'System.Data.Entity'.
AssemblyResolver: Attempting referencing assembly's directory.
AssemblyResolver: Did not find assembly in referencing assembly's
directory.
AssemblyResolver: Attempting input directory.
AssemblyResolver: Did not find assembly in input directory.
AssemblyResolver: Attempting user-supplied directories.
AssemblyResolver: No user-supplied directories.
AssemblyResolver: Attempting framework directory.
AssemblyResolver: Did not find assembly in framework directory.
AssemblyResolver: Unable to resolve reference. (It still might be
found, e.g., in the GAC.)
Merging assembly 'Build' into target assembly.
Merging assembly 'FlyOnDreams.Net' into target assembly.
Merging assembly 'Ionic.Zip' into target assembly.
Merging assembly-level attributes from assembly 'Build' into target
assembly.
Copying 2 Win32 Resources from assembly 'Build' into target assembly.
Transferring entry point 'Build.Program.Main(System.String[])' from
assembly 'Build' to assembly 'BuildMerged'.
There were no errors reported in the target assembly's metadata.
ILMerge: Writing target assembly 'BuildMerged.exe'.
AssemblyResolver: Assembly 'Build' is referencing assembly
'System.Core'.
AssemblyResolver: Attempting referencing assembly's directory.
AssemblyResolver: Did not find assembly in referencing assembly's
directory.
AssemblyResolver: Attempting input directory.
AssemblyResolver: Did not find assembly in input directory.
AssemblyResolver: Attempting user-supplied directories.
AssemblyResolver: No user-supplied directories.
AssemblyResolver: Attempting framework directory.
AssemblyResolver: Did not find assembly in framework directory.
AssemblyResolver: Unable to resolve reference. (It still might be
found, e.g., in the GAC.)
Location for referenced assembly 'mscorlib' is 'C:\Windows
\Microsoft.NET\Framework64\v2.0.50727\mscorlib.dll'
There were no errors reported in mscorlib's metadata.
Location for referenced assembly 'System.Core' is 'C:\Windows
\Microsoft.Net\assembly\GAC_MSIL\System.Core
\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll'
There were errors reported in System.Core's metadata.
Could not resolve type reference: [mscorlib]System.Func`2.
Could not resolve type reference: [mscorlib]System.Func`3.
Could not resolve type reference:
[System]System.Collections.Generic.ISet`1.
Location for referenced assembly 'System' is 'C:\Windows\Microsoft.NET
\Framework64\v2.0.50727\System.dll'
There were no errors reported in System's metadata.
Location for referenced assembly 'System.Drawing' is 'C:\Windows
\Microsoft.NET\Framework64\v2.0.50727\System.Drawing.dll'
There were no errors reported in System.Drawing's metadata.
Location for referenced assembly 'System.Data.Entity' is 'C:\Windows
\Microsoft.Net\assembly\GAC_MSIL\System.Data.Entity
\v4.0_4.0.0.0__b77a5c561934e089\System.Data.Entity.dll'
There were errors reported in System.Data.Entity's metadata.
Could not resolve type reference:
[mscorlib]System.Runtime.TargetedPatchingOptOutAttribute.
Could not resolve member reference:
System.Runtime.TargetedPatchingOptOutAttribute::.ctor.
ILMerge: Done.

Thank You,
Miguel Moura
 
A

Arne Vajhøj

I have been trying to solve this but no luck. Let me explain what I
have:

I am using ILMerge to merge the following files: Build.exe,
FlyOnDreams.Net.dll and Ionic.Zip.dll.

- Build.exe> Net 4.0 Console Application
- FlyOnDreams.Net.dll> Net 4.0 Library. It contains classes with
helpers methods.
It depends only on NET Framework
libraries.
- Ionic.Zip.dll> A Net Zip library (http://dotnetzip.codeplex.com/)

I used the following config file (From ILMerge site):

<?xml version ="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<requiredRuntime safemode="true" imageVersion="v4.0.30319"
version="v4.0.30319"/>
</startup>
</configuration>

And the following Windows Batch File:
ILMerge /log:ILMerge.log /target:exe /out:BuildMerged.exe Build.exe
FlyOnDreams.Net.dll Ionic.Zip.dll

The BuildMerged.exe is built successfully but it crashes when I run
it.

I debugged it and get the following error:
Could not load type 'System.Func`2' from assembly 'mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

I checked the Log and I think the problem might be here:

“Location for referenced assembly 'System.Core' is 'C:\Windows
\Microsoft.Net\assembly\GAC_MSIL\System.Core
\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll'
There were errors reported in System.Core's metadata.
Could not resolve type reference: [mscorlib]System.Func`2.
Could not resolve type reference: [mscorlib]System.Func`3.
Could not resolve type reference:
[System]System.Collections.Generic.ISet`1.
Location for referenced assembly 'System' is 'C:\Windows
\Microsoft.NET\Framework64\v2.0.50727\System.dll'
There were no errors reported in System's metadata.
Location for referenced assembly 'System.Drawing' is 'C:\Windows
\Microsoft.NET\Framework64\v2.0.50727\System.Drawing.dll'
There were no errors reported in System.Drawing's metadata.
Location for referenced assembly 'System.Data.Entity' is 'C:\Windows
\Microsoft.Net\assembly\GAC_MSIL\System.Data.Entity
\v4.0_4.0.0.0__b77a5c561934e089\System.Data.Entity.dll'
There were errors reported in System.Data.Entity's metadata.
Could not resolve type reference:
[mscorlib]System.Runtime.TargetedPatchingOptOutAttribute.
Could not resolve member reference:
System.Runtime.TargetedPatchingOptOutAttribute::.ctor.
ILMerge: Done.”

I am using ILMerge version 2.10.0526. The latest version.

But again, the Merged File is created, and in log I read
“ILMerge:Done”.

What might be wrong?

It looks very suspiciously that you use some 2.0 DLL's in
something that should be 4.0!

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top