Что именно делает System.Diagnostics.Process UseShellExecute?

У меня есть задача MSBuild, которая выполняет (помимо прочего) вызов xcopy. Я обнаружил, что этот вызов xcopy выполняется правильно, когда я запускаю задачу MSBuild из командного файла и не могу выполнить или произвести какой-либо вывод, который позволил бы мне понять, что происходит, когда тот же командный файл вызывается из другого C # с System.Diagnostics.Process.

Оба процесса запускаются с более или менее одинаковой структурой:

waitProc.StartInfo.Arguments = "/C [executable]"; waitProc.StartInfo.FileName = "cmd.exe"; waitProc.StartInfo.UseShellExecute = false; 

Кроме того, изменив значение «UseShellExecute» с false на true в команде xcopy, я могу сделать это успешным в обоих случаях использования, однако команда не запускается в третьем случае использования. Третий вариант использования – наша автоматическая система сборки, которая является службой Windows, вызывающей msbuild напрямую. В случае сбоя на нашей машине для сборки команда копирования зависает бесконечно, что, я считаю, связано с тем, что System.Diagnostics.Process пытается отобразить окно, а службы не имеют сеанса рабочего стола Windows, связанного с ними, поэтому они не могут windows дисплея.

Я попытался использовать свойство «CreateNoWindow», и я попытался настроить «WindowStyle» на «ProcessWindowStyle.Hidden», но это не меняет поведение на машине сборки.

Все это говорит о том, что я действительно хочу знать о том, что именно имеет свойство UseShellExecute, потому что, похоже, это намного больше, чем предлагает документация MSDN.

Благодарю.

ProcessStartInfo.UseShellExecute сообщает процессу использовать оболочку Windows для выполнения указанного приложения.

Без этого набора вы можете напрямую запускать EXE-файл. Установив это, вы разрешаете использовать оболочку Windows, которая позволяет такие вещи, как указание файла .doc и наличие связанной программы, открыть файл.

Однако использование Windows Shell требует действительного контекста рабочего стола, поэтому ваш третий вариант использования не работает.

В общем случае использование cmd.exe проблематично, если вы не используете оболочку Windows. Вы можете просто написать код для обработки вашей «пакетной» операции напрямую, т. Е. Использовать методы из типов в пространстве имен System.IO для копирования. Это позволит полностью избежать этой проблемы.

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

Установка этого свойства в значение false позволяет перенаправить stream ввода, вывода и ошибок.

Примечание. UseShellExecute должно быть ложным, если свойство UserName не является пустой ссылкой (Nothing in Visual Basic) или пустой строкой, или InvalidOperationException будет вызываться при вызове метода Process.Start (ProcessStartInfo). Когда вы используете оболочку операционной системы для запуска процессов, вы можете запустить любой документ (который представляет собой любой зарегистрированный тип файла, связанный с исполняемым файлом, который имеет открытое действие по умолчанию) и выполнять операции над файлом, например печать, с помощью компонента Process. Когда UseShellExecute является ложным, вы можете запускать только исполняемые файлы с компонентом Process.

Примечание. UseShellExecute должен быть истинным, если для свойства ErrorDialog установлено значение true. Свойство WorkingDirectory ведет себя по-разному, когда UseShellExecute истинно, чем когда UseShellExecute является ложным. Когда UseShellExecute истинно, свойство WorkDirectory указывает местоположение исполняемого файла. Если WorkDirectory является пустой строкой, в текущем каталоге понимается исполняемый файл.

Когда UseShellExecute является ложным, свойство WorkDirectory не используется для поиска исполняемого файла. Вместо этого он используется процессом, который запускается и имеет смысл только в контексте нового процесса.

Использование «UseShellExecute» IIRC, позволяет обозревателю (основной оболочке) выполнять этот процесс, а не .NET runtime …. если кто-то не исправляет меня, что я ошибаюсь …

Вы правильно указали WorkDirectory? Вы можете увидеть фактический вывод своей команды, добавив >c:\log.txt 2>c:\err.txt запустите это добавление и проверьте эти файлы