簡體   English   中英

UseShellExecute有什么區別?

[英]What Difference Does UseShellExecute Have?

我從我的IIS Web應用程序中啟動一個小型控制台應用程序。 代碼是使用這樣的代碼從應用程序池中啟動的,

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(這是默認值),那么它將調用shell32.dll中的ShellExecuteEX來執行該過程。 它實際上會這樣做(使用ILSpy從System.dll復制),

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,那么它將調用kernel32.dll中的CreateProcess來啟動該進程。

我想知道上面的代碼ShellExecuteOnSTAThread創建一個新線程是否存在問題? 應用程序池是否可以在線程上達到某些限制,這可能會間接導致Win32Exception?

當某些COM對象沒有注冊時會發生此錯誤,盡管這對我來說有點神秘,為什么它是間歇性的。

但公平地說,從IIS中生成本地可執行文件是一件非常罕見的事情,它實際上可能會導致安全問題,或者至少導致IIS出現問題,如果命令由於某種原因而失敗並且無法控制到系統。

實際上,類似這樣的事情的最佳實踐是記錄您需要在注冊表,數據庫或某種設置文件中發生的操作,並將本地應用程序作為計划任務或Windows服務運行。

作為參考,UseShellExec說明內核是否應該直接啟動exe,或者它是否應該要求Explorer啟動該文件。

當沒有人登錄時你可能會遇到這個問題所以沒有必要加載shell來啟動exe。

但最終,你目前正在嘗試做的是生產中的一件壞事 - 你無法保證IIS在嘗試啟動這個exe時的狀態,因此,IIS不是Shell。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM