【问题标题】:C# CompileAssemblyFromSource, add referenced assemblies it needs?C# CompileAssemblyFromSource,添加它需要的引用程序集?
【发布时间】:2026-01-17 11:05:01
【问题描述】:

我有 CompileAssemblyFromSource 用于仅引用我的程序(编译它)使用的程序集的代码。它工作得很好。

但是,如果我需要编译具有“using blah;”的代码声明,它将无法找到 blah 并说它缺少资源。

因此,如果它是“System.Windows.Forms”,我说“compilerparams.ReferencedAssemblies.Add("System.Windows.Forms.dll")”,它就可以工作。

所以我可以解析代码文件并获取所有“使用”参数,但我怎么知道这些应该是“*.dll”添加,或者它们是其他地方的名称空间或诸如此类? .NET 有没有办法接受“System.Windows.Forms”并吐出“System.Windows.Forms.dll”,因为这是它所需要的等等?

【问题讨论】:

  • 无法找到包含您的类的程序集,因为名称空间可以跨程序集产生,并且有人可以使用您使用的完全相同的类名和名称空间创建 DLL,因此您的代码无法编译.要解决问题,您必须提供二进制文件,例如附属程序集,以与源代码相同的方式作为引用包含在内,Visual Studio 保存引用(包括哈希)
  • Assembly.GetAssembly(typeof(MyType)) 呢?您必须知道实际使用了哪些类型,而不仅仅是 using 语句,因为单个命名空间可以来自每个 @ArturMustafin 的多个程序集
  • @mellamokb:如果您的代码如下所示:Assembly.GetAssembly(typeof(MyType)),这意味着在编译时类型 MyType 是已知的(typeof 语句需要使用),或者代码本身或者在正在编译的源代码中,情况并非如此。在您的情况下,您必须为 AppDomain.AssemblyResolve 事件处理程序提供解析方法来定位和下载程序集。但是,无论如何,正如人们所说,您不能仅依靠源代码来解决问题
  • 在您的源代码中 System.Windows.Forms 可以是自定义类 Forms,位于自定义程序集中的命名空间 System.Windows 中,而不是在 GAC 中(或者它可以在 GAC 中,但是具有不同的签名密钥,即使具有相同的程序集/文件版本),命名为System.Windows.Forms.dll,因此无法获取字符串“System.Windows.Forms”并获取相应的程序集
  • 最终,有一种方法,但您应该提供完整的程序集名称(包括版本号、公共签名等),因为它通常存储在项目文件中。通常,如果没有其他信息,只有 GAC 中的 KNOWN 程序集可以在运行时加载。即使这样,您也必须使用 AssemblyInfo 类来提供程序集名称并获取要引用的 Assembly 对象

标签: c# compileassemblyfromsource


【解决方案1】:
  1. 阅读文章How the Runtime Locates Assemblies
  2. 在编译代码之前,加载第 1 点中提到的位置中的所有程序集
  3. 加载所有程序集中的所有类型并保留命名空间字典,类型对
  4. 当在源代码中遇到 using 时,尝试从 3 中的字典中添加程序集的引用

【讨论】: