我正在为我的团队开发一个代码gen ( VSIX ),并且在与VSIX扩展框架进行了斗争之后,我正将Roslyn作为一个基本引擎来使用。
我的代码gen目前能够为解决方案生成一个新的csproj,并能够根据VSIX扩展性生成基于模板项目的样板代码库。我很有野心,我尽量不依赖静态模板项目,而是使用Roslyn来编写代码。
我的解决方案有一个文件夹列表,每个文件夹都有一个csproj列表。
我的问题1是,我试图使用来检测在代码编辑器中打开的当前文档(.cs),或者试图从解决方案资源管理器右键单击所选cs文件的当前文档id。
我尝试过使用AdhocWorkspace,到目前为止,它已经失败了,因为我无法得到任何。
问题2:如果我使用AdhocWorkspace,是否能够更改csproj属性中的默认命名空间?或者它不是目前Roslyn中功能的一部分?
谢谢。
发布于 2016-06-14 08:56:30
对于第一种代码,我必须做同样的事情。我正在做一些关于光标的事情,所以我正在浏览caretPosition (游标)。还有其他的方法,但要点是一样的,得到当前的文本视图从那个到罗斯林。
您将需要安装Microsoft.CodeAnalysis.EditorFeatures.Text
,它引入了分配的代码分析包,但允许您使用应用于ITextSnapshot
的GetOpenDocumentInCurrentContextWithChanges
扩展。
private IVsEditorAdaptersFactoryService GetEditorAdaptersFactoryService()
{
IComponentModel componentModel =(IComponentModel)GetService(typeof(SComponentModel));
return componentModel.GetService<IVsEditorAdaptersFactoryService>();
}
private Microsoft.VisualStudio.Text.Editor.IWpfTextView GetTextView()
{
IVsTextManager textManager = (IVsTextManager)GetService(typeof(SVsTextManager));
if (textManager == null)
return null;
IVsTextView textView = null;
textManager.GetActiveView(1, null, out textView);
if (textView == null)
return null;
return GetEditorAdaptersFactoryService().GetWpfTextView(textView);
}
//code to get the doc
Microsoft.VisualStudio.Text.Editor.IWpfTextView textView = GetTextView();
if (textView != null)
{
SnapshotPoint caretPosition = textView.Caret.Position.BufferPosition;
Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
//do stuff with Roslyn Document
}
“或者试图从解决方案资源管理器右键单击所选cs文件的当前文档id。”
这确实很难看,但我用的是一篇与众不同的文章(不记得作者了),这篇文章效果很好。
private static bool IsSingleProjectItemSelection(out IVsHierarchy hierarchy, out uint itemid)
{
hierarchy = null;
itemid = VSConstants.VSITEMID_NIL;
int hr = VSConstants.S_OK;
var monitorSelection = Package.GetGlobalService( typeof( SVsShellMonitorSelection ) ) as IVsMonitorSelection;
var solution = Package.GetGlobalService( typeof( SVsSolution ) ) as IVsSolution;
if (monitorSelection == null || solution == null)
return false;
IVsMultiItemSelect multiItemSelect = null;
IntPtr hierarchyPtr = IntPtr.Zero;
IntPtr selectionContainerPtr = IntPtr.Zero;
try
{
hr = monitorSelection.GetCurrentSelection( out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainerPtr );
if (ErrorHandler.Failed( hr ) || hierarchyPtr == IntPtr.Zero || itemid == VSConstants.VSITEMID_NIL)
return false;
// multiple items are selected
if (multiItemSelect != null)
return false;
// there is a hierarchy root node selected, thus it is not a single item inside a project
if (itemid == VSConstants.VSITEMID_ROOT)
return false;
hierarchy = Marshal.GetObjectForIUnknown( hierarchyPtr ) as IVsHierarchy;
if (hierarchy == null)
return false;
Guid guidProjectID = Guid.Empty;
if (ErrorHandler.Failed( solution.GetGuidOfProject( hierarchy, out guidProjectID ) ))
return false;
// if we got this far then there is a single project item selected
return true;
}
finally
{
if (selectionContainerPtr != IntPtr.Zero)
Marshal.Release( selectionContainerPtr );
if (hierarchyPtr != IntPtr.Zero)
Marshal.Release( hierarchyPtr );
}
}
IVsHierarchy hierarchy = null;
uint itemid = VSConstants.VSITEMID_NIL;
if (!IsSingleProjectItemSelection(out hierarchy, out itemid))
return;
string itemFullPath = null;
((IVsProject)hierarchy).GetMkDocument(itemid, out itemFullPath);
if (itemFullPath.EndsWith(".cs"))
https://stackoverflow.com/questions/36218148
复制