This is a migrated thread and some comments may be shown as answers.

Merge Only Telerik Assemblies into WPF Executable

2 Answers 147 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Alan
Top achievements
Rank 1
Alan asked on 08 Oct 2013, 07:46 PM
Some people on here are probably familiar with this blog entry about Merging Telerik's Assemblies into an WPF executable. We actually decided to take a completely different spin and wanted to just merge the Telerik assemblies only leaving all our others untouched (our program as a plug-gable module architecture so we can't merge ALL assemblies). I'm not sure if any one else would be interested in this but I wanted to post it anyway just to get it out there that it is possible. 

MSBuild AfterResolveReferences:
<Target Name="AfterResolveReferences">
  <ItemGroup>
    <EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch(%(ReferenceCopyLocalPaths.Filename), 'Telerik')) And '%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
      <LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
    </EmbeddedResource>
  </ItemGroup>
</Target>

Program.cs:
namespace WpfApplication1
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
 
    public class Program
    {
        [STAThreadAttribute]
        public static void Main()
        {
            var assemblies = new Dictionary<string, Assembly>();
            var executingAssembly = Assembly.GetExecutingAssembly();
            var resources = executingAssembly.GetManifestResourceNames().Where(n => n.StartsWith("Telerik")).Where(n => n.EndsWith(".dll"));
 
            foreach (string resource in resources)
            {
                using (var stream = executingAssembly.GetManifestResourceStream(resource))
                {
                    if (stream == null)
                        continue;
 
                    var bytes = new byte[stream.Length];
                    stream.Read(bytes, 0, bytes.Length);
                    try
                    {
                        assemblies.Add(resource, Assembly.Load(bytes));
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.Print(string.Format("Failed to load: {0}, Exception: {1}", resource, ex.Message));
                    }
                }
            }
 
            AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
            {
                var assemblyName = new AssemblyName(e.Name);
 
                var path = string.Format("{0}.dll", assemblyName.Name);
 
                if (assemblies.ContainsKey(path))
                {
                    return assemblies[path];
                }
 
                return null;
            };
 
            App.Main();
        }
    }
}

We also did an additional spin with a PostBuildEvent of deleting the Telerik files after the build.

PostBuildEvent:
  <PropertyGroup>
    <PostBuildEvent>del /F /Q "$(TargetDir)Telerik*"
rmdir /S /Q "$(TargetDir)de"
rmdir /S /Q "$(TargetDir)es"
rmdir /S /Q "$(TargetDir)fr"
rmdir /S /Q "$(TargetDir)it"
rmdir /S /Q "$(TargetDir)nl"
rmdir /S /Q "$(TargetDir)tr"</PostBuildEvent>
  </PropertyGroup>

I hope someone else finds this useful as we did.

2 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 09 Oct 2013, 07:02 AM
Hi Alan,

 Thank you very much for sharing your solution! I've added 5000 Telerik points to your account.

Regards,
Vlad
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Alan
Top achievements
Rank 1
answered on 09 Oct 2013, 06:03 PM
Update:

Apparently I was a bit too trigger happy on the PostBuildEvent that deletes the Telerik objects. I forgot to account that some of the dlls have XML manifests (and I haven't figured out how to load those from embedded resources properly) so here's an updated PostBuildEvent that only focuses on the dlls.


  <PropertyGroup>
    <PostBuildEvent>del /F /Q "$(TargetDir)Telerik*dll"
rmdir /S /Q "$(TargetDir)de"
rmdir /S /Q "$(TargetDir)es"
rmdir /S /Q "$(TargetDir)fr"
rmdir /S /Q "$(TargetDir)it"
rmdir /S /Q "$(TargetDir)nl"
rmdir /S /Q "$(TargetDir)tr"</PostBuildEvent>
  </PropertyGroup>
Tags
General Discussions
Asked by
Alan
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Alan
Top achievements
Rank 1
Share this question
or