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); }
/// <summary> /// Open the file in invisible editor in RDT, and get text buffer from it. /// </summary> /// <remarks> /// This method created for refactoring usage, refactoring will work on all kinds of /// docdata, not only SqlEditorDocData. If change this method, please get let LiangZ /// know. /// </remarks> /// <param name="fullPathFileName">File name with full path.</param> /// <param name="project">the hierarchy for the document</param> /// <param name="spEditor">The result invisible editor.</param> /// <param name="textLines">The result text buffer.</param> /// <returns>True, if the file is opened correctly in invisible editor.</returns> public bool TryGetTextLinesAndInvisibleEditor( string fullPathFileName, VsShell.IVsProject project, out VsShell.IVsInvisibleEditor spEditor, out VsTextMgr.IVsTextLines textLines) { spEditor = null; textLines = null; // Need to open this file. Use the invisible editor manager to do so. VsShell.IVsInvisibleEditorManager invisibleEditorMgr; var ppDocData = IntPtr.Zero; bool result; var iidIVsTextLines = typeof(VsTextMgr.IVsTextLines).GUID; try { invisibleEditorMgr = _invisibleEditorManager; NativeMethods.ThrowOnFailure( invisibleEditorMgr.RegisterInvisibleEditor( fullPathFileName, project, (uint)VsShell._EDITORREGFLAGS.RIEF_ENABLECACHING, null, out spEditor)); if (spEditor != null) { var hr = spEditor.GetDocData(0, ref iidIVsTextLines, out ppDocData); if (hr == VSConstants.S_OK && ppDocData != IntPtr.Zero) { textLines = Marshal.GetTypedObjectForIUnknown(ppDocData, typeof(VsTextMgr.IVsTextLines)) as VsTextMgr.IVsTextLines; result = true; } else { result = false; } } else { result = false; } } finally { if (ppDocData != IntPtr.Zero) { Marshal.Release(ppDocData); } } return(result); }
public int Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IntPtr[] rgbOutputFileContents, out uint output, IVsGeneratorProgress generateProgress) { try { if (cancelGenerating) { byte[] fileData = File.ReadAllBytes(Path.ChangeExtension(inputFilePath, GetDefaultExtension())); // Return our summary data, so that Visual Studio may write it to disk. //outputFileContents = Marshal.AllocCoTaskMem(fileData.Length); rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(fileData.Length); //Marshal.Copy(fileData, 0, outputFileContents, fileData.Length); Marshal.Copy(fileData, 0, rgbOutputFileContents[0], fileData.Length); //output = fileData.Length; output = (uint)fileData.Length; //return 0; return(VSConstants.E_ABORT); // ?????? } this.inputFileContents = inputFileContents; this.inputFilePath = inputFilePath; this.defaultNamespace = defaultNamespace; int iFound = 0; uint itemId = 0; ProjectItem projectItem; Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[] pdwPriority = new Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[1]; // Obtain a reference to the current project as an IVsProject type Microsoft.VisualStudio.Shell.Interop.IVsProject VsProject = VsHelper.ToVsProject(project); // This locates, and returns a handle to our source file, as a ProjectItem VsProject.IsDocumentInProject(InputFilePath, out iFound, pdwPriority, out itemId); // If our source file was found in the project (which it should have been) if (iFound != 0 && itemId != 0) { Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp = null; VsProject.GetItemContext(itemId, out oleSp); if (oleSp != null) { ServiceProvider sp = new ServiceProvider(oleSp); // Convert our handle to a ProjectItem projectItem = sp.GetService(typeof(ProjectItem)) as ProjectItem; } else { throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem"); } } else { throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem"); } oldFileNames.Clear(); newFileNames.Clear(); foreach (ProjectItem childItem in projectItem.ProjectItems) { oldFileNames.Add(childItem.Name); if (!childItem.Name.EndsWith(".cs")) { childItem.Properties.Item("BuildAction").Value = 0; } } // Now we can start our work, iterate across all the 'items' in our source file foreach (T item in this) { // Obtain a name for this target file string fileName = GetFileName(item); // Add it to the tracking cache newFileNames.Add(fileName); // Fully qualify the file on the filesystem string filePath = Path.Combine(Path.GetDirectoryName(inputFilePath), fileName); if (!(item as IChangable).IsChanged && File.Exists(filePath)) { continue; } try { bool isNewAdded = !oldFileNames.Contains(fileName); if (!isNewAdded) { // Check out this file. if (project.DTE.SourceControl.IsItemUnderSCC(filePath) && !project.DTE.SourceControl.IsItemCheckedOut(filePath)) { project.DTE.SourceControl.CheckOutItem(filePath); } } // Create the file FileStream fs = File.Create(filePath); try { // Generate our target file content byte[] data = GenerateContent(item); // Write it out to the stream fs.Write(data, 0, data.Length); fs.Close(); OnFileGenerated(filePath, isNewAdded); /* * Here you may wish to perform some addition logic * such as, setting a custom tool for the target file if it * is intented to perform its own generation process. * Or, set the target file as an 'Embedded Resource' so that * it is embedded into the final Assembly. * * EnvDTE.Property prop = itm.Properties.Item("CustomTool"); * * if (String.IsNullOrEmpty((string)prop.Value) || !String.Equals((string)prop.Value, typeof(AnotherCustomTool).Name)) * { * prop.Value = typeof(AnotherCustomTool).Name; * } */ } catch (Exception ex) // An error generating the content and writing to file. Not fatal? { fs.Close(); OnError(ex); LogException(ex); } } catch (Exception ex) // An error during core SS and/or file system operations. This is thrown to parent. { throw ex; } } // Perform some clean-up, making sure we delete any old (stale) target-files foreach (ProjectItem childItem in projectItem.ProjectItems) { if (!(childItem.Name.EndsWith(GetDefaultExtension()) || newFileNames.Contains(childItem.Name))) { // Then delete it childItem.Delete(); } } foreach (var newFileName in newFileNames) { if (!oldFileNames.Contains(newFileName)) { string fileName = Path.Combine(inputFilePath.Substring(0, inputFilePath.LastIndexOf(Path.DirectorySeparatorChar)), newFileName); // Add the newly generated file to the solution, as a child of the source file... ProjectItem itm = projectItem.ProjectItems.AddFromFile(fileName); // Set buildaction to none if (!newFileName.EndsWith(".cs")) { itm.Properties.Item("BuildAction").Value = 0; } } } // Generate our summary content for our 'single' file byte[] summaryData = GenerateSummaryContent(); if (summaryData == null) { //outputFileContents = IntPtr.Zero; rgbOutputFileContents[0] = IntPtr.Zero; output = 0; } else { // Return our summary data, so that Visual Studio may write it to disk. //outputFileContents = Marshal.AllocCoTaskMem(summaryData.Length); rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(summaryData.Length); // Marshal.Copy(summaryData, 0, outputFileContents, summaryData.Length); Marshal.Copy(summaryData, 0, rgbOutputFileContents[0], summaryData.Length); output = (uint)summaryData.Length; } } catch (Exception ex) { OnError(ex); LogException(ex); //outputFileContents = IntPtr.Zero; rgbOutputFileContents[0] = IntPtr.Zero; output = 0; } return(VSConstants.S_OK); }
public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress) { this._pGenerateProgress = pGenerateProgress; this.bstrInputFileContents = bstrInputFileContents; this.wszInputFilePath = wszInputFilePath; this.newFileNames.Clear(); int iFound = 0; uint itemId = 0; EnvDTE.ProjectItem item; Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[] pdwPriority = new Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[1]; // obtain a reference to the current project as an IVsProject type Microsoft.VisualStudio.Shell.Interop.IVsProject VsProject = VsHelper.ToVsProject(GetProject()); // this locates, and returns a handle to our source file, as a ProjectItem VsProject.IsDocumentInProject(InputFilePath, out iFound, pdwPriority, out itemId); // if our source file was found in the project (which it should have been) if (iFound != 0 && itemId != 0) { Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp = null; VsProject.GetItemContext(itemId, out oleSp); if (oleSp != null) { ServiceProvider sp = new ServiceProvider(oleSp); // convert our handle to a ProjectItem item = sp.GetService(typeof(EnvDTE.ProjectItem)) as EnvDTE.ProjectItem; } else { throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem"); } } else { throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem"); } // now we can start our work, iterate across all the 'elements' in our source file foreach (IterativeElementType element in this) { try { // obtain a name for this target file string fileName = GetFileName(element); // add it to the tracking cache newFileNames.Add(fileName); // fully qualify the file on the filesystem string strFile = Path.Combine(wszInputFilePath.Substring(0, wszInputFilePath.LastIndexOf(Path.DirectorySeparatorChar)), fileName); // create the file FileStream fs = File.Create(strFile); try { // generate our target file content byte[] data = GenerateContent(element); // write it out to the stream fs.Write(data, 0, data.Length); fs.Close(); // add the newly generated file to the solution, as a child of the source file... EnvDTE.ProjectItem itm = item.ProjectItems.AddFromFile(strFile); /* * Here you may wish to perform some addition logic * such as, setting a custom tool for the target file if it * is intented to perform its own generation process. * Or, set the target file as an 'Embedded Resource' so that * it is embedded into the final Assembly. * * EnvDTE.Property prop = itm.Properties.Item("CustomTool"); */ //// set to embedded resource itm.Properties.Item("BuildAction").Value = 3; /* * if (String.IsNullOrEmpty((string)prop.Value) || !String.Equals((string)prop.Value, typeof(AnotherCustomTool).Name)) * { * prop.Value = typeof(AnotherCustomTool).Name; * } */ } catch (Exception) { fs.Close(); if (File.Exists(strFile)) { File.Delete(strFile); } } } catch (Exception ex) { throw ex; } } // perform some clean-up, making sure we delete any old (stale) target-files foreach (EnvDTE.ProjectItem childItem in item.ProjectItems) { if (!(childItem.Name.EndsWith(GetMultiExtension()) || newFileNames.Contains(childItem.Name))) { // then delete it childItem.Delete(); } } // generate our summary content for our 'single' file byte[] summaryData = GenerateSummaryContent(); if (summaryData == null) { rgbOutputFileContents[0] = IntPtr.Zero; pcbOutput = 0; } else { // return our summary data, so that Visual Studio may write it to disk. rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(summaryData.Length); Marshal.Copy(summaryData, 0, rgbOutputFileContents[0], summaryData.Length); pcbOutput = (uint)summaryData.Length; } return(VSConstants.S_OK); }
protected override byte[] GenerateCode(string inputFileContent) { List <string> newFileNames = new List <string>(); string wszInputFilePath = InputFilePath; byte[] returnValue = null; int iFound = 0; uint itemId = 0; EnvDTE.ProjectItem item; Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[] pdwPriority = new Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[1]; // obtain a reference to the current project as an IVsProject type Microsoft.VisualStudio.Shell.Interop.IVsProject VsProject = VsHelper.ToVsProject(GetProject()); // this locates, and returns a handle to our source file, as a ProjectItem VsProject.IsDocumentInProject(InputFilePath, out iFound, pdwPriority, out itemId); // if our source file was found in the project (which it should have been) if (iFound != 0 && itemId != 0) { Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp = null; VsProject.GetItemContext(itemId, out oleSp); if (oleSp != null) { ServiceProvider sp = new ServiceProvider(oleSp); // convert our handle to a ProjectItem item = sp.GetService(typeof(EnvDTE.ProjectItem)) as EnvDTE.ProjectItem; } else { throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem"); } } else { throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem"); } foreach (EnvDTE.ProjectItem childItem in item.ProjectItems) { if ((childItem.Name.EndsWith(GetDefaultExtension()) /*|| newFileNames.Contains(childItem.Name)*/)) { // then delete it childItem.Delete(); } } // now we can start our work, iterate across all the 'elements' in our source file IEnumerable <IterativeElementType> elements = GenerateElements(inputFileContent); if (elements != null) { int count = 0; if (typeof(System.Collections.ICollection).IsAssignableFrom(elements.GetEnumerator().GetType())) { count = (elements.GetEnumerator() as System.Collections.ICollection).Count; } int i = 0; string firstFileName = null; foreach (IterativeElementType element in elements) { // obtain a name for this target file string fileName = GetFileName(element); // generate our target file content byte[] data = GenerateContent(element); if (returnValue == null) { returnValue = data; firstFileName = fileName; continue; } // add it to the tracking cache newFileNames.Add(fileName); // fully qualify the file on the filesystem string strFile = Path.Combine( wszInputFilePath.Substring(0, wszInputFilePath.LastIndexOf(Path.DirectorySeparatorChar)), fileName); // create the file bool err = true; try { using (FileStream fs = File.Create(strFile)) { // write it out to the stream fs.Write(data, 0, data.Length); } // add the newly generated file to the solution, as a child of the source file... EnvDTE.ProjectItem itm = item.ProjectItems.AddFromFile(strFile); /* * Here you may wish to perform some addition logic * such as, setting a custom tool for the target file if it * is intented to perform its own generation process. * Or, set the target file as an 'Embedded Resource' so that * it is embedded into the final Assembly. * * EnvDTE.Property prop = itm.Properties.Item("CustomTool"); * //// set to embedded resource * itm.Properties.Item("BuildAction").Value = 3; * if (String.IsNullOrEmpty((string)prop.Value) || !String.Equals((string)prop.Value, typeof(AnotherCustomTool).Name)) * { * prop.Value = typeof(AnotherCustomTool).Name; * } */ err = false; } finally { if (err && File.Exists(strFile)) { File.Delete(strFile); } } if (this.CodeGeneratorProgress != null) { //Report that we are 1/2 done this.CodeGeneratorProgress.Progress((uint)i, (uint)count); } i++; } } //if (i == 1) // _fileName = firstFileName; // perform some clean-up, making sure we delete any old (stale) target-files //foreach (EnvDTE.ProjectItem childItem in item.ProjectItems) //{ // if ((childItem.Name.EndsWith(GetDefaultExtension()) /*|| newFileNames.Contains(childItem.Name)*/)) // // then delete it // childItem.Delete(); //} return(returnValue); }