在Visual Studio 2015扩展中访问ProjectItem内容及替代方法问询
在Visual Studio 2015扩展开发中直接访问ProjectItem内容的方案
当然可以直接访问ProjectItem对象的内容,完全不用绕弯子去通过Properties获取FullPath再读取文件。下面是几个在VS2015扩展开发里常用的替代方案,亲测好用:
1. 利用ProjectItem.Document对象直接读取
ProjectItem本身就关联了一个Document对象,通过它能直接拿到文本内容,甚至包括编辑器里未保存的修改(如果文件已经打开的话)。示例代码如下:
if (projectItem.Document != null) { var textDocument = projectItem.Document.Object("TextDocument") as TextDocument; if (textDocument != null) { // 从文档起始点创建编辑点,读取到末尾 EditPoint startPoint = textDocument.StartPoint.CreateEditPoint(); string fullContent = startPoint.GetText(textDocument.EndPoint); // 这里就拿到了文件的全部内容 } }
如果文件还没被打开,你可以先调用projectItem.Open()来初始化Document对象,要是不想弹出编辑器窗口,可以指定打开方式:projectItem.Open(Constants.vsViewKindCode),这样文档会在后台加载,不会激活窗口。
2. 用IVsTextLines接口(底层高效方案)
如果需要更高效的文本访问,或者不想依赖编辑器的状态,可以借助VS的COM接口IVsTextLines来获取内容。这个方式直接读取文本缓冲区,性能更优。示例代码片段:
// 先把ProjectItem转成IVsHierarchy和对应的Item ID IVsHierarchy hierarchy = projectItem.ContainingProject.Object as IVsHierarchy; if (hierarchy != null) { hierarchy.GetCanonicalName((uint)projectItem.ID, out string itemCanonicalName); // 获取文本管理器服务 IVsTextManager2 textManager = (IVsTextManager2)Package.GetGlobalService(typeof(SVsTextManager)); textManager.GetBufferSupportingLangServiceByFileName(itemCanonicalName, Guid.Empty, out IVsTextLines textLines); if (textLines != null) { // 获取最后一行的索引,然后读取全部内容 textLines.GetLastLineIndex(out int lastLine, out int lastCol); textLines.GetLineText(0, 0, lastLine, lastCol, out string fullContent); // 处理读取到的内容 } }
注意事项
- 不是所有
ProjectItem都有Document对象,比如文件夹、二进制文件这类非文本项,所以使用前一定要做好null检查,避免空引用异常。 - 如果你需要读取的是二进制文件内容,那可能还是得通过
FullPath去读,但文本类文件用上面的方法完全没问题。
内容的提问来源于stack exchange,提问作者Elsbeth
相关产品推荐
相关产品推荐

