c# - 使用 Roslyn 编译时如何设置程序集版本、文化和公钥 token ?

标签 c# .net compilation roslyn assembly-signing

我正在使用 Roslyn 将 Visual Studio 中的 CSharpCompilation 对象发送到文件。生成的 DLL 不包含除程序集元数据之外的任何程序集信息,我想添加版本并在可能的情况下对其进行签名。这些如何使用 Roslyn 完成?

最佳答案

您需要包含设置 Assembly* 属性的源代码,就像在 VS C# 项目模板中一样。如果您这样做了,.NET 版本信息就设置好了。您可以使用 Reflection 或 ILSpy 等工具阅读该信息。

这样,Explorer 就不会在其属性页中显示任何版本信息。资源管理器仅显示 Win32 VersionInfo不是 .NET 版本信息。您需要使用 Rosyln 发出 Win32 资源代码来设置这些值。幸运的是,有一种方法可以从 .NET 中自动生成 Win32 信息:CreateDefaultWin32Resources .

这是一个完整且有效的代码示例:

public void VersionInfoExample()
{
    // 1. Generate AssemblyInfo.cs-like C# code and parse syntax tree
    StringBuilder asmInfo = new StringBuilder();

    asmInfo.AppendLine("using System.Reflection;");
    asmInfo.AppendLine("[assembly: AssemblyTitle(\"Test\")]");
    asmInfo.AppendLine("[assembly: AssemblyVersion(\"1.1.0\")]");
    asmInfo.AppendLine("[assembly: AssemblyFileVersion(\"1.1.0\")]");
    // Product Info
    asmInfo.AppendLine("[assembly: AssemblyProduct(\"Foo\")]");
    asmInfo.AppendLine("[assembly: AssemblyInformationalVersion(\"1.3.3.7\")]");

    var syntaxTree = CSharpSyntaxTree.ParseText(asmInfo.ToString(), encoding: Encoding.Default);

    // 2. Create compilation
    string mscorlibPath = typeof(object).Assembly.Location;
    MetadataReference mscorlib = MetadataReference.CreateFromFile(mscorlibPath, new MetadataReferenceProperties(MetadataImageKind.Assembly));
    CSharpCompilationOptions options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

    CSharpCompilation compilation = CSharpCompilation.Create("Test.dll",
                            references: new[] { mscorlib },
                            syntaxTrees: new[] { syntaxTree },
                            options: options);

    // 3. Emit code including win32 version info
    using (MemoryStream dllStream = new MemoryStream())
    using (MemoryStream pdbStream = new MemoryStream())
    using (Stream win32resStream = compilation.CreateDefaultWin32Resources(
                                                                versionResource: true, // Important!
                                                                noManifest: false,
                                                                manifestContents: null,
                                                                iconInIcoFormat: null))
    {
        EmitResult result = compilation.Emit(
                                     peStream: dllStream,
                                    pdbStream: pdbStream,
                                    win32Resources: win32resStream);

        System.IO.File.WriteAllBytes("Test.dll", dllStream.ToArray());
    }
}

关于c# - 使用 Roslyn 编译时如何设置程序集版本、文化和公钥 token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30989090/

相关文章:

c# - 在 C# 中使用证书的 M2MQtt 连接

c# - 线程池异常

c# - 代码合约运行时错误消息

c# - 删除自定义标记需要正则表达式

c++ - pthreads 编译但未创建二进制文件

c++ - 为什么带有 const 参数的函数声明允许调用带有非常量参数的函数?

c# - 使用抽象类型的反射从表中获取实体

c# - Paypal Ipn 与 asp.net MVC 集成

c# - 使用 Fluent 验证的 Model T 的通用验证器?

compilation - 什么是 RVA 和 VA?