C# 在IDE中打开模式对话框时,访问Visual Studio DTE成员将挂起
在下面的代码中,我试图访问有效的C# 在IDE中打开模式对话框时,访问Visual Studio DTE成员将挂起,c#,visual-studio,debugging,freeze,envdte,C#,Visual Studio,Debugging,Freeze,Envdte,在下面的代码中,我试图访问有效的DTE2对象的Debugger属性(通过类似的方法获得),以检查它是否正在调试当前进程(可能会打开多个Visual Studio实例) 它工作得很好,除了当其中一个Visual Studio(2015)实例显示模式对话框(例如,询问当前加载的项目的源代码是否应由于背景代码更改而重新加载)时,访问dte.Debugger将挂起,直到用户处理该对话框。试图访问dte对象的其他成员也将挂起 using System.Runtime.InteropServices; us
DTE2
对象的Debugger
属性(通过类似的方法获得),以检查它是否正在调试当前进程(可能会打开多个Visual Studio实例)
它工作得很好,除了当其中一个Visual Studio(2015)实例显示模式对话框(例如,询问当前加载的项目的源代码是否应由于背景代码更改而重新加载)时,访问dte.Debugger将挂起,直到用户处理该对话框。试图访问dte
对象的其他成员也将挂起
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Threading;
using EnvDTE;
using EnvDTE80;
using EnvDTE90a;
public static class VSAutomation {
public static int? GetCurrentDebuggerPid() {
var taskCompletion = new TaskCompletionSource<int?>();
var staThread = new System.Threading.Thread(() => {
try {
int? debuggerPid = null;
using (new MessageFilter()) {
using (var currentProcess = System.Diagnostics.Process.GetCurrentProcess())
using (var vsInstances = System.Diagnostics.Process.GetProcessesByName("devenv").AsDisposable()) {
foreach (var p in vsInstances.Enumerable) {
DTE2 dte;
if (TryGetVSInstance(p.Id, out dte)) {
Utils.Retry(() => {
var debugger = dte.Debugger; //MAY HANG HERE
if (debugger != null) {
foreach (Process2 process in debugger.DebuggedProcesses) {
if (process.ProcessID == currentProcess.Id) {
debuggerPid = p.Id;
break;
}
}
}
Marshal.ReleaseComObject(dte);
}, nbRetries: int.MaxValue, msInterval: 1000, retryOnlyOnExceptionTypes: typeof(COMException).InArray());
if (debuggerPid != null) break;
}
}
}
}
taskCompletion.SetResult(debuggerPid);
}
catch (Exception ex) {
taskCompletion.TrySetException(ex);
}
}) { IsBackground = true };
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
taskCompletion.Task.Wait();
return taskCompletion.Task.Result;
}
}
使用System.Runtime.InteropServices;
使用System.Runtime.InteropServices.ComTypes;
使用系统线程;
使用EnvDTE;
使用EnvDTE80;
使用EnvDTE90a;
公共静态类自动化{
公共静态int?GetCurrentDebuggerPid(){
var taskCompletion=new TaskCompletionSource();
var statthread=新系统.Threading.Thread(()=>{
试一试{
int?debuggerPid=null;
使用(new MessageFilter()){
使用(var currentProcess=System.Diagnostics.Process.GetCurrentProcess())
使用(var vsInstances=System.Diagnostics.Process.GetProcessesByName(“devenv”).AsDisposable()){
foreach(vsInstances.Enumerable中的var p){
DTE2-dte;
if(TryGetVSInstance(p.Id,out dte)){
Utils.Retry(()=>{
var debugger=dte.debugger;//可能挂在这里
if(调试器!=null){
foreach(调试器.DebuggedProcesses中的Process2进程){
if(process.ProcessID==currentProcess.Id){
debuggerPid=p.Id;
打破
}
}
}
元帅发布对象(dte);
},nbRetries:int.MaxValue,msInterval:1000,retryOnlyOnExceptionTypes:typeof(COMException.InArray());
如果(debuggerPid!=null)中断;
}
}
}
}
taskCompletion.SetResult(debuggerPid);
}
捕获(例外情况除外){
任务完成。TrySetException(ex);
}
}){IsBackground=true};
SetApartmentState(ApartmentState.STA);
statthread.Start();
taskCompletion.Task.Wait();
返回taskCompletion.Task.Result;
}
}
尽管模式对话框已打开,但是否有任何方法可以访问调试器对象
如果没有,除了在有超时的任务中启动赋值var debugger=dte.debugger
之外,还有什么方法可以检测到需要用户操作吗?嘿,你有没有解决过这个问题?我也有类似的问题@SyntaxError不,很遗憾我没有。@SyntaxError如果可能的话,你真的需要更新到VS 2019,他们确实做了很多改进。我同时有两个版本,但仍在处理一些不会(尚未)在VS2019中构建的旧项目