我正在为我的团队开发代码生成器(VSIX),并且在我努力使用VSIX可扩展性框架之后,我打算将Roslyn用作基础引擎。
我的代码gen目前能够为解决方案生成一个新的csproj,并能够根据VSIX扩展性的Templating项目生成样板代码库。我很有野心,我试图不依赖静态模板项目,而是使用Roslyn来代替生成代码。
我的解决方案有一个文件夹列表,每个文件夹都有一个csproj列表。
我的问题1是我尝试使用Roslyn Workspace API来检测已在代码编辑器中打开的当前文档(.cs),或者我试图获取所选cs文件的当前文档ID我是对的单击解决方案资源管理器。
我曾尝试使用AdhocWorkspace,到目前为止我已经失败,因为我无法获得任何内容。
问题2:如果我使用AdhocWorkspace,我能否更改csproj属性中的默认命名空间?或者它目前不属于Roslyn Workspace API的功能部分?
感谢。
答案 0 :(得分:2)
对于#1一些代码,我必须做同样的事情。我正在用光标做事,所以我要通过caretPosition(光标)。还有其他方法,但要点是相同的,让当前的文本视图从那里到罗斯林。
您需要安装Microsoft.CodeAnalysis.EditorFeatures.Text
,这会引入所有代码分析包,但允许您使用GetOpenDocumentInCurrentContextWithChanges
上应用的ITextSnapshot
扩展程序
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
}
&#34;或者我正在尝试从解决方案资源管理器中右键单击所选cs文件的当前文档ID。&#34;
这真的很丑陋,但我从一个不同的SO帖子(不记得作者)中使用的确实运作良好。
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"))