2015-10-09 3 views
12

От MSDN:В каких случаях метод Process.Start() возвращает false?

Возвращаемое значение верно указывает на то, что новый ресурс процесс был начал. Если ресурс процесса, заданный членом FileName из , свойство StartInfo уже запущено на компьютере, нет запускается дополнительный ресурс процесса. Вместо этого ресурс запущенного процесса повторно используется и возвращается false.

Пытаясь что-то вроде этого:

var info = new ProcessStartInfo {FileName = @"CMD"}; 

var p1 = new Process 
{ 
    StartInfo = info 
}; 

var result = p1.Start(); //true 
result = p1.Start(); //true 

var p2 = new Process 
{ 
    StartInfo = info 
}; 

result = p2.Start(); //true 

тот же результат, если я использую FilePath = @"c:\myapp.exe" вместо CMD.

В каких случаях он возвращает false?

+0

Возможный дубликат [Process.Start и выделенные ресурсы] (http://stackoverflow.com/questions/10884136/process-start-and-allocated-resources) – Sinatr

+0

FWIW, В зависимости от того, используете ли вы Shell Execute для начните процесс, вот фактический код, который его определяет: [Без выполнения оболочки] (http://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Process.cs,2167), [С помощью Shell Execute ] (http://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Process.cs,2278). –

ответ

9

Если вы посмотрите на опорный источник, вы увидите, как Process.Start работы:

http://referencesource.microsoft.com/System/R/c50d8ac0eb7bc0d6.html

Это один из двух методов, называемых при вызове Process.Start. Обратите внимание на нижнюю часть, где оно возвращает значение true или false. False возвращается только в том случае, если после запуска процесса он не может получить дескриптор процесса, который был запущен.

Для того, чтобы начать процесс, он использует NativeMethods.CreateProcess, которые вы можете найти источник здесь: http://referencesource.microsoft.com/System/compmod/microsoft/win32/NativeMethods.cs.html#9c52a5ca5f3eeea3

который является только метод прототипа для Kernel32.CreateProcess, которого API находится здесь: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

Если вы смотрите на возвращаемые значения, он говорит:

Если функция выполнена успешно, возвращаемое значение отличное от нуля. Если функция не работает, возвращаемое значение равно нулю.

Я не могу найти ничего в API для CreateProcess, что говорит, что это не работает, если запрашиваемый процесс уже запущен, возможно, если процесс не удалось запустить, поскольку это единственное приложение экземпляра (например, Outlook), то он может fail, но для приложений с несколькими экземплярами, таких как командная строка, он не должен создавать дескриптор процесса.

Итак, после того, как все говорят, что, возможно, что в документации MSDN это не совсем правильно, у меня нет ссылки у вас есть, но для Process.Start(StartInfo), MSDN говорит это о возвращаемом значении:

Новый процесс, связанный с ресурсом процесса, или null, если не запущен ресурс процесса. Обратите внимание, что новый процесс, который запускается рядом с уже запущенными экземплярами одного и того же процесса, будет независимым от других. Кроме того, Start может возвращать ненулевой процесс с свойством HasExited, уже установленным в true. В этом случае запущенный процесс может активировать существующий экземпляр самого себя, а затем выйти.

(Акцент, добавленный мной). Он не говорит, что вызов завершится неудачно, если он уже запущен.

Для Process.Start(), он говорит:

Возвращаемое значение Тип: System.Boolean верно, если запущен ресурс процесса; false, если новый ресурс процесса не запущен (например, если существующий процесс используется повторно).

Так говорит если существующий процесс повторно, это полностью зависит от приложения при старте или способа его запуска.

+0

Так в каких практических случаях это может быть неверно? Я попробовал как внешний вид, так и запуск службы Windows (например, Sql Server), все вернулось «True». – Vova

+0

@AlexK. Я думаю, что я исправил, что в конце редактирования добавится ссылка для метода экземпляра за секунду. –

+0

@Vova Возвращает false, когда не удается создать дескриптор процесса для процесса. Outlook может немного отличаться, поскольку это приложение с одним экземпляром, но создаст несколько окон. Я не уверен, что повторное использование происходит только тогда, когда «Процесс» используется как «Компонент» в приложении формы, например, я не запускал тесты кода для проверки лично. –

6

Вы можете технически получить false return при использовании ProcessStartInfo.UseShellExecute = true (по умолчанию), и вы запустите процесс, передав имя файла документа. И оболочка как-то может понять, чтобы передать запрос открытого документа на уже запущенный экземпляр процесса.

Единственный документированный случай этого - открытие веб-страницы в Internet Explorer. Могут быть и другие, возможно, имеющие какое-то отношение к устаревшей активации DDE. Это предположение.

В противном случае это конкретный случай общей проблемы с Process.Start(), существует множество приложений с одним экземпляром. Приложения Office являются наиболее распространенным примером. Наиболее типичным поведением, которое вы наблюдаете, является то, что процесс очень быстро заканчивается снова. Он только что обнаружил, что приложение уже запущено и использует процесс-interop, чтобы попросить запущенный экземпляр открыть документ. Вид функции также supported in .NET.

Вы не будете иметь ни малейшего представления, какой конкретный процесс, показывающий документ, если вы не знаете это приложение в единственном экземпляре и его имя процесса, так у вас есть какая-то надежда найти его обратно с Process.GetProcessesByName(). Это, однако, не безопасно, может быть несвязанный процесс, который имеет одно и то же имя. Преимущество получения false заключается в том, что вы знаете, что нет смысла ждать его завершения.

Смежные вопросы