#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 рассматривались только варианты использования консольных приложений, поэтому тот факт, что мы не можем использовать его из приложения с графическим интерфейсом, вероятно, не является приоритетом.