Visual Studio 2017 - Фильтр сообщений показывает, что приложение занято - PullRequest
0 голосов
/ 12 мая 2018

Я портирую через небольшое консольное приложение, которое удаляет файлы на диске, которых нет в проекте Visual Studio.Этот код работал в Visual Studio 2013, но я получаю следующую ошибку при запуске в Visual Studio 2017:

System.Runtime.InteropServices.COMException: 'TheФильтр сообщений показал, что приложение занято.(Исключение из 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).

Примечания:

  • Код основан на этой статье MSDN .Я хочу сохранить это в консольном приложении.
  • Я обнаружил PowerShell и VS Addons / Extensions, но мне интересно сохранить этот класс C #, называемый в составе консольного приложения.
  • Я попытался использовать только EnvDTE вместо EnvDTE80, но получил ту же ошибку.

1 Ответ

0 голосов
/ 12 мая 2018

Реализация IOleMessageFilter, зарегистрированного с использованием функции CoRegisterMessageFilter , должна находиться в потоке квартиры STA.

Из документации по функции CoRegisterMessageFilter:

Только одинФильтр сообщений может быть зарегистрирован для каждой темы.Потоки в многопоточных квартирах не могут иметь фильтры сообщений.

В вашем вопросе указано, что вы портируете через небольшое консольное приложение и указывает, что вы используете C #.Я не знаю точно, что подразумевает перенос , но если исходный код был в VB.Net, VB.Net автоматически помечает консольные приложения с помощью STAThreadAttribute , где C # не делает икак таковой поток создается в потоке MTA.

В C # вы применяете атрибут к методу ввода (Main), как показано ниже.

namespace ConsoleApp1
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
        }
    }
}
...