В чем отличие UseShellExecute?

Я запускаю небольшое консольное приложение из своего веб-приложения IIS. Код запускается из пула приложений, используя такой код:

Process process = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo();

processStartInfo.CreateNoWindow = true;
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

//..

process.Start();

Раньше я периодически получал ошибку,

Win32Exception exception has occured  Message: No such interface supported
ErrorCode: 80004005  NativeErrorCode: 80004002

Я доказал, что когда это происходило, консольное приложение вообще не запускалось.

Я добавил к приведенному выше коду

processStartInfo.UseShellExecute = false;

И проблема исчезла (до сих пор,скрестим пальцы ). Я понимаю, что при внесении этого изменения для запуска не требуется действительный контекст рабочего стола, но что именно это означает. Если это означает, что мы не можем запустить приведенный выше код, если нет рабочего стола (, который применяется к пулу приложений IIS, работающему с системным пользователем ), то почему в прошлом он иногда запускался, а не каждый раз?

Кто-нибудь знает, почему это может изменить ситуацию? Что означает отсутствие поддерживаемого интерфейса в этом контексте?

ОБНОВЛЕНИЕ:

Я принял к сведению все, что сказали люди, и сам провел дополнительные исследования. Таким образом, если у вас есть UseShellExecute = true (, что является значением по умолчанию ), тогда он вызовет ShellExecuteEX в shell32.dll для выполнения процесса. Это будет сделано на самом деле (, скопированном из System.dll с помощью ILSpy ),

public bool ShellExecuteOnSTAThread()
{
    if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
    {
        ThreadStart start = new ThreadStart(this.ShellExecuteFunction);
        Thread thread = new Thread(start);
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
    }
    else
    {
        this.ShellExecuteFunction();
    }
    return this._succeeded;
}

Если у вас UseShellExecute = false, тогда он вызовет CreateProcess в kernel32.dll, чтобы запустить процесс.

Мне интересно, есть ли проблема с тем фактом, что приведенный выше код ShellExecuteOnSTAThread создает новый поток? Может ли пул приложений достичь некоторого ограничения на потоки, которые могут косвенно вызвать исключение Win32Exception?

6
задан peter 20 April 2012 в 03:14
поделиться