[英]Visual Studio 2017 - Message filter indicated that the application is busy
I'm porting over a small console application that deletes files on disk that are not in a Visual Studio project.我正在移植一个小型控制台应用程序,该应用程序删除磁盘上不在 Visual Studio 项目中的文件。 This code worked in Visual Studio 2013, but I'm receiving the following error when I ran it in Visual Studio 2017:
此代码在 Visual Studio 2013 中有效,但在 Visual Studio 2017 中运行时收到以下错误:
System.Runtime.InteropServices.COMException: 'The message filter indicated that the application is busy.
System.Runtime.InteropServices.COMException: '消息过滤器表明应用程序正忙。 (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))'
(来自 HRESULT 的异常:0x8001010A (RPC_E_SERVERCALL_RETRYLATER))'
Current Code:当前代码:
public static int DeleteFilesNotInProject(string solutionFileAndPath, string projectName, string extension)
{
var returnValue = 0;
EnvDTE80.DTE2 dte;
// Targets Visual Studio 2017
dte = (EnvDTE80.DTE2)Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.DTE.15.0", true), true);
MessageFilter.Register();
System.Threading.Thread.Sleep(2000);
while (!dte.Solution.IsOpen)
{
// make sure it is ready to open
System.Threading.Thread.Sleep(500);
dte.Solution.Open(solutionFileAndPath);
}
dte.Solution.Open(solutionFileAndPath);
System.Threading.Thread.Sleep(5000);
foreach (Project project in dte.Solution.Projects)
{
if (project.UniqueName.EndsWith(projectName))
foreach (string s in GetFilesNotInProject(project, extension))
{
FileInfo fi = new FileInfo(s);
File.SetAttributes(s, FileAttributes.Normal);
File.Delete(s);
returnValue++;
}
}
dte.Quit();
MessageFilter.Revoke();
return returnValue;
}
The exception is thrown on the while (!dte.Solution.IsOpen)
line.在
while (!dte.Solution.IsOpen)
行上抛出异常。 I tried commenting that out and then it is thrown on the foreach (Project project in dte.Solution.Projects)
line instead.我尝试将其注释掉,然后将其抛出到
foreach (Project project in dte.Solution.Projects)
行上。
Notes:笔记:
The implementation of the IOleMessageFilter registered using the CoRegisterMessageFilter function must be in a STA apartment thread. 使用CoRegisterMessageFilter函数注册的IOleMessageFilter的实现必须在STA单元线程中。
From the CoRegisterMessageFilter function documentation: 从CoRegisterMessageFilter函数文档中:
Only one message filter can be registered for each thread.
每个线程只能注册一个消息过滤器。 Threads in multithreaded apartments cannot have message filters.
多线程单元中的线程不能具有消息过滤器。
Your question stated that you are porting over a small console application and indicates that you are using C#. 您的问题表明您正在移植一个小型控制台应用程序,并表明您正在使用C#。 I don't know exactly what porting implies, but if the original code was in VB.Net, VB.Net automatically marks Console applications with the STAThreadAttribute where-as C# does not and as such the thread is created in a MTA thread.
我不确切知道移植的含义,但是如果原始代码在VB.Net中,则VB.Net会自动使用STAThreadAttribute标记控制台应用程序,而C#则不会,因此该线程是在MTA线程中创建的。
In C#, you apply the attribute to the entry method ( Main
) as shown below. 在C#中,将属性应用于输入方法(
Main
),如下所示。
namespace ConsoleApp1
{
class Program
{
[STAThread]
static void Main(string[] args)
{
}
}
}
So I had a similar issue to this question.所以我对这个问题有类似的问题。 I added the STAThread attribute as directed in the accepted answer but in addition to getting the
RPC_E_SERVERCALL_RETRYLATER
exception, I also got the RPC_E_CALL_REJECTED
exception as well.我按照接受的答案中的指示添加了 STAThread 属性,但除了获得
RPC_E_SERVERCALL_RETRYLATER
异常之外,我还获得了RPC_E_CALL_REJECTED
异常。 After some googling I came across the following MS document:经过一番谷歌搜索后,我发现了以下 MS 文档:
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ms228772(v=vs.100)?redirectedfrom=MSDN https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ms228772(v=vs.100)?redirectedfrom=MSDN
The above doc from MS states that to avoid these errors we can implement a COM message filter (IOleMessageFilter) that simply tells the COM interface to retry if we get the RPC_E_CALL_REJECTED
message and wait if we get RPC_E_SERVERCALL_RETRYLATER
message.来自 MS 的上述文档指出,为了避免这些错误,我们可以实现一个 COM 消息过滤器 (IOleMessageFilter),它只是告诉 COM 接口在我们收到
RPC_E_CALL_REJECTED
消息时重试,并在我们收到RPC_E_SERVERCALL_RETRYLATER
消息时等待。
Hope this helps someone who is lost.希望这对迷路的人有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.