如何在使用Roslyn编译时设置程序集版本、区域性和公钥令牌



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

您需要包含设置Assembly*属性的源代码,就像在VSC#项目模板中一样。如果您已经完成了此操作,则会设置.NET版本信息。您可以使用反射或ILSpy等工具读取这些信息。

这样,资源管理器就不会在其属性页中显示任何版本信息。资源管理器只显示Win32版本信息,而不显示.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());
    }
}

最新更新