ProjectItem _FindItem(string path) { int iFound = 0; uint itemId = 0; EnvDTE.ProjectItem item; Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[] pdwPriority = new Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[1]; for (var i = 0; i < _projects.Length; i++) { Microsoft.VisualStudio.Shell.Interop.IVsProject vsProject = VSUtility.ToVsProject(_projects.GetValue(i) as EnvDTE.Project); vsProject.IsDocumentInProject(path, out iFound, pdwPriority, out itemId); if (iFound != 0 && itemId != 0) { Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp = null; vsProject.GetItemContext(itemId, out oleSp); if (null != oleSp) { ServiceProvider sp = new ServiceProvider(oleSp); // convert our handle to a ProjectItem item = sp.GetService(typeof(EnvDTE.ProjectItem)) as EnvDTE.ProjectItem; return(item); } } } return(null); }
public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress) { string outputfile = null; string log = ""; try { if (null == _site) { throw new InvalidOperationException("The Rolex custom tool can only be used in a design time environment. Consider using Rolex as a pre-build step instead."); } wszInputFilePath = Path.GetFullPath(wszInputFilePath); var item = _FindItem(wszInputFilePath); if (null == item) { throw new ApplicationException("Design time environment project item fetch failed."); } foreach (EnvDTE.ProjectItem childItem in item.ProjectItems) { childItem.Delete(); } var proj = item.ContainingProject; var pil = new List <object>(proj.ProjectItems.Count); foreach (EnvDTE.ProjectItem pi in proj.ProjectItems) { if (pi != item) { pil.Add(pi); } } var genShared = !VSUtility.HasClassOrStruct(pil, wszDefaultNamespace, "TableTokenizer"); var dir = Path.GetDirectoryName(wszInputFilePath); var lang = VSUtility.GetProjectLanguageFromItem(item); if (null == lang) { lang = "cs"; } outputfile = Path.Combine(dir, Path.GetFileNameWithoutExtension(wszInputFilePath) + "." + lang); var args = new List <string>(); args.Add(wszInputFilePath); args.Add("/output"); args.Add(outputfile); if (0 != string.Compare("cs", lang, StringComparison.InvariantCultureIgnoreCase)) { args.Add("/language"); args.Add(lang); } if (!string.IsNullOrWhiteSpace(wszDefaultNamespace)) { args.Add("/namespace"); args.Add(wszDefaultNamespace); } if (!genShared) { args.Add("/noshared"); } var sw = new StringWriter(); var ec = global::Rolex.Program.Run(args.ToArray(), TextReader.Null, TextWriter.Null, sw); log = sw.ToString(); var isSuccess = 0 == ec; if (isSuccess) { EnvDTE.ProjectItem outitm = item.ProjectItems.AddFromFile(outputfile); string ext; DefaultExtension(out ext); } else { pGenerateProgress.GeneratorError(0, 0, "Rolex returned error code: " + ec.ToString(), unchecked ((uint)-1), unchecked ((uint)-1)); } } catch (Exception ex) { pGenerateProgress.GeneratorError(0, 0, "Rolex custom tool failed with: " + ex.Message, unchecked ((uint)-1), unchecked ((uint)-1)); log += "Rolex custom tool failed with: " + ex.Message; } finally { try { pGenerateProgress.Progress(2, 2); } catch { } } // have used streams here in the past to scale, but even for huge items, this is faster! // most likely due to the lack of extra copies (memory/array resizing) byte[] bytes = Encoding.UTF8.GetBytes(log); int length = bytes.Length; rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(length); Marshal.Copy(bytes, 0, rgbOutputFileContents[0], length); pcbOutput = (uint)length; return(VSConstants.S_OK); }