2

I am very new to programming and would love some help. I just installed MahApps.Metro and it looks really nice and nifty. But I cannot run the program without System.Windows.Interactivity.dll and MahApps.Metro.dll in the same folder, if I try running it without those two DLL's it just .. doesn't open. Is there a way to incorporate those DLL's in the exe or just run it without them?

Thanks in advance for any help!

2 Answers2

1

You could use ILMerge (http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=17630).

With ILMerge it is possible to merge all assemblies (all dlls in your folder) to, for instance one exe, file. See this explanation: http://research.microsoft.com/en-us/people/mbarnett/ILMerge.aspx

But what's your problem about deploying all assemblies. I think this is very common these days.

Kai
  • 1,953
  • 2
  • 13
  • 18
  • Yes, I think it looks neater just to have one EXE because I am 13 and just share programs usb to usb with friend, they never exceed 20mb so its nothing big –  Apr 24 '13 at 08:15
  • MahApps is WPF : Merging WPF assemblies ILMerge is not able to merge WPF assemblies. They contain resources with encoded assembly identities. ILMerge is unable to deserialize the resources, modify the assembly identities, and then re-serialize them. Sorry! –  Apr 24 '13 at 08:16
0

You can't run your application without these assemblies if they are used. After all, you are using code that is only in these assemblies, and what should your application do if it doesn't find required code other than shutdown?

But there is a way to embed the assemblies in your exe, so you only have to redistribute one file. The referenced assemblies can be added as an embedded resource (add the dll to your project and set its "Build Action" to "Embedded Resource") and loaded from there.

You'll then need to load it yourself in the AppDomain.AssemblyResolve event of the current AppDomain. For this, you need to add a handler to this event like this:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
    String resourceName = 
        "YourDefaultNameSpace." + new AssemblyName(args.Name).Name + ".dll";
    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) {
        Byte[] assemblyData = new Byte[stream.Length];
        stream.Read(assemblyData, 0, assemblyData.Length);
        return Assembly.Load(assemblyData);
    }
};

For a WPF app, you can override App.OnStartup (in App.xaml.cs) and add it there:

protected override void OnStartup(StartupEventArgs e) {
    base.OnStartup(e);
    // ---- Add the handler code here ----
}

Original source and more details:
Jeffrey Richter: Excerpt #2 from CLR via C#, Third Edition

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • @RohylJoshi You just need to add the code in a location where your app starts. If you have a WPF App, you could override `App.OnStartup` in your `App.xaml.cs` file and add it there. You just need to replace "YourDefaultNameSpace." with the default namespace of your application (you can find that in the application properties (and don't forget the dot at the end)). BTW this method also works for WPF assemblies. – Botz3000 Apr 24 '13 at 09:12
  • Wait... I have a mainwindow.xaml, do I put it in the mainwindow.xaml.cs , and if I do, where :O –  Apr 25 '13 at 03:45
  • @RohylJoshi `App.OnStartup` would be a better idea. See my edited post for some more details on how to override it. – Botz3000 Apr 25 '13 at 06:33