2

I'm about to elaborate a solution for simplifying a translator tool. Therefore I currently try to automatically compile a Satellite Assembly from within my code.

So what I want to achive is to replace a manual run of the following command:

AL.exe /culture:de /out:de\TestResource.resources.dll /embed:TestResource.de.resources

So far I've tested generating a .dll file, which worked. But embedding/linking an ressource like shown below doesn't has any effect, but expanding the dll's size. So obviously it's there but not usable as if the resulting dll was a Satellite Assembly.

    static void Main(string[] args)
    {
        CSharpCodeProvider codeProvider = new CSharpCodeProvider();
        CompilerParameters parameters = new CompilerParameters();

        parameters.GenerateExecutable = false;
        parameters.OutputAssembly = "./output/satellite_test.dll";
        parameters.EmbeddedResources.Add(@"./TestResource.en.resources");
        parameters.LinkedResources.Add(@"./TestResource.de.resources");

        CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, "");
    }

Is there any way to generate a dll programmatically which contains just the localized resources for one language, so that it's usable as a Satellite Assembly?

infotoni91
  • 722
  • 3
  • 13

1 Answers1

4

Finally I've managed to generate Satellite Assemblies from Code.

Following code generates an appropriate resourcefile:

// Already the resourcefilename has to match the 
// exact namespacepath of the original resourcename.
var resourcefileName = @"TranslationTest.Resources.TestResource.de.resources";

// File has to be a .resource file. (ResourceWriter instead of ResXResourceWriter)
// .resx not working and has to be converted into .resource file.
using (var resourceWriter = new ResourceWriter(resourcefileName))
{
    resourceWriter.AddResource("testtext", "Language is german!!");
}

Using this resourcefile there are some compileroptions which are necessary:

CompilerParameters parameters = new CompilerParameters();

// Newly created assembly has to be a dll.
parameters.GenerateExecutable = false;

// Filename has to be like the original resourcename. Renaming afterwards does not work.
parameters.OutputAssembly = "./de/TranslationTest.resources.dll";

// Resourcefile has to be embedded in the new assembly.
parameters.EmbeddedResources.Add(resourcefileName);

Finally compiling the assembly there is some required code which has to be compiled into:

// Culture information has to be part of the newly created assembly.
var assemblyAttributesAsCode = @"
    using System.Reflection; 
    [assembly: AssemblyCulture(""de"")]";

CSharpCodeProvider codeProvider = new CSharpCodeProvider();
CompilerResults results = codeProvider.CompileAssemblyFromSource(
    parameters, 
    assemblyAttributesAsCode
);
infotoni91
  • 722
  • 3
  • 13
  • I believe that the documentation also recommends making sure the target is library. So adding this line could be useful `parameters.CompilerOptions = "-target:library";` – Matt Bart Jan 26 '21 at 15:09
  • For me at least the DLL was empty (seemed to be okay, but empty in contents) until I starting using an **absolute path** for the resourceFilename – Matt Bart Jan 26 '21 at 15:11