将.dll文件合并到C#程序集中?

4

使用 #C.net 3.5

我知道ILMerge和类似的技术,但我实际上想利用Jeffrey Richter的建议

在将此代码添加到构造函数后,会出现命名空间问题。

Jeffrey Richter的代码:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
    String resourceName = "AssemblyLoadingAndReflection." + 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);
    }
};

我将两个DLL设置为“嵌入式资源”并将它们添加为引用,但是当我构建程序时,这两个DLL仍然是“未嵌入的”。然后我将它们作为引用移除,但是在构建程序时会出现错误,显示:“找不到类型或命名空间...是否缺少使用指令或程序集引用?”我已经将这两个命名空间添加为使用指令...然后我尝试删除这两个引用和两个使用指令,但仍然出现错误。
这是我的代码:
using System.Reflection;
    namespace WindowsFormsApplication2
    {
        public partial class Ndice : Form
        {
            public Ndice()
            {
                AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
                {
                    String resourceName = "AssemblyLoadingAndReflection." + 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);
                    }
                };
                InitializeComponent();
               }
           }
        }

你理解你粘贴的代码吗?它恰好做了你要求的事情。 - x0n
“AssemblyLoadingAndReflection.” 应该被更改吗?如果是,应该更改成什么? - Dacto
你的原始代码接近正确,但是可执行文件名被硬编码在其中。请参考下面的答案。 - userSteve
3个回答

3
从您问题的描述中,有些事情不太清楚,可能需要为了回答而需要:
1. 到底是什么出了问题?编译时失败还是运行时失败? 2. 您能展示不能编译或无法在运行时工作的代码吗? 3. 当您说程序集“未嵌入”时,您是指什么?
基本上,据我所知,您有一个尝试使用这两个程序集中的类的代码。这段代码是静态的,意味着类必须在编译时已知。换句话说,在编译使用其中定义类型的代码之前,您必须引用那两个程序集。
我并不真正理解当您将这些程序集添加为引用时发生了什么问题。如果您困扰的是它们被复制到bin/debug目录中,那也不应该防止它们被嵌入到主要程序集中。因此,您可以尝试手动从bin/debug目录中删除它们,或者将其设置为“复制本地=假”。
还有一件事-您遇到的提到“using”和“namespaces”的错误实际上并不是关于命名空间的。这个错误意味着编译器找不到所需的类型。这可能是因为您删除了对这两个程序集的引用。

谢谢,你的指针帮助我解决了问题,在发布应用程序文件的属性区域,默认情况下它们被包含在内。 - Dacto
运行程序并尝试使用dll后,我收到了以下错误信息:无法加载文件或程序集“Assembly1231,Version=0.9.6.8,Culture=neutral,PublicKeyToken=null”或其某个依赖项。无效指针(来自HRESULT的异常:0x80004003(E_POINTER))。 - Dacto

3
将其放在构造函数中,而不是InitializeComponent()。将using指令添加到主类源代码文件中不是问题。

-1
String resourceName = "AssemblyLoadingAndReflection." + new AssemblyName(args.Name).Name + ".dll";

应该被改为:

String resourceName = Application.Current.GetType().Namespace + "." + new AssemblyName(args.Name).Name + ".dll";

Application.Current不存在?你是不是指的是CurrentCulture? - userSteve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接