How to set assembly version, culture and public key token while compiling with Roslyn?

4.8k views Asked by At

I'm using Roslyn to emit a CSharpCompilation object in Visual Studio to a file. The DLL that is generated does not contain any assembly info other than the assembly metadata, and I'd like to add the version and sign it if possible. How can these be done with Roslyn?

1

There are 1 answers

3
MBulli On

You need to include source code which sets the Assembly* attributes just like in the VS C# project templates. If you have done that, the .NET version info is set. You can read that information with Reflection or tools like ILSpy.

That way Explorer won't show any version info in its property page. Explorer is only showing Win32 VersionInfo not .NET version info. You need to emit Win32 resource code with Rosyln to set these values. Luckily there's a method to auto generate the Win32 info from the .NET ones: CreateDefaultWin32Resources.

Here's a complete and working code sample:

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());
    }
}