File.Exists возвращает false,Process.Start() не может запустить файл, но он действительно существует

Примечание. На моем компьютере включена песочница Windows.

Console.WriteLine(File.Exists(@"C:\Windows\system32\WindowsSandbox.exe"));
Console.WriteLine(new FileInfo(@"C:\Windows\system32\WindowsSandbox.exe").Exists);

Запуск приведенного выше кода в C# Interactive(VS не в режиме администратора):

True
True

Однако, когда я запускаю его в консольном приложении (как в режиме администратора, так и в режиме без прав администратора), результаты всегда ложны.

False
False

Я попытался Process.Start(@"C:\Windows\system32\WindowsSandbox.exe"), консольное приложение завершилось неудачно (администратор и не админ), но интерактивный C# завершился успешно.

В PowerShellC:\Windows\system32\WindowsSandbox.exeуспешно запустил Windows Sandbox. В проводнике (папка system32): изображение

Может ли кто-нибудь объяснить, почему это могло произойти?

2 ответа

Решение

Я не знаком с Windows Sandbox, но похоже, что это проблема архитектуры.

В 64-битной Windows C:\Windows\system32это 64-битный системный каталог. Explorer и PowerShell, которые, как вы говорите, могут видетьC:\Windows\system32\WindowsSandbox.exe, будут 64-битными процессами, если вы не изо всех сил будете запускать 32-битные версии.

В 32-битном приложении путь C:\Windows\system32получает перенаправляется в каталог 32-битной системы,C:\Windows\SysWOW64. Поскольку вы говорите, что у вас нетC:\Windows\SysWOW64\WindowsSandbox.exe файл, и ваше приложение не может видеть (то, что оно считает) C:\Windows\system32\WindowsSandbox.exe файл, который предполагает, что ваше приложение создано для 32-разрядной версии.

Итак, проблема в том, что нет 32-битной версии Windows Sandboxдля запуска вашего 32-битного приложения. Когда вы меняете путь наcalc.exe или notepad.exeваш же код работает, потому что Windows предоставляет как 32-, так и 64-разрядные версии этих исполняемых файлов. Чтобы ваше приложение запускало 64-битнуюWindowsSandbox.exe, вы также можете...

  • Создайте его для 64-битной версии или еще лучше...
  • Пусть он выполнит путь C:\Windows\sysnative\WindowsSandbox.exe. sysnative - это специальный псевдоним, который позволяет 32-битным приложениям ссылаться на собственный (64-битный) системный каталог без перенаправления.

Что касается того, почему Visual Studio может видеть C:\Windows\system32\WindowsSandbox.exe, Я не могу этого объяснить. Это будет зависеть от того, какую версию вы используете, но, насколько я понимаю, приложение остается 32-битным, хотя было бы разумно, если бы некоторые компоненты были 64-битными. Что касается того, будут ли такие компоненты, как отладчик, работать с той же архитектурой, что и ОС или создаваемое приложение, я действительно не знаю.

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

Метод Exists возвращает false, если возникает какая-либо ошибка при попытке определить, существует ли указанный файл. Это может произойти в ситуациях, которые вызывают исключения, такие как передача имени файла с недопустимыми символами или слишком большим количеством символов, неисправный или отсутствующий диск или если у вызывающего абонента нет разрешения на чтение файла.

Один из способов увидеть, что происходит, - просто попытаться прочитать файл (например, с помощью File.OpenRead). Я был бы удивлен, если это удастся, но если это не удастся, исключение должно предоставить вам дополнительную информацию. Также проверьте из вызова, какой идентификатор используется при запуске команды (т.е.cmd whoami, так далее.)

Другие вопросы по тегам