[英]How to debug Visual Studio extensions?
我目前正在尝试编写自己的Visual Studio扩展(自定义编辑器)。 我尝试编写一些类似于SDK中MS提供的示例的代码,但是它不起作用。
发生的情况是,在运行VS的第二个实验实例之后,并构造了所有必需的类(编辑器工厂,编辑器窗格和编辑器控件本身)之后,VS通知“无法完成操作”,并且什么也没有发生。
我确实附有调试器,但是它不会因任何错误而停止。 除了我的源代码中明确放置的两个跟踪外,关于扩展的跟踪也没有了:
Entering constructor for: Spooksoft.Spk.SpkPackage
Entering Initialize() of: Spooksoft.Spk.SpkPackage
'devenv.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualStudio.Data.Tools.Delta.UI\v4.0_11.1.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Data.Tools.Delta.UI.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'devenv.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.TeamFoundation.Controls\v4.0_11.0.0.0__b03f5f7f11d50a3a\Microsoft.TeamFoundation.Controls.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'devenv.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.TeamFoundation.Client\11.0.0.0__b03f5f7f11d50a3a\Microsoft.TeamFoundation.Client.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
(...)
'devenv.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualStudio.Web.HTML.Razor.Shims\v4.0_11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Web.HTML.Razor.Shims.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'devenv.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualStudio.Web.HTML.Razor.Implementation.Shims.2_0\v4.0_11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Web.HTML.Razor.Implementation.Shims.2_0.dll'
The thread 'StatusBar' (0x760) has exited with code 0 (0x0).
The thread '<No Name>' (0xffc) has exited with code 0 (0x0).
The program '[4200] devenv.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).
我如何确定出了什么问题? 在哪里可以搜索任何错误消息?
源代码 (如果有人在乎)。
那可能无法解决我的问题,但肯定会提供更多选择。 在MS员工的帮助下(在MS论坛上),我设法确定了预期在VS中实现哪些接口。
您必须实现ICustomQueryInterface。 它的实现可能如下所示:
public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv)
{
Debug.WriteLine(String.Format("Attempt to cast to interface with iid {0}", iid));
ppv = IntPtr.Zero;
return CustomQueryInterfaceResult.NotHandled;
}
您将得到以下结果:
Attempt to cast to interface with iid f22a0ad5-8f51-4f66-a644-ea64770cf8b7
Attempt to cast to interface with iid 9d71890d-090c-4b67-80c3-4cb55c600b60
Attempt to cast to interface with iid d5d49c61-1c0b-4ea1-9adb-a79fb1dbc7b5
Attempt to cast to interface with iid 9d71890d-090c-4b67-80c3-4cb55c600b60
Attempt to cast to interface with iid d5d49c61-1c0b-4ea1-9adb-a79fb1dbc7b5
Attempt to cast to interface with iid d5d49c61-1c0b-4ea1-9adb-a79fb1dbc7b5
Attempt to cast to interface with iid 9d71890d-090c-4b67-80c3-4cb55c600b60
Attempt to cast to interface with iid d5d49c61-1c0b-4ea1-9adb-a79fb1dbc7b5
Attempt to cast to interface with iid d5d49c61-1c0b-4ea1-9adb-a79fb1dbc7b5
Attempt to cast to interface with iid 00020400-0000-0000-c000-000000000046
Attempt to cast to interface with iid d5d49c61-1c0b-4ea1-9adb-a79fb1dbc7b5
Attempt to cast to interface with iid d5d49c61-1c0b-4ea1-9adb-a79fb1dbc7b5
Attempt to cast to interface with iid 8560cecd-dfac-4f7b-9d2a-e6d9810f3443
Attempt to cast to interface with iid 8560cecd-dfac-4f7b-9d2a-e6d9810f3443
这为我们提供了接口的GUID,VS试图将其转换为我们的类。 现在,我们可以使用以下类从GUID中检索实际类型。
正如七人所说,简陋,但有效。
public static class Util
{
private static Dictionary<string, Type> guidMap;
static Util()
{
guidMap = new Dictionary<string, Type>();
AppDomain.CurrentDomain.AssemblyLoad += (s, e) =>
{
try
{
_ScanAssembly(e.LoadedAssembly);
}
catch
{
}
};
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
_ScanAssembly(a);
}
catch
{
}
}
}
private static void _ScanAssembly(Assembly a)
{
foreach (Type t in a.GetTypes())
{
var attrs = t.GetCustomAttributes<GuidAttribute>(false);
foreach (var item in attrs) {
if (!guidMap.ContainsKey(item.Value.ToLower()))
guidMap.Add(item.Value.ToLower(), t);
}
}
}
public static Dictionary<string, Type> GuidMap
{
get
{
return guidMap;
}
}
}
现在,我们可以以一些不同的方式实现ICustomQueryInterface:
public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv)
{
if (Util.GuidMap.ContainsKey(iid.ToString().ToLower()))
{
Type t = Util.GuidMap[iid.ToString()];
Debug.WriteLine(String.Format("Attempt to cast to interface {0}", t.ToString()));
}
else
Debug.WriteLine(String.Format("Attempt to cast to interface with iid {0}", iid));
ppv = IntPtr.Zero;
return CustomQueryInterfaceResult.NotHandled;
}
结果更加有用:
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsDeferredDocView
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData2
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData2
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData2
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData
Attempt to cast to interface System.Runtime.InteropServices.NativeMethods+IDispatch
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData
Attempt to cast to interface Microsoft.VisualStudio.Shell.Interop.IVsPersistDocData
Attempt to cast to interface Microsoft.VisualStudio.TextManager.Interop.SVsCodeWindow
Attempt to cast to interface Microsoft.VisualStudio.TextManager.Interop.SVsCodeWindow
现在,我将尝试确定哪些接口是必需的,哪些是可选的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.