コード例 #1
0
ファイル: LocBaml.cs プロジェクト: smellyriver/tankinspector
        /// <summary>
        /// Genereate localized baml
        /// </summary>
        private static void GenerateBamlResources(LocBamlOptions options)
        {
            Stream input = File.OpenRead(options.Translations);

            using (ResourceTextReader reader = new ResourceTextReader(options.TranslationFileType, input))
            {
                TranslationDictionariesReader dictionaries = new TranslationDictionariesReader(reader);
                ResourceGenerator.Generate(options, dictionaries);
            }
        }
コード例 #2
0
        public static string GenerateBamlResourcesFromStream(LocBamlOptions options, Stream stream)
        {
            string errors;

            using (ResourceTextReader reader = new ResourceTextReader(options.TranslationFileType, stream))
            {
                TranslationDictionariesReader dictionaries = new TranslationDictionariesReader(reader);
                errors = ResourceGenerator.Generate(options, dictionaries);
            }
            return(errors);
        }
コード例 #3
0
ファイル: locbaml.cs プロジェクト: cozzyy2002/WPF
 /// <summary>
 /// Genereate localized baml 
 /// </summary>        
 private static void GenerateBamlResources(LocBamlOptions options)
 {
     Stream input = File.OpenRead(options.Translations);
     using (ResourceTextReader reader = new ResourceTextReader(options.TranslationFileType, input))
     {
         TranslationDictionariesReader dictionaries = new TranslationDictionariesReader(reader);
         ResourceGenerator.Generate(options, dictionaries);
     }
 }
コード例 #4
0
        /// <summary>
        /// Generates localized Baml from translations
        /// </summary>
        /// <param name="options">LocBaml options</param>
        /// <param name="dictionaries">the translation dictionaries</param>
        internal static void Generate(LocBamlOptions options, TranslationDictionariesReader dictionaries)
        {
            // base on the input, we generate differently
            switch(options.InputType)
            {
                case FileType.BAML :
                {
                    // input file name
                    string bamlName = Path.GetFileName(options.Input);

                    // outpuf file name is Output dir + input file name
                    string outputFileName = GetOutputFileName(options);

                    // construct the full path
                    string fullPathOutput = Path.Combine(options.Output, outputFileName);

                    options.Write(StringLoader.Get("GenerateBaml", fullPathOutput));

                    using (Stream input = File.OpenRead(options.Input))
                    {
                        using (Stream output = new FileStream(fullPathOutput, FileMode.Create))
                        {
                            BamlLocalizationDictionary dictionary = dictionaries[bamlName];

                            // if it is null, just create an empty dictionary.
                            if (dictionary == null)
                                dictionary = new BamlLocalizationDictionary();

                            GenerateBamlStream(input, output, dictionary, options);
                        }
                    }

                    options.WriteLine(StringLoader.Get("Done"));
                    break;
                }
                case FileType.RESOURCES :
                {
                    string outputFileName = GetOutputFileName(options);
                    string fullPathOutput = Path.Combine(options.Output, outputFileName);

                    using (Stream input = File.OpenRead(options.Input))
                    {
                        using (Stream output = File.OpenWrite(fullPathOutput))
                        {
                            // create a Resource reader on the input;
                            IResourceReader reader = new ResourceReader(input);

                            // create a writer on the output;
                            IResourceWriter writer = new ResourceWriter(output);

                            GenerateResourceStream(
                                options,         // options
                                options.Input,   // resources name
                                reader,          // resource reader
                                writer,          // resource writer
                                dictionaries);   // translations

                            reader.Close();

                            // now generate and close
                            writer.Generate();
                            writer.Close();
                        }
                    }

                    options.WriteLine(StringLoader.Get("DoneGeneratingResource", outputFileName));
                    break;
                }
            case FileType.EXE:
                case FileType.DLL:
                {
                    GenerateAssembly(options, dictionaries);
                    break;
                }
                default:
                {
                    Debug.Assert(false, "Can't generate to this type");
                    break;
                }
            }
        }
コード例 #5
0
        private static void GenerateResourceStream(
                LocBamlOptions options,                     // options from the command line
                string resourceName,                        // the name of the .resources file
                IResourceReader reader,                     // the reader for the .resources
                IResourceWriter writer,                     // the writer for the output .resources
                TranslationDictionariesReader dictionaries  // the translations
            )
        {
            options.WriteLine(StringLoader.Get("GenerateResource", resourceName));
            // enumerate through each resource and generate it
            foreach(DictionaryEntry entry in reader)
            {
                string name = entry.Key as string;
                object resourceValue = null;

                // See if it looks like a Baml resource
                if (BamlStream.IsResourceEntryBamlStream(name, entry.Value))
                {
            Stream targetStream = null;
                    options.Write("    ");
                    options.Write(StringLoader.Get("GenerateBaml", name));

                    // grab the localizations available for this Baml
                    string bamlName = BamlStream.CombineBamlStreamName(resourceName, name);
                    BamlLocalizationDictionary localizations = dictionaries[bamlName];
                    if (localizations != null)
                    {
                        targetStream = new MemoryStream();

                        // generate into a new Baml stream
                        GenerateBamlStream(
                            (Stream) entry.Value,
                            targetStream,
                            localizations,
                            options
                        );
                    }
                    options.WriteLine(StringLoader.Get("Done"));

            // sets the generated object to be the generated baml stream
            resourceValue = targetStream;
                }

            if (resourceValue == null)
                {
                    //
                    // The stream is not localized as Baml yet, so we will make a copy of this item into
                    // the localized resources
                    //

            // We will add the value as is if it is serializable. Otherwise, make a copy
            resourceValue = entry.Value;

                    object[] serializableAttributes = resourceValue.GetType().GetCustomAttributes(typeof(SerializableAttribute), true);
                    if (serializableAttributes.Length == 0)
                    {
                        // The item returned from resource reader is not serializable
                        // If it is Stream, we can wrap all the values in a MemoryStream and
                        // add to the resource. Otherwise, we had to skip this resource.
            Stream resourceStream = resourceValue as Stream;
                        if (resourceStream != null)
                        {
                Stream targetStream = new MemoryStream();
                            byte[] buffer = new byte[resourceStream.Length];
                            resourceStream.Read(buffer, 0, buffer.Length);
                            targetStream = new MemoryStream(buffer);
                resourceValue = targetStream;
                        }
                    }
                }

            if (resourceValue != null)
                {
            writer.AddResource(name, resourceValue);
                }
            }
        }
コード例 #6
0
        //--------------------------------------------------
        // The function follows Managed code parser
        // implementation. in the future, maybe they should
        // share the same code
        //--------------------------------------------------
        private static void GenerateAssembly(LocBamlOptions options, TranslationDictionariesReader dictionaries)
        {
            // there are many names to be used when generating an assembly
            string sourceAssemblyFullName   = options.Input;                // source assembly full path
            string outputAssemblyDir        = options.Output;               // output assembly directory
            string outputAssemblyLocalName  = GetOutputFileName(options);   // output assembly name
            string moduleLocalName          = GetAssemblyModuleLocalName(options, outputAssemblyLocalName); // the module name within the assmbly

            // get the source assembly
            Assembly srcAsm = Assembly.LoadFrom(sourceAssemblyFullName);

            // obtain the assembly name
            AssemblyName targetAssemblyNameObj = srcAsm.GetName();

            // store the culture info of the source assembly
            CultureInfo srcCultureInfo  = targetAssemblyNameObj.CultureInfo;

            // update it to use it for target assembly
            targetAssemblyNameObj.Name        = Path.GetFileNameWithoutExtension(outputAssemblyLocalName);
            targetAssemblyNameObj.CultureInfo = options.CultureInfo;

            // we get a assembly builder
            AssemblyBuilder targetAssemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(
                targetAssemblyNameObj,                  // name of the assembly
                AssemblyBuilderAccess.RunAndSave,       // access rights
                outputAssemblyDir                       // storage dir
                );

            // we create a module builder for embeded resource modules
            ModuleBuilder moduleBuilder = targetAssemblyBuilder.DefineDynamicModule(
                moduleLocalName,
                outputAssemblyLocalName
                );

            options.WriteLine(StringLoader.Get("GenerateAssembly"));

            // now for each resource in the assembly
            foreach (string resourceName in srcAsm.GetManifestResourceNames())
            {
                // get the resource location for the resource
                ResourceLocation resourceLocation = srcAsm.GetManifestResourceInfo(resourceName).ResourceLocation;

                // if this resource is in another assemlby, we will skip it
                if ((resourceLocation & ResourceLocation.ContainedInAnotherAssembly) != 0)
                {
                    continue;   // in resource assembly, we don't have resource that is contained in another assembly
                }

                // gets the neutral resource name, giving it the source culture info
                string neutralResourceName  = GetNeutralResModuleName(resourceName, srcCultureInfo);

                // gets the target resource name, by giving it the target culture info
                string targetResourceName   = GetCultureSpecificResourceName(neutralResourceName, options.CultureInfo);

                // resource stream
                Stream resourceStream       = srcAsm.GetManifestResourceStream(resourceName);

                // see if it is a .resources
                if (neutralResourceName.ToLower(CultureInfo.InvariantCulture).EndsWith(".resources"))
                {
                    // now we think we have resource stream
                    // get the resource writer
                    IResourceWriter writer;
                    // check if it is a embeded assembly
                    if ((resourceLocation & ResourceLocation.Embedded) != 0)
                    {
                        // gets the resource writer from the module builder
                        writer = moduleBuilder.DefineResource(
                            targetResourceName,         // resource name
                            targetResourceName,         // resource description
                            ResourceAttributes.Public   // visibilty of this resource to other assembly
                            );
                    }
                    else
                    {
                        // it is a standalone resource, we get the resource writer from the assembly builder
                        writer =  targetAssemblyBuilder.DefineResource(
                            targetResourceName,         // resource name
                            targetResourceName,         // description
                            targetResourceName,         // file name to save to
                            ResourceAttributes.Public   // visibility of this resource to other assembly
                        );
                    }

                    // get the resource reader
                    IResourceReader reader = new ResourceReader(resourceStream);

                    // generate the resources
                    GenerateResourceStream(options, resourceName, reader, writer, dictionaries);

                    // we don't call writer.Generate() or writer.Close() here
                    // because the AssemblyBuilder will call them when we call Save() on it.
                }
                else
                {
                    // else it is a stand alone untyped manifest resources.
                    string extension = Path.GetExtension(targetResourceName);

                    string fullFileName = Path.Combine(outputAssemblyDir, targetResourceName);

                    // check if it is a .baml, case-insensitive
                    if (string.Compare(extension, ".baml", true, CultureInfo.InvariantCulture) == 0)
                    {
                        // try to localized the the baml
                        // find the resource dictionary
                        BamlLocalizationDictionary dictionary = dictionaries[resourceName];

                        // if it is null, just create an empty dictionary.
                        if (dictionary != null)
                        {
                            // it is a baml stream
                            using (Stream output = File.OpenWrite(fullFileName))
                            {
                                options.Write("    ");
                                options.WriteLine(StringLoader.Get("GenerateStandaloneBaml", fullFileName));
                                GenerateBamlStream(resourceStream, output, dictionary, options);
                                options.WriteLine(StringLoader.Get("Done"));
                            }
                        }
                        else
                        {
                            // can't find localization of it, just copy it
                            GenerateStandaloneResource( fullFileName, resourceStream);
                        }
                    }
                    else
                    {
                        // it is an untyped resource stream, just copy it
                        GenerateStandaloneResource( fullFileName, resourceStream);
                    }

                    // now add this resource file into the assembly
                    targetAssemblyBuilder.AddResourceFile(
                        targetResourceName,           // resource name
                        targetResourceName,           // file name
                        ResourceAttributes.Public     // visibility of the resource to other assembly
                    );

                }
            }

            // at the end, generate the assembly
            targetAssemblyBuilder.Save(outputAssemblyLocalName);
            options.WriteLine(StringLoader.Get("DoneGeneratingAssembly"));
        }
コード例 #7
0
        /// <summary>
        /// Generates localized Baml from translations
        /// </summary>
        /// <param name="options">LocBaml options</param>
        /// <param name="dictionaries">the translation dictionaries</param>
        internal static string Generate(LocBamlOptions options, TranslationDictionariesReader dictionaries)
        {
            // base on the input, we generate differently
            switch (options.InputType)
            {
            case FileType.BAML:
            {
                // input file name
                string bamlName = Path.GetFileName(options.Input);

                // output file name is output dir + input file name
                string outputFileName = GetOutputFileName(options);

                // construct the full path
                string fullPathOutput = Path.Combine(options.Output, outputFileName);

                options.Write(StringLoader.Get("GenerateBaml", fullPathOutput));

                using (Stream input = File.OpenRead(options.Input))
                {
                    using (Stream output = new FileStream(fullPathOutput, FileMode.Create))
                    {
                        BamlLocalizationDictionary dictionary = dictionaries[bamlName];

                        // if it is null, just create an empty dictionary.
                        if (dictionary == null)
                        {
                            dictionary = new BamlLocalizationDictionary();
                        }

                        string status = GenerateBamlStream(input, output, dictionary, options);
                        if (status != null)
                        {
                            return(status);
                        }
                    }
                }

                options.WriteLine(StringLoader.Get("Done"));
                break;
            }

            case FileType.RESOURCES:
            {
                string outputFileName = GetOutputFileName(options);
                string fullPathOutput = Path.Combine(options.Output, outputFileName);

                using (Stream input = File.OpenRead(options.Input))
                {
                    using (Stream output = File.OpenWrite(fullPathOutput))
                    {
                        // create a Resource reader on the input;
                        IResourceReader reader = new ResourceReader(input);

                        // create a writer on the output;
                        IResourceWriter writer = new ResourceWriter(output);

                        string status = GenerateResourceStream(
                            options,             // options
                            options.Input,       // resources name
                            reader,              // resource reader
                            writer,              // resource writer
                            dictionaries);       // translations

                        reader.Close();
                        if (status != null)
                        {
                            return(status);
                        }
                        // now generate and close
                        writer.Generate();
                        writer.Close();
                    }
                }

                options.WriteLine(StringLoader.Get("DoneGeneratingResource", outputFileName));
                break;
            }

            case FileType.EXE:
            case FileType.DLL:
            {
                string status = GenerateAssembly(options, dictionaries);
                if (status != null)
                {
                    return(status);
                }
                break;
            }

            default:
            {
                Debug.Assert(false, "Can't generate to this type");
                return("Can't generate to a resource of the type EXE");

                break;
            }
            }

            return(null);
        }
コード例 #8
0
        //--------------------------------------------------
        // The function follows Managed code parser
        // implementation. in the future, maybe they should
        // share the same code
        //--------------------------------------------------
        private static string GenerateAssembly(LocBamlOptions options, TranslationDictionariesReader dictionaries)
        {
            // there are many names to be used when generating an assembly
            string sourceAssemblyFullName  = options.Input;                                                // source assembly full path
            string outputAssemblyDir       = options.Output;                                               // output assembly directory
            string outputAssemblyLocalName = GetOutputFileName(options);                                   // output assembly name
            string moduleLocalName         = GetAssemblyModuleLocalName(options, outputAssemblyLocalName); // the module name within the assembly

            // get the source assembly
            Assembly srcAsm = Assembly.LoadFrom(sourceAssemblyFullName);

            // obtain the assembly name
            AssemblyName targetAssemblyNameObj = srcAsm.GetName();

            // store the culture info of the source assembly
            CultureInfo srcCultureInfo = targetAssemblyNameObj.CultureInfo;

            // update it to use it for target assembly
            targetAssemblyNameObj.Name        = Path.GetFileNameWithoutExtension(outputAssemblyLocalName);
            targetAssemblyNameObj.CultureInfo = options.CultureInfo;

            // we get a assembly builder
            AssemblyBuilder targetAssemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(
                targetAssemblyNameObj,                  // name of the assembly
                AssemblyBuilderAccess.RunAndSave,       // access rights
                outputAssemblyDir                       // storage dir
                );

            // we create a module builder for embedded resource modules
            ModuleBuilder moduleBuilder = targetAssemblyBuilder.DefineDynamicModule(
                moduleLocalName,
                outputAssemblyLocalName
                );

            options.WriteLine(StringLoader.Get("GenerateAssembly"));

            // now for each resource in the assembly
            foreach (string resourceName in srcAsm.GetManifestResourceNames())
            {
                // get the resource location for the resource
                ResourceLocation resourceLocation = srcAsm.GetManifestResourceInfo(resourceName).ResourceLocation;

                // if this resource is in another assembly, we will skip it
                if ((resourceLocation & ResourceLocation.ContainedInAnotherAssembly) != 0)
                {
                    continue;   // in resource assembly, we don't have resource that is contained in another assembly
                }

                // gets the neutral resource name, giving it the source culture info
                string neutralResourceName = GetNeutralResModuleName(resourceName, srcCultureInfo);

                // gets the target resource name, by giving it the target culture info
                string targetResourceName = GetCultureSpecificResourceName(neutralResourceName, options.CultureInfo);

                // resource stream
                Stream resourceStream = srcAsm.GetManifestResourceStream(resourceName);

                // see if it is a .resources
                if (neutralResourceName.ToLower(CultureInfo.InvariantCulture).EndsWith(".resources"))
                {
                    // now we think we have resource stream
                    // get the resource writer
                    IResourceWriter writer;
                    // check if it is a embedded assembly
                    if ((resourceLocation & ResourceLocation.Embedded) != 0)
                    {
                        // gets the resource writer from the module builder
                        writer = moduleBuilder.DefineResource(
                            targetResourceName,         // resource name
                            targetResourceName,         // resource description
                            ResourceAttributes.Public   // visibility of this resource to other assembly
                            );
                    }
                    else
                    {
                        // it is a standalone resource, we get the resource writer from the assembly builder
                        writer = targetAssemblyBuilder.DefineResource(
                            targetResourceName,         // resource name
                            targetResourceName,         // description
                            targetResourceName,         // file name to save to
                            ResourceAttributes.Public   // visibility of this resource to other assembly
                            );
                    }

                    // get the resource reader
                    IResourceReader reader = new ResourceReader(resourceStream);

                    // generate the resources
                    string status = GenerateResourceStream(options, resourceName, reader, writer, dictionaries);
                    if (status != null)
                    {
                        return(status);
                    }

                    // we don't call writer.Generate() or writer.Close() here
                    // because the AssemblyBuilder will call them when we call Save() on it.
                }
                else
                {
                    // else it is a stand alone untyped manifest resources.
                    string extension = Path.GetExtension(targetResourceName);

                    string fullFileName = Path.Combine(outputAssemblyDir, targetResourceName);

                    // check if it is a .baml, case-insensitive
                    if (string.Compare(extension, ".baml", true, CultureInfo.InvariantCulture) == 0)
                    {
                        // try to localized the baml
                        // find the resource dictionary
                        BamlLocalizationDictionary dictionary = dictionaries[resourceName];

                        // if it is null, just create an empty dictionary.
                        if (dictionary != null)
                        {
                            // it is a baml stream
                            using (Stream output = File.OpenWrite(fullFileName))
                            {
                                options.Write("    ");
                                options.WriteLine(StringLoader.Get("GenerateStandaloneBaml", fullFileName));
                                GenerateBamlStream(resourceStream, output, dictionary, options);
                                options.WriteLine(StringLoader.Get("Done"));
                            }
                        }
                        else
                        {
                            // can't find localization of it, just copy it
                            GenerateStandaloneResource(fullFileName, resourceStream);
                        }
                    }
                    else
                    {
                        // it is an untyped resource stream, just copy it
                        GenerateStandaloneResource(fullFileName, resourceStream);
                    }

                    // now add this resource file into the assembly
                    targetAssemblyBuilder.AddResourceFile(
                        targetResourceName,           // resource name
                        targetResourceName,           // file name
                        ResourceAttributes.Public     // visibility of the resource to other assembly
                        );
                }
            }

            // at the end, generate the assembly
            targetAssemblyBuilder.Save(outputAssemblyLocalName);
            options.WriteLine(StringLoader.Get("DoneGeneratingAssembly"));
            return(null);
        }
コード例 #9
0
        private static string GenerateResourceStream(
            LocBamlOptions options,                         // options from the command line
            string resourceName,                            // the name of the .resources file
            IResourceReader reader,                         // the reader for the .resources
            IResourceWriter writer,                         // the writer for the output .resources
            TranslationDictionariesReader dictionaries      // the translations
            )
        {
            options.WriteLine(StringLoader.Get("GenerateResource", resourceName));
            // enumerate through each resource and generate it
            foreach (DictionaryEntry entry in reader)
            {
                string name          = entry.Key as string;
                object resourceValue = null;

                // See if it looks like a Baml resource
                if (BamlStream.IsResourceEntryBamlStream(name, entry.Value))
                {
                    Stream targetStream = null;
                    options.Write("    ");
                    options.Write(StringLoader.Get("GenerateBaml", name));

                    // grab the localizations available for this Baml
                    string bamlName = BamlStream.CombineBamlStreamName(resourceName, name);
                    BamlLocalizationDictionary localizations = dictionaries[bamlName];
                    if (localizations != null)
                    {
                        targetStream = new MemoryStream();

                        // generate into a new Baml stream
                        string status = GenerateBamlStream(
                            (Stream)entry.Value,
                            targetStream,
                            localizations,
                            options
                            );
                        if (status != null)
                        {
                            options.WriteLine(status);
                            return(status);
                        }
                    }

                    options.WriteLine(StringLoader.Get("Done"));

                    // sets the generated object to be the generated baml stream
                    resourceValue = targetStream;
                }

                if (resourceValue == null)
                {
                    //
                    // The stream is not localized as Baml yet, so we will make a copy of this item into
                    // the localized resources
                    //

                    // We will add the value as is if it is serializable. Otherwise, make a copy
                    resourceValue = entry.Value;

                    object[] serializableAttributes = resourceValue.GetType().GetCustomAttributes(typeof(SerializableAttribute), true);
                    if (serializableAttributes.Length == 0)
                    {
                        // The item returned from resource reader is not serializable
                        // If it is Stream, we can wrap all the values in a MemoryStream and
                        // add to the resource. Otherwise, we had to skip this resource.
                        Stream resourceStream = resourceValue as Stream;
                        if (resourceStream != null)
                        {
                            Stream targetStream = new MemoryStream();
                            byte[] buffer       = new byte[resourceStream.Length];
                            resourceStream.Read(buffer, 0, buffer.Length);
                            targetStream  = new MemoryStream(buffer);
                            resourceValue = targetStream;
                        }
                    }
                }

                if (resourceValue != null)
                {
                    writer.AddResource(name, resourceValue);
                }
            }

            return(null);
        }
コード例 #10
0
        public override bool Execute()
        {
            _Options             = new LocBamlOptions();
            _Options.CultureInfo = new CultureInfo(Culture);

            // generation-related options
            _Options.ToGenerate   = true;
            _Options.Translations = TranslationsFile;
            _Options.Input        = InputFile;
            _Options.Output       = OutputFolder;

            // TBD: Should we do this automatically or not?
            if (!System.IO.Directory.Exists(OutputFolder))
            {
                System.IO.Directory.CreateDirectory(OutputFolder);
            }

            _Options.ToParse = false;

            // Just to get rid of compiler warnings
            _Options.HasNoLogo = true;

            // TODO:
            if ((Assemblies == null) || (Assemblies.Length == 0))
            {
                _Options.AssemblyPaths = null;
            }
            else
            {
                _Options.AssemblyPaths = new System.Collections.ArrayList();
                _Options.AssemblyPaths.AddRange(Assemblies);
            }

            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

            // TODO: Add a logger interface so we can use MSBuild logger from
            // LocBamlOptions.Write() and WriteLine()
            _Options.IsVerbose = true;

            bool success = true;

            string errorString = _Options.CheckAndSetDefault();

            if (errorString != null)
            {
                Log.LogError(errorString);
                success = false;
            }
            else
            {
                try
                {
                    TranslationDictionariesReader dictionaries = _Options.GetTranslationsDictionary();
                    ResourceGenerator.Generate(_Options, dictionaries);
                }
                catch (Exception e)
                {
                    Log.LogError("Exception generating: {0}", e.Message);
                    success = false;
                }
                Log.LogMessage("Done with LocBamlGenerate");
            }
            AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
            return(success);
        }
コード例 #11
0
        /// <summary>
        /// Genereate localized baml
        /// </summary>
        private static void GenerateBamlResources(LocBamlOptions options)
        {
            TranslationDictionariesReader dictionaries = options.GetTranslationsDictionary();

            ResourceGenerator.Generate(options, dictionaries);
        }
コード例 #12
0
ファイル: LocBamlTranslate.cs プロジェクト: eaglemc/locbaml
        public override bool Execute()
        {
            // First stage: parse
            _Options             = new LocBamlOptions();
            _Options.ToParse     = true;
            _Options.Input       = InputFile;
            _Options.Output      = TranslationsFile;
            _Options.CultureInfo = new CultureInfo(Culture);

            // Just to get rid of compiler warnings
            _Options.HasNoLogo = true;
            // generation-related options
            _Options.ToGenerate   = false;
            _Options.Translations = string.Empty;

            // TODO:
            if ((Assemblies == null) || (Assemblies.Length == 0))
            {
                _Options.AssemblyPaths = null;
            }
            else
            {
                _Options.AssemblyPaths = new System.Collections.ArrayList();
                _Options.AssemblyPaths.AddRange(Assemblies);
            }

            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

            // TODO: Add a logger interface so we can use MSBuild logger from
            // LocBamlOptions.Write() and WriteLine()
            _Options.IsVerbose = true;

            bool success = true;

            string errorString = _Options.CheckAndSetDefault();

            if (errorString != null)
            {
                Log.LogError(errorString);
                AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
                success = false;
            }
            else
            {
                try
                {
                    TranslationDictionariesWriter.Write(_Options);
                }
                catch (Exception e)
                {
                    Log.LogError("Exception parsing: {0}", e.Message);
                    success = false;
                }
            }

            // TBD: a way to override automatic algorithm?
            string outputFolder = Path.GetDirectoryName(Path.GetFullPath(InputFile));

            string[] folderParts = outputFolder.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
            // Try to figure out if the ouptut folder is a culture name, if so remove it
            foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
            {
                string cName = culture.Name;
                if (string.IsNullOrEmpty(cName))
                {
                    continue;
                }
                if (folderParts[folderParts.Length - 1].Equals(cName, StringComparison.InvariantCultureIgnoreCase))
                {
                    outputFolder = string.Join(Path.DirectorySeparatorChar.ToString(), folderParts, 0, folderParts.Length - 1);
                    outputFolder = Path.Combine(outputFolder, _Options.CultureInfo.Name);
                    break;
                }
            }

            if (success)
            {
                // Don't call _Options.CheckAndSetDefault() again because it will reload the assemblies
                // generation-related options
                _Options.ToGenerate   = true;
                _Options.Translations = TranslationsFile;
                _Options.Input        = InputFile;
                _Options.Output       = outputFolder;

                // TBD: Should we do this automatically or not?
                if (!Directory.Exists(outputFolder))
                {
                    Directory.CreateDirectory(outputFolder);
                }

                _Options.ToParse = false;

                try
                {
                    TranslationDictionariesReader dictionaries = _Options.GetTranslationsDictionary();
                    ResourceGenerator.Generate(_Options, dictionaries);
                }
                catch (Exception e)
                {
                    Log.LogError("Exception generating: {0}", e.Message);
                    success = false;
                }
            }

            // Cleanup
            AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;

            return(success);
        }
コード例 #13
0
ファイル: ResourceGenerator.cs プロジェクト: eaglemc/locbaml
        //--------------------------------------------------
        // The function follows Managed code parser
        // implementation. in the future, maybe they should
        // share the same code
        //--------------------------------------------------
        private static void GenerateAssembly(LocBamlOptions options, TranslationDictionariesReader dictionaries)
        {
            // there are many names to be used when generating an assembly
            string sourceAssemblyFullName  = options.Input;                                                // source assembly full path
            string outputAssemblyDir       = options.Output;                                               // output assembly directory
            string outputAssemblyLocalName = GetOutputFileName(options);                                   // output assembly name
            string moduleLocalName         = GetAssemblyModuleLocalName(options, outputAssemblyLocalName); // the module name within the assmbly

            // get the source assembly
            byte[]   sourceContents = File.ReadAllBytes(sourceAssemblyFullName);
            Assembly srcAsm         = Assembly.Load(sourceContents);

            // obtain the assembly name
            AssemblyName targetAssemblyNameObj = srcAsm.GetName();

            // store the culture info of the source assembly
            CultureInfo srcCultureInfo = targetAssemblyNameObj.CultureInfo;

            // update it to use it for target assembly
            targetAssemblyNameObj.Name        = Path.GetFileNameWithoutExtension(outputAssemblyLocalName);
            targetAssemblyNameObj.CultureInfo = options.CultureInfo;

            // we get a assembly builder
            AssemblyBuilder targetAssemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(
                targetAssemblyNameObj,                  // name of the assembly
                AssemblyBuilderAccess.RunAndSave,       // access rights
                outputAssemblyDir                       // storage dir
                );

            // we create a module builder for embeded resource modules
            ModuleBuilder moduleBuilder = targetAssemblyBuilder.DefineDynamicModule(
                moduleLocalName,
                outputAssemblyLocalName
                );

            Dictionary <string, IResourceWriter> resourceWriters = new Dictionary <string, IResourceWriter>();

            // If the output assembly already exists, copy the embedded resources to the new assembly
            string existingAssemblyName = Path.Combine(Directory.GetCurrentDirectory(), options.CultureInfo.Name, outputAssemblyLocalName);

            if (File.Exists(existingAssemblyName))
            {
                // Use ReadAllBytes() so we don't hold a file handle open, which would prevent
                // us from overwriting the file at the end.
                Assembly existingAssembly      = Assembly.Load(File.ReadAllBytes(existingAssemblyName));
                string[] existingResourceNames = existingAssembly.GetManifestResourceNames();
                foreach (string resourceName in existingResourceNames)
                {
                    ManifestResourceInfo info = existingAssembly.GetManifestResourceInfo(resourceName);
                    if ((info.ResourceLocation & ResourceLocation.Embedded) != ResourceLocation.Embedded)
                    {
                        continue;
                    }
                    IResourceWriter writer;
                    if (!resourceWriters.TryGetValue(resourceName, out writer))
                    {
                        writer = moduleBuilder.DefineResource(
                            resourceName,             // resource name
                            resourceName,             // resource description
                            ResourceAttributes.Public // visibilty of this resource to other assembly
                            );
                        resourceWriters.Add(resourceName, writer);
                    }
                    Stream resourceStream = existingAssembly.GetManifestResourceStream(resourceName);
                    using (ResourceReader reader = new ResourceReader(resourceStream))
                    {
                        foreach (DictionaryEntry entry in reader)
                        {
                            string key   = entry.Key.ToString();
                            object value = entry.Value;
                            if (key.EndsWith(".baml"))
                            {
                                // Skip it, we're going to get this from the untranslated assembly
                                continue;
                            }
                            writer.AddResource(key, value);
                        }
                    }
                }
            }

            // Add assembly info, trying to preserver original values as close as possible
            CopyAssemblyVersion(targetAssemblyBuilder, srcAsm);

            options.WriteLine(StringLoader.Get("GenerateAssembly"));

            // now for each resource in the assembly
            foreach (string resourceName in srcAsm.GetManifestResourceNames())
            {
                // get the resource location for the resource
                ResourceLocation resourceLocation = srcAsm.GetManifestResourceInfo(resourceName).ResourceLocation;

                // if this resource is in another assemlby, we will skip it
                if ((resourceLocation & ResourceLocation.ContainedInAnotherAssembly) != 0)
                {
                    continue;   // in resource assembly, we don't have resource that is contained in another assembly
                }

                // gets the neutral resource name, giving it the source culture info
                string neutralResourceName = GetNeutralResModuleName(resourceName, srcCultureInfo);

                // gets the target resource name, by giving it the target culture info
                string targetResourceName = GetCultureSpecificResourceName(neutralResourceName, options.CultureInfo);

                // resource stream
                Stream resourceStream = srcAsm.GetManifestResourceStream(resourceName);

                // see if it is a .resources
                if (neutralResourceName.ToLower(CultureInfo.InvariantCulture).EndsWith(".resources"))
                {
                    // now we think we have resource stream
                    // get the resource writer
                    IResourceWriter writer;
                    // check if it is a embeded assembly
                    if (!resourceWriters.TryGetValue(targetResourceName, out writer))
                    {
                        if ((resourceLocation & ResourceLocation.Embedded) != 0)
                        {
                            // gets the resource writer from the module builder
                            writer = moduleBuilder.DefineResource(
                                targetResourceName,         // resource name
                                targetResourceName,         // resource description
                                ResourceAttributes.Public   // visibilty of this resource to other assembly
                                );
                        }
                        else
                        {
                            // it is a standalone resource, we get the resource writer from the assembly builder
                            writer = targetAssemblyBuilder.DefineResource(
                                targetResourceName,         // resource name
                                targetResourceName,         // description
                                targetResourceName,         // file name to save to
                                ResourceAttributes.Public   // visibility of this resource to other assembly
                                );
                        }
                        resourceWriters.Add(targetResourceName, writer);
                    }

                    // get the resource reader
                    IResourceReader reader = new ResourceReader(resourceStream);

                    // generate the resources
                    GenerateResourceStream(options, resourceName, reader, writer, dictionaries);

                    // we don't call writer.Generate() or writer.Close() here
                    // because the AssemblyBuilder will call them when we call Save() on it.
                }
                else
                {
                    // else it is a stand alone untyped manifest resources.
                    string extension = Path.GetExtension(targetResourceName);

                    string fullFileName = Path.Combine(outputAssemblyDir, targetResourceName);

                    // check if it is a .baml, case-insensitive
                    if (string.Compare(extension, ".baml", true, CultureInfo.InvariantCulture) == 0)
                    {
                        // try to localized the the baml
                        // find the resource dictionary
                        BamlLocalizationDictionary dictionary = dictionaries[resourceName];

                        // if it is null, just create an empty dictionary.
                        if (dictionary != null)
                        {
                            // it is a baml stream
                            using (Stream output = File.OpenWrite(fullFileName))
                            {
                                options.Write("    ");
                                options.WriteLine(StringLoader.Get("GenerateStandaloneBaml", fullFileName));
                                GenerateBamlStream(resourceStream, output, dictionary, options);
                                options.WriteLine(StringLoader.Get("Done"));
                            }
                        }
                        else
                        {
                            // can't find localization of it, just copy it
                            GenerateStandaloneResource(fullFileName, resourceStream);
                        }
                    }
                    else
                    {
                        // it is an untyped resource stream, just copy it
                        GenerateStandaloneResource(fullFileName, resourceStream);
                    }

                    // now add this resource file into the assembly
                    targetAssemblyBuilder.AddResourceFile(
                        targetResourceName,           // resource name
                        targetResourceName,           // file name
                        ResourceAttributes.Public     // visibility of the resource to other assembly
                        );
                }
            }

            // at the end, generate the assembly
            targetAssemblyBuilder.Save(outputAssemblyLocalName);
            options.WriteLine(StringLoader.Get("DoneGeneratingAssembly"));
        }
コード例 #14
0
ファイル: ResourceGenerator.cs プロジェクト: f00f/locbaml
        //--------------------------------------------------
        // The function follows Managed code parser
        // implementation. in the future, maybe they should
        // share the same code
        //--------------------------------------------------
        private static void GenerateAssembly(LocBamlOptions options, TranslationDictionariesReader dictionaries)
        {
            // there are many names to be used when generating an assembly
            string sourceAssemblyFullName  = options.Input;                                                // source assembly full path
            string outputAssemblyDir       = options.Output;                                               // output assembly directory
            string outputAssemblyLocalName = GetOutputFileName(options);                                   // output assembly name
            string moduleLocalName         = GetAssemblyModuleLocalName(options, outputAssemblyLocalName); // the module name within the assmbly

            // get the source assembly
            Assembly srcAsm = Assembly.LoadFrom(sourceAssemblyFullName);

            // obtain the assembly name
            AssemblyName targetAssemblyNameObj = srcAsm.GetName();

            // store the culture info of the source assembly
            CultureInfo srcCultureInfo = targetAssemblyNameObj.CultureInfo;

            // update it to use it for target assembly
            targetAssemblyNameObj.Name        = Path.GetFileNameWithoutExtension(outputAssemblyLocalName);
            targetAssemblyNameObj.CultureInfo = options.CultureInfo;

            // we get a assembly builder
            AssemblyBuilder targetAssemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(
                targetAssemblyNameObj,                  // name of the assembly
                AssemblyBuilderAccess.RunAndSave,       // access rights
                outputAssemblyDir                       // storage dir
                );

            // Add assembly info, trying to preserver original values as close as possible
            Action <Type, string> AddCustomStringAttribute = (Type type, string content) =>
            {
                if (string.IsNullOrEmpty(content))
                {
                    return;
                }
                ConstructorInfo ctor = type.GetConstructor(new Type[] { typeof(string) });
                targetAssemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(ctor, new object[] { content }));
            };
            bool hasInformationalVersionAttr = false;

            object[] attrs = srcAsm.GetCustomAttributes(false);
            foreach (var attr in attrs)
            {
                if (attr is AssemblyCompanyAttribute cmp)
                {
                    AddCustomStringAttribute(attr.GetType(), cmp.Company); continue;
                }
                if (attr is AssemblyCopyrightAttribute copy)
                {
                    AddCustomStringAttribute(attr.GetType(), copy.Copyright); continue;
                }
                if (attr is AssemblyDescriptionAttribute da)
                {
                    AddCustomStringAttribute(attr.GetType(), da.Description); continue;
                }
                if (attr is AssemblyFileVersionAttribute fva)
                {
                    AddCustomStringAttribute(attr.GetType(), fva.Version);
                    if (!hasInformationalVersionAttr)
                    {
                        // Also set AssemblyInformationalVersionAttribute, if not set already.
                        // The unmanaged ProductVersion is taken from that attribute.
                        AddCustomStringAttribute(typeof(AssemblyInformationalVersionAttribute), fva.Version);
                    }
                    continue;
                }
                if (attr is AssemblyInformationalVersionAttribute iva)
                {
                    AddCustomStringAttribute(attr.GetType(), iva.InformationalVersion);
                    hasInformationalVersionAttr = true;
                    continue;
                }
                if (attr is AssemblyProductAttribute pa)
                {
                    AddCustomStringAttribute(attr.GetType(), pa.Product); continue;
                }
                if (attr is AssemblyTitleAttribute ta)
                {
                    AddCustomStringAttribute(attr.GetType(), ta.Title); continue;
                }
                if (attr is AssemblyTrademarkAttribute tm)
                {
                    AddCustomStringAttribute(attr.GetType(), tm.Trademark); continue;
                }
                if (attr is AssemblyVersionAttribute va)
                {
                    AddCustomStringAttribute(attr.GetType(), va.Version); continue;
                }
            }
            targetAssemblyBuilder.DefineVersionInfoResource();

            // we create a module builder for embeded resource modules
            ModuleBuilder moduleBuilder = targetAssemblyBuilder.DefineDynamicModule(
                moduleLocalName,
                outputAssemblyLocalName
                );

            options.WriteLine(StringLoader.Get("GenerateAssembly"));

            // now for each resource in the assembly
            foreach (string resourceName in srcAsm.GetManifestResourceNames())
            {
                // get the resource location for the resource
                ResourceLocation resourceLocation = srcAsm.GetManifestResourceInfo(resourceName).ResourceLocation;

                // if this resource is in another assemlby, we will skip it
                if ((resourceLocation & ResourceLocation.ContainedInAnotherAssembly) != 0)
                {
                    continue;   // in resource assembly, we don't have resource that is contained in another assembly
                }

                // gets the neutral resource name, giving it the source culture info
                string neutralResourceName = GetNeutralResModuleName(resourceName, srcCultureInfo);

                // gets the target resource name, by giving it the target culture info
                string targetResourceName = GetCultureSpecificResourceName(neutralResourceName, options.CultureInfo);

                // resource stream
                Stream resourceStream = srcAsm.GetManifestResourceStream(resourceName);

                // see if it is a .resources
                if (neutralResourceName.ToLower(CultureInfo.InvariantCulture).EndsWith(".resources"))
                {
                    // now we think we have resource stream
                    // get the resource writer
                    IResourceWriter writer;
                    // check if it is a embeded assembly
                    if ((resourceLocation & ResourceLocation.Embedded) != 0)
                    {
                        // gets the resource writer from the module builder
                        writer = moduleBuilder.DefineResource(
                            targetResourceName,         // resource name
                            targetResourceName,         // resource description
                            ResourceAttributes.Public   // visibilty of this resource to other assembly
                            );
                    }
                    else
                    {
                        // it is a standalone resource, we get the resource writer from the assembly builder
                        writer = targetAssemblyBuilder.DefineResource(
                            targetResourceName,         // resource name
                            targetResourceName,         // description
                            targetResourceName,         // file name to save to
                            ResourceAttributes.Public   // visibility of this resource to other assembly
                            );
                    }

                    // get the resource reader
                    IResourceReader reader = new ResourceReader(resourceStream);

                    // generate the resources
                    GenerateResourceStream(options, resourceName, reader, writer, dictionaries);

                    // we don't call writer.Generate() or writer.Close() here
                    // because the AssemblyBuilder will call them when we call Save() on it.
                }
                else
                {
                    // else it is a stand alone untyped manifest resources.
                    string extension = Path.GetExtension(targetResourceName);

                    string fullFileName = Path.Combine(outputAssemblyDir, targetResourceName);

                    // check if it is a .baml, case-insensitive
                    if (string.Compare(extension, ".baml", true, CultureInfo.InvariantCulture) == 0)
                    {
                        // try to localized the the baml
                        // find the resource dictionary
                        BamlLocalizationDictionary dictionary = dictionaries[resourceName];

                        // if it is null, just create an empty dictionary.
                        if (dictionary != null)
                        {
                            // it is a baml stream
                            using (Stream output = File.OpenWrite(fullFileName))
                            {
                                options.Write("    ");
                                options.WriteLine(StringLoader.Get("GenerateStandaloneBaml", fullFileName));
                                GenerateBamlStream(resourceStream, output, dictionary, options);
                                options.WriteLine(StringLoader.Get("Done"));
                            }
                        }
                        else
                        {
                            // can't find localization of it, just copy it
                            GenerateStandaloneResource(fullFileName, resourceStream);
                        }
                    }
                    else
                    {
                        // it is an untyped resource stream, just copy it
                        GenerateStandaloneResource(fullFileName, resourceStream);
                    }

                    // now add this resource file into the assembly
                    targetAssemblyBuilder.AddResourceFile(
                        targetResourceName,           // resource name
                        targetResourceName,           // file name
                        ResourceAttributes.Public     // visibility of the resource to other assembly
                        );
                }
            }

            // at the end, generate the assembly
            targetAssemblyBuilder.Save(outputAssemblyLocalName);
            options.WriteLine(StringLoader.Get("DoneGeneratingAssembly"));
        }