Created
May 3, 2011 06:03
-
-
Save nikhilk/952879 to your computer and use it in GitHub Desktop.
Single file generator sample/snippet from script# code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // This isn't all the code, but hopefully enough to get you started... | |
| // ResxScriptGenerator.cs | |
| using System; | |
| using System.Diagnostics; | |
| using System.IO; | |
| using System.Reflection; | |
| using System.Runtime.InteropServices; | |
| using System.Text; | |
| namespace ScriptSharp.ResourceModel { | |
| public abstract class ResXScriptGenerator : Interop.IObjectWithSite, Interop.IVsSingleFileGenerator { | |
| private object _site; | |
| private bool _publicResources; | |
| protected ResXScriptGenerator(bool publicResources) { | |
| _publicResources = publicResources; | |
| } | |
| public string GenerateCode(string resourceFileName, string resourceFileContent, string namespaceName) { | |
| if (IsLocalizedResourceFile(resourceFileName)) { | |
| return null; | |
| } | |
| ResourceModelBuilder resourceModelBuilder = new ResourceModelBuilder(); | |
| ResourceItemList resourceItems = resourceModelBuilder.BuildResourceItemList(resourceFileContent); | |
| string className = Path.GetFileNameWithoutExtension(resourceFileName); | |
| StringBuilder codeBuilder = new StringBuilder(2048); | |
| codeBuilder.AppendLine("//------------------------------------------------------------------------------"); | |
| codeBuilder.AppendLine("// <auto-generated>"); | |
| codeBuilder.Append("// "); | |
| codeBuilder.Append(className); | |
| codeBuilder.AppendLine(".cs"); | |
| codeBuilder.AppendLine("//"); | |
| codeBuilder.Append("// Do not edit directly. This file has been generated by "); | |
| codeBuilder.Append(GetGeneratorName()); | |
| codeBuilder.AppendLine("."); | |
| codeBuilder.AppendLine("// </auto-generated>"); | |
| codeBuilder.AppendLine("//------------------------------------------------------------------------------"); | |
| codeBuilder.AppendLine(); | |
| codeBuilder.AppendLine("using System;"); | |
| codeBuilder.AppendLine("using System.CodeDom.Compiler;"); | |
| codeBuilder.AppendLine("using System.Runtime.CompilerServices;"); | |
| codeBuilder.AppendLine(); | |
| codeBuilder.Append("namespace "); | |
| codeBuilder.Append(namespaceName); | |
| codeBuilder.AppendLine(" {"); | |
| codeBuilder.AppendLine(); | |
| codeBuilder.Append(" /// <summary>"); | |
| codeBuilder.Append(className); | |
| codeBuilder.AppendLine(" resources class</summary>"); | |
| codeBuilder.Append(" [GeneratedCodeAttribute(\""); | |
| codeBuilder.Append(this.GetType().Name); | |
| codeBuilder.Append("\", \""); | |
| codeBuilder.Append(typeof(ResXScriptGenerator).Assembly.GetName().Version.ToString()); | |
| codeBuilder.AppendLine("\")]"); | |
| codeBuilder.AppendLine(" [Resources]"); | |
| codeBuilder.Append(_publicResources ? " public" : " internal"); | |
| codeBuilder.Append(" static class "); | |
| codeBuilder.Append(className); | |
| codeBuilder.AppendLine(" {"); | |
| foreach (ResourceItem resourceItem in resourceItems.Items) { | |
| codeBuilder.AppendLine(); | |
| if (resourceItem.Comment.Length != 0) { | |
| codeBuilder.Append(" /// <summary>"); | |
| codeBuilder.Append(resourceItem.Comment); | |
| codeBuilder.AppendLine("</summary>"); | |
| } | |
| codeBuilder.Append(" public static readonly string "); | |
| codeBuilder.Append(resourceItem.Name); | |
| codeBuilder.AppendLine(" = null;"); | |
| } | |
| codeBuilder.AppendLine(" }"); | |
| codeBuilder.AppendLine("}"); | |
| return codeBuilder.ToString(); | |
| } | |
| private string GetGeneratorName() { | |
| string format; | |
| if (_publicResources) { | |
| format = "PublicResXFileScriptGenerator v{0}"; | |
| } | |
| else { | |
| format = "ResXFileScriptGenerator v{0}"; | |
| } | |
| Version versionInfo = typeof(ScriptPreprocessorApplication).Assembly.GetName().Version; | |
| return String.Format(format, versionInfo); | |
| } | |
| private static bool IsLocalizedResourceFile(string resourceFileName) { | |
| string locale = Utility.GetResourceFileLocale(resourceFileName); | |
| return (String.IsNullOrEmpty(locale) == false); | |
| } | |
| #region Implementation of IObjectWithSite | |
| int Interop.IObjectWithSite.SetSite(object pUnkSite) { | |
| _site = pUnkSite; | |
| return Interop.S_OK; | |
| } | |
| int Interop.IObjectWithSite.GetSite(ref Guid riid, out IntPtr ppunkSite) { | |
| ppunkSite = IntPtr.Zero; | |
| int hr = Interop.E_FAIL; | |
| if (_site != null) { | |
| IntPtr punk = Marshal.GetIUnknownForObject(_site); | |
| if (punk != IntPtr.Zero) { | |
| try { | |
| hr = Marshal.QueryInterface(punk, ref riid, out ppunkSite); | |
| } | |
| finally { | |
| Marshal.Release(punk); | |
| punk = IntPtr.Zero; | |
| } | |
| } | |
| } | |
| return hr; | |
| } | |
| #endregion | |
| #region IVsSingleFileGenerator Members | |
| int Interop.IVsSingleFileGenerator.GetDefaultExtension(out string extension) { | |
| extension = ".cs"; | |
| return Interop.S_OK; | |
| } | |
| int Interop.IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, out IntPtr pbstrOutputFileContents, out int pbstrOutputFileContentsSize, Interop.IVsGeneratorProgress pGenerateProgress) { | |
| pbstrOutputFileContents = IntPtr.Zero; | |
| pbstrOutputFileContentsSize = 0; | |
| if (String.IsNullOrEmpty(wszInputFilePath)) { | |
| return Interop.E_INVALIDARG; | |
| } | |
| if (String.IsNullOrEmpty(bstrInputFileContents)) { | |
| return Interop.E_INVALIDARG; | |
| } | |
| string code = null; | |
| try { | |
| code = GenerateCode(wszInputFilePath, bstrInputFileContents, wszDefaultNamespace); | |
| } | |
| catch (Exception e) { | |
| Debug.Fail(e.ToString()); | |
| } | |
| if (String.IsNullOrEmpty(code)) { | |
| return Interop.E_FAIL; | |
| } | |
| try { | |
| byte[] codeBytes = Encoding.UTF8.GetBytes(code); | |
| IntPtr buffer = Marshal.AllocCoTaskMem(codeBytes.Length); | |
| Marshal.Copy(codeBytes, 0, buffer, codeBytes.Length); | |
| pbstrOutputFileContents = buffer; | |
| pbstrOutputFileContentsSize = codeBytes.Length; | |
| } | |
| catch { | |
| return Interop.E_OUTOFMEMORY; | |
| } | |
| return Interop.S_OK; | |
| } | |
| #endregion | |
| } | |
| } | |
| // Interop.cs | |
| using System; | |
| using System.Diagnostics; | |
| using System.Runtime.InteropServices; | |
| namespace ScriptSharp { | |
| internal static class Interop { | |
| public const int S_OK = 0; | |
| public const int E_FAIL = unchecked(-2147467259); | |
| public const int E_INVALIDARG = unchecked(-2147024809); | |
| public const int E_OUTOFMEMORY = unchecked(-2147024882); | |
| [ | |
| ComImport, | |
| Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352"), | |
| InterfaceType(ComInterfaceType.InterfaceIsIUnknown) | |
| ] | |
| internal interface IObjectWithSite { | |
| [PreserveSig] | |
| int SetSite([MarshalAs(UnmanagedType.Interface)] object pUnkSite); | |
| [PreserveSig] | |
| int GetSite([In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppunkSite); | |
| } | |
| [ | |
| ComImport, | |
| Guid("BED89B98-6EC9-43CB-B0A8-41D6E2D6669D"), | |
| InterfaceType(ComInterfaceType.InterfaceIsIUnknown) | |
| ] | |
| internal interface IVsGeneratorProgress { | |
| [PreserveSig] | |
| int GeneratorError(bool fWarning, int dwLevel, [MarshalAs(UnmanagedType.BStr)] string bstrError, int dwLine, int dwColumn); | |
| [PreserveSig] | |
| int Progress(int nComplete, int nTotal); | |
| } | |
| [ | |
| ComImport, | |
| Guid("3634494C-492F-4F91-8009-4541234E4E99"), | |
| InterfaceType(ComInterfaceType.InterfaceIsIUnknown) | |
| ] | |
| internal interface IVsSingleFileGenerator { | |
| [PreserveSig] | |
| int GetDefaultExtension([Out, MarshalAs(UnmanagedType.BStr)] out string extension); | |
| [PreserveSig] | |
| int Generate([MarshalAs(UnmanagedType.LPWStr)] string wszInputFilePath, [MarshalAs(UnmanagedType.BStr)] string bstrInputFileContents, [MarshalAs(UnmanagedType.LPWStr)] string wszDefaultNamespace, out IntPtr pbstrOutputFileContents, out int pbstrOutputFileContentsSize, IVsGeneratorProgress pGenerateProgress); | |
| } | |
| } | |
| } | |
| // Registration (requires some registry entries ... unfortunately... | |
| // this is done by the script# msi) | |
| // Hopefully WiX code will be indicative of what you need for your own | |
| // single file generator | |
| <RegistryKey Id="VWDExp10_ResxCLSID" Action="createAndRemoveOnUninstall" | |
| Root="HKLM" Key="Software\Microsoft\VWDExpress\9.0\CLSID\{33FA0BF4-CBBA-4fdd-9300-0F5A6BDE7E33}"> | |
| <RegistryValue Type="string" Value="ScriptSharp.ResourceModel.ResXInternalScriptGenerator" /> | |
| <RegistryValue Type="string" Name="InprocServer32" Value="[%SystemRoot]\System32\mscoree.dll" /> | |
| <RegistryValue Type="string" Name="Class" Value="ScriptSharp.ResourceModel.ResXInternalScriptGenerator" /> | |
| <RegistryValue Type="string" Name="Assembly" Value="ScriptSharp, Version=[PRODUCTVERSION], Culture=neutral, PublicKeyToken=8fc0e3af5abcb6c4" /> | |
| <RegistryValue Type="string" Name="ThreadingModel" Value="Both" /> | |
| </RegistryKey> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment