using System; using System.CodeDom.Compiler; using System.Runtime.InteropServices; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Designer.Interfaces; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Xsd2Code.Library; using IServiceProvider=Microsoft.VisualStudio.OLE.Interop.IServiceProvider; namespace Xsd2Code.CustomTool { /// /// Implementation of the Xsd2Code custom tool for VisualStudio /// Usage: /// Specify Xsd2CodeCustomTool in the CustomTool proprty of an XSD file within Visual Studio /// /// /// /// Revision history: /// /// Modified 2009-02-20 by Ruslan Urban /// Changed signature of the GeneratorFacade class constructor /// /// [Guid("9E6FCB59-E3EF-4bbe-966C-30AC92A44DF6")] public class Xsd2CodeCustomTool : IVsSingleFileGenerator, IObjectWithSite { private CodeDomProvider provider; private object site; #region IVsSingleFileGenerator Membres public int DefaultExtension(out string pbstrDefaultExtension) { pbstrDefaultExtension = this.provider.FileExtension; if (!string.IsNullOrEmpty(pbstrDefaultExtension)) pbstrDefaultExtension = ".Designer." + pbstrDefaultExtension.TrimStart(".".ToCharArray()); return 0; } /// /// Generates the specified WSZ input file path. /// /// The WSZ input file path. /// The BSTR input file contents. /// The WSZ default namespace. /// The RGB output file contents. /// The PCB output. /// The p generate progress. /// public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress) { if (wszInputFilePath == null) throw new ArgumentNullException(wszInputFilePath); var generatorParams = GeneratorParams.LoadFromFile(wszInputFilePath) ?? new GeneratorParams(); generatorParams.InputFilePath = wszInputFilePath; generatorParams.NameSpace = wszDefaultNamespace; var xsdGen = new GeneratorFacade(this.provider, generatorParams); var result = xsdGen.GenerateBytes(); var generatedStuff = result.Entity; if (generatedStuff == null) { rgbOutputFileContents[0] = IntPtr.Zero; pcbOutput = 0; return 0; } // Copie du flux en mémoire pour que Visual Studio puisse le récupérer rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(generatedStuff.Length); Marshal.Copy(generatedStuff, 0, rgbOutputFileContents[0], generatedStuff.Length); pcbOutput = (uint) generatedStuff.Length; return 0; } #endregion #region IObjectWithSite Members /// /// /// /// public void GetSite(ref Guid riid, out IntPtr ppvSite) { if (this.site == null) throw new COMException("Aucun site", VSConstants.E_FAIL); // Créer un pointeur d'interface IntPtr pUnknownPointer = Marshal.GetIUnknownForObject(this.site); // ReSharper disable RedundantAssignment IntPtr intPointer = IntPtr.Zero; // ReSharper restore RedundantAssignment // Demande de pointeur de l'interface pUnknownPointer Marshal.QueryInterface(pUnknownPointer, ref riid, out intPointer); if (intPointer == IntPtr.Zero) throw new COMException("site ne supporte pas la demande de pointeur", VSConstants.E_NOINTERFACE); ppvSite = intPointer; } /// /// /// public void SetSite(object pUnkSite) { this.site = pUnkSite; //Créer un fournisseur de service du site var serviceProvider = new ServiceProvider(this.site as IServiceProvider); //Récupéreur le service SVSMDCodeDomProvider var p = serviceProvider.GetService(typeof (SVSMDCodeDomProvider)) as IVSMDCodeDomProvider; if (p != null) this.provider = p.CodeDomProvider as CodeDomProvider; else { //Ici, aucun langage n'a pu être déterminé this.provider = CodeDomProvider.CreateProvider("C#"); } } #endregion } }