Почему WslApi внезапно перестал работать в приложениях WPF

#c# #wpf #windows-subsystem-for-linux

#c# #wpf #windows-subsystem-for-linux

Вопрос:

При попытке получить доступ к дистрибутиву WSL через wslapi в приложении WPF это указывает на то, что дистрибутив не зарегистрирован, хотя он определенно зарегистрирован. (Например, я могу запустить его из powershell и т. Д.)

Проблема, похоже, возникает только в приложениях WPF (или, по крайней мере, она не возникает в консольных приложениях).

Эта проблема внезапно появилась два дня назад, когда раньше ее не было.

У меня есть программа, которая взаимодействует с пользовательским дистрибутивом Linux в WSL. Дистрибутив не важен; важно вот что:

Программа при запуске использует wslapi (импорт dll), чтобы определить, установлен ли дистрибутив. Если он установлен, то он запускает программу. Если нет, он перенаправляется к мастеру для загрузки дистрибутива wsl.

Пару дней назад УСТАНОВЛЕННАЯ версия программы (поэтому мы НЕ говорим об изменениях кода) внезапно перестала обнаруживать, что установлен дистрибутив WSL. На это указывает всегда перенаправление к мастеру, даже если дистрибутив установлен.

С тех пор я смог сузить обстоятельства сбоя при обнаружении установки до случаев, когда я НЕ в консольном приложении.

Для устранения неполадок я создал единую библиотеку классов WslLink, в которой есть класс WslService, который выполняет этот код, чтобы определить, зарегистрирован ли дистрибутив:

 [DllImport("wslapi.dll", CharSet = CharSet.Unicode)]
public static extern bool WslIsDistributionRegistered(string distributionName);

...

bool IsInstalled() 
{
    var isRegistered = WslIsDistributionRegistered("MyLinux");
    return isRegistered;
}
  

Это тот же код, который работал в установленном приложении до двух дней назад.

В простом приложении .NET Framework WPF, которое обновляет описанный выше проект WslLink, у меня есть следующий код в App.OnStartup() (после удаления параметра StartupUri из xaml):

     var wslService = new WslService();

    if (wslService.IsInstalled())
    {
        MessageBox.Show("The MyLinux is installed");
    }
    else
    {
        MessageBox.Show("The MyLinux is not installed");
    }
  

Этот код выводит окно сообщения с надписью «MyLinux не установлен», что указывает на то, что дистрибутив не зарегистрирован в соответствии с wslapi.

В аналогичном консольном приложении .NET Framework в том же решении и ссылающемся на тот же проект WslLink, у меня есть:

     var wslService = new WslService();

    if (wslService.IsInstalled())
    {
        Console.WriteLine("The MyLinux is installed");
    }
    else
    {
        Console.WriteLine("The MyLinux is not installed");
    }
  

Выводится сообщение «Установлен MyLinux», указывающее, что дистрибутив зарегистрирован в соответствии с wslapi.

Ну, либо дистрибутив зарегистрирован, либо нет, и, исходя из того факта, что я могу запустить его из powershell, а команды типа wslconfig /l показывают дистрибутив, это явно так.

Однако в любом случае, поскольку консольное приложение и приложение wpf используют ОДНУ и ту же БИБЛИОТЕКУ КЛАССОВ для вызова проверки регистрации wslapi, я бы ожидал, что оба они дадут одинаковый результат — либо оба говорят «не установлено», либо оба говорят «установлено».

Но вместо этого приложение wpf всегда не обнаруживает установку, а консольное приложение всегда обнаруживает установку.

Для повторной итерации (я очень сильно бьюсь в этот барабан, потому что это просто не имеет смысла): УСТАНОВЛЕННОЕ приложение wpf, которое выполняло идентичный код, работало в течение нескольких месяцев, а затем внезапно, пару дней назад, оно перестало работать. Я не говорю о переустановке или о чем-то подобном. Я говорю о том, чтобы однажды запустить его, и вдруг он больше не обнаруживает установку.

Кто-нибудь знает что-нибудь, что могло измениться в Windows, чтобы вызвать это?

Комментарии:

1. Я не уверен в этом, но попробуйте. Можете ли вы проверить, запущена ли служба LxssManager, прежде чем вызывать этот WSL API? Код будет выглядеть так: «если запущена служба LxssManger, вызовите этот API, если нет, запустите службу, затем вызовите API».

Ответ №1:

Я обнаружил, что автоматическое обновление Windows KB4493464 прерывает вызовы wslapi из приложений WPF. Вот почему установленная программа просто внезапно перестала работать. Я проверил это с помощью A / B / A тестирования (резервное копирование обновления для проверки, а затем его повторное применение).

Спасибо за предложение, @Biswapriyo, но LxssManager работал во всех случаях, поэтому консольное приложение могло работать корректно.

Я уведомил Microsoft, но я не ожидаю, что действия по исправлению этого в ближайшее время. Я уверен, что для этого API рассматривались только варианты использования консольных приложений, поэтому тот факт, что мы не можем использовать его из приложения с графическим интерфейсом, вероятно, не является приоритетом.