/// <summary> /// This is called after the single file generator has been invoked to create or update the code file. /// </summary> /// <param name="fileNode">The node associated to the generator</param> /// <param name="data">data to update the file with</param> /// <param name="size">size of the data</param> /// <param name="fileName">Name of the file to update or create</param> /// <returns>full path of the file</returns> protected virtual string UpdateGeneratedCodeFile(FileNode fileNode, byte[] data, int size, string fileName) { string filePath = Path.Combine(Path.GetDirectoryName(fileNode.GetMkDocument()), fileName); IVsRunningDocumentTable rdt = this.projectMgr.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable; // (kberes) Shouldn't this be an InvalidOperationException instead with some not to annoying errormessage to the user? if (rdt == null) { ErrorHandler.ThrowOnFailure(VSConstants.E_FAIL); } IVsHierarchy hier; uint cookie; uint itemid; IntPtr docData = IntPtr.Zero; ErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument((uint)(_VSRDTFLAGS.RDT_NoLock), filePath, out hier, out itemid, out docData, out cookie)); if (docData != IntPtr.Zero) { Marshal.Release(docData); IVsTextStream srpStream = null; if (srpStream != null) { int oldLen = 0; int hr = srpStream.GetSize(out oldLen); if (ErrorHandler.Succeeded(hr)) { IntPtr dest = IntPtr.Zero; try { dest = Marshal.AllocCoTaskMem(data.Length); Marshal.Copy(data, 0, dest, data.Length); ErrorHandler.ThrowOnFailure(srpStream.ReplaceStream(0, oldLen, dest, size / 2)); } finally { if (dest != IntPtr.Zero) { Marshal.Release(dest); } } } } } else { using (FileStream generatedFileStream = File.Open(filePath, FileMode.OpenOrCreate)) { generatedFileStream.Write(data, 0, size); } EnvDTE.ProjectItem projectItem = fileNode.GetAutomationObject() as EnvDTE.ProjectItem; if (projectItem != null && (this.projectMgr.FindChild(fileNode.FileName) == null)) { projectItem.ProjectItems.AddFromFile(filePath); } } return(filePath); }
/// <summary> /// This is called after the single file generator has been invoked to create or update the code file. /// </summary> /// <param name="fileNode">The node associated to the generator</param> /// <param name="data">data to update the file with</param> /// <param name="size">size of the data</param> /// <param name="fileName">Name of the file to update or create</param> /// <returns>full path of the file</returns> protected virtual string UpdateGeneratedCodeFile(FileNode fileNode, byte[] data, int size, string fileName) { string filePath = Path.Combine(Path.GetDirectoryName(fileNode.GetMkDocument()), fileName); IVsRunningDocumentTable rdt = this.projectMgr.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable; // (kberes) Shouldn't this be an InvalidOperationException instead with some not to annoying errormessage to the user? if(rdt == null) { ErrorHandler.ThrowOnFailure(VSConstants.E_FAIL); } IVsHierarchy hier; uint cookie; uint itemid; IntPtr docData = IntPtr.Zero; ErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument((uint)(_VSRDTFLAGS.RDT_NoLock), filePath, out hier, out itemid, out docData, out cookie)); if(docData != IntPtr.Zero) { Marshal.Release(docData); IVsTextStream srpStream = null; if(srpStream != null) { int oldLen = 0; int hr = srpStream.GetSize(out oldLen); if(ErrorHandler.Succeeded(hr)) { IntPtr dest = IntPtr.Zero; try { dest = Marshal.AllocCoTaskMem(data.Length); Marshal.Copy(data, 0, dest, data.Length); ErrorHandler.ThrowOnFailure(srpStream.ReplaceStream(0, oldLen, dest, size / 2)); } finally { if(dest != IntPtr.Zero) { Marshal.Release(dest); } } } } } else { using(FileStream generatedFileStream = File.Open(filePath, FileMode.OpenOrCreate)) { generatedFileStream.Write(data, 0, size); } EnvDTE.ProjectItem projectItem = fileNode.GetAutomationObject() as EnvDTE.ProjectItem; if(projectItem != null && (this.projectMgr.FindChild(fileNode.FileName) == null)) { projectItem.ProjectItems.AddFromFile(filePath); } } return filePath; }