Php

PHP exec() 在 Windows 上的 UNC 路徑

  • March 23, 2016

我的環境是 Windows Server 2012 R2、IIS 8、Active Directory 和文件共享。IIS、AD 和文件共享都是獨立的 VM。

我在 IIS 中設置了一個網站 www.example.com。應用程序池標識設置為 AD 使用者IUSR_example,該使用者對包含站點文件的文件夾具有“完全控制”權限。站點文件位於文件共享上,IIS 通過 UNC 路徑引用該文件共享。

通常,該站點的工作原理是它可以提供 PHP、ASP.Net 和 ASP Classic 頁面,並且程式碼甚至可以創建新文件。

但是,我遇到了一個似乎特定於 PHP 的問題exec()。我試過打電話給whoami,dirffmpeg,但我沒有從他們那裡得到任何回報。使用 Sysinternals Procmon 我已經確認執行檔永遠不會啟動。

奇怪的是,我可以使用 ASP Classic(使用 )進行完全相同的呼叫WScript.Shell,而且效果很好。exec()當腳本不在 UNC 路徑上執行時, 我也可以讓 PHP正常工作。

這是我嘗試/發現的:

  • 使用 ASP 時,procmon 報告 w3wp.exe 生成一個 cmd.exe 程序,該程序又生成 conhost.exe 和(例如)ffmpeg.exe。ffmpeg 的輸出文件成功出現。
  • 使用 PHP 時,procmon 報告 w3wp.exe 生成一個 php-cgi.exe 程序,該程序又創建一個 cmd.exe 和一個 conhost.exe。ffmpeg.exe 的執行緒永遠不會出現。
  • cmd.exe 使用如下所示的命令行呼叫: cmd.exe /c ""--the command to be executed--""
  • 對於 ASP Classic 和 PHP,cmd.exe 程序的命令行完全相同。
  • 在 Procmon 中,使用者總是被報告為IUSR_example
  • 我試過添加2>&1到命令的末尾
  • 我已經嘗試將 IUSR 賦予“替換程序級令牌”的權利
  • 我嘗試關閉 FastCGI 模擬並在“程序模型”>“高級設置”下的“NamedPipe”和“TCP”之間切換
  • PHP 錯誤日誌中沒有錯誤
  • 任何 Windows 事件日誌中都沒有錯誤

請注意,這並不特定於 ffmpeg。的任何其他使用exec()也會失敗。另外,我不希望WScript.Shell在 PHP 中使用,因為最終我們將使用依賴exec().

我該如何進一步解決這個問題?

正如使用者“pajoye”在 bugs.php.net 上所建議的那樣,使用允許proc_open()我成功執行命令。這反過來又讓我可以使用 procmon 來發現方式exec()proc_open()工作之間的區別。長話短說,當 PHP 腳本位於網路共享上時,我將其稱為在 Windows 上執行的 PHP 的核心錯誤。以下是關鍵細節:

  • exec()預設目前工作目錄為 PHP 腳本的路徑,在我的例子中是一個 UNC 路徑。
  • cmd.exe不允許您將 UNC 路徑作為目前工作目錄,並cmd.exe聲稱它將恢復到 Windows 文件夾。
  • 儘管cmd.exe繼續執行並conhost.exe生成,但原始工作目錄仍然會導致某種問題,並且從未啟動所需的執行檔。

所以一個簡單的解決方法是chdir()在呼叫exec(). 但是,有很多 WordPress 外掛依賴於exec(),所以我認為exec()應該不知道 PHP 腳本是否在共享上執行。我會詢問是否可以在未來的版本中包含對此的修復。

引用自:https://serverfault.com/questions/765425