我移植一个小型控制台应用程序,删除磁盘上不在Visual Studio项目中的文件。此代码在Visual Studio 2013中有效,但我在Visual Studio 2017中运行时收到以下错误:
System.Runtime.InteropServices.COMException:'邮件过滤器 表示应用程序正忙。 (HRESULT的例外情况: 0x8001010A(RPC_E_SERVERCALL_RETRYLATER))'
当前代码:
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;
}
while (!dte.Solution.IsOpen)
行引发异常。我尝试对其进行评论,然后将其放在foreach (Project project in dte.Solution.Projects)
行上。
注意:
答案 0 :(得分:5)
使用CoRegisterMessageFilter function注册的IOleMessageFilter的实现必须位于STA公寓线程中。
来自CoRegisterMessageFilter功能文档:
每个线程只能注册一个消息过滤器。线程在 多线程公寓不能有消息过滤器。
您的问题表明您正在移植一个小型控制台应用程序,并表示您正在使用C#。我不确切知道移植意味着什么,但如果原始代码在VB.Net中,VB.Net会自动将控制台应用程序标记为STAThreadAttribute,而C#不会因此,线程是在MTA线程中创建的。
在C#中,您将属性应用于输入方法(Main
),如下所示。
namespace ConsoleApp1
{
class Program
{
[STAThread]
static void Main(string[] args)
{
}
}
}