IIS+ php exec以使用WSL不起作用的Linux命令运行Linux命令

发布于 2025-02-02 11:10:44 字数 1552 浏览 3 评论 0原文

配置

  • Windows 11
  • IIS 10.0.22000.1
  • php 5.6.40(我知道,它是旧的,但是我不知道我的脚本将在哪里执行,所以我走了很广泛)
  • WSL已安装

上下文,

我试图编写runlinuxCommand < /代码>可以在Windows上运行(带有Windows子系统的Linux)或Linux(也许是Unix,也许是OSX)。

我对exec(“ dir”,$ result,$ code)返回$ code ==&gt; 1。然后,我更改了IIS中运行PHP的用户为我的当前登录用户(这是管理员)。我知道,这不是理想的,但是就目前而言,我想实现自己的目标。之后,我将尝试减少权利。而且...奏效了!

问题

因此,我尝试执行exec(“ wsl date”,$ result,$ code),但没有运气,仍然是1的退出代码。是的,打开命令提示符并执行WSL日期确实有效。使用登录的用户或作为管理员。

我目前唯一能看到的是初始化WSL需要太多时间,但完全不确定。

尝试

#1

“发行”部分中的

尝试#2

exec('C:\\ Windows \\ System32 \\ wsl.exe Date',$ result,$ code);

相同结果。

尝试#3

exec('start /b /wita c:\ windows \ system32 \ wsl.exe date',$ result,$ code); < /code>

挂起...永远不会通过此行。

尝试#4

exec('start /b /wait cmd /cc: \ \ windows \ system32 \ wsl.exe date',$ result,$ code); < /code>

no Orror。没有结果 /输出。

尝试#5

$WshShell = new \com("WScript.Shell");
$oExec = $WshShell->Exec("C:\\Windows\\System32\\wsl.exe date");
$out = $oExec->StdOut->ReadLine();

现在,运行第二行时,我会有一个特定的错误消息:未找到文件。我可以向您保证,存在c:\ Windows \ System32 \ wsl.exe存在。

我已经使用$ oexec = $ wshshell-&gt; run(“ whoami”,0,true);作为第二行,即用户是我登录的一个(管理员帐户,我可以使用终端测试)。

除了

我搜索了很多东西,我什么也没发现(好吧,我发现的一切都不具体)。

Configuration

  • Windows 11
  • IIS 10.0.22000.1
  • PHP 5.6.40 (I know, it's old, but I don't know where my script will be executed, so I went broad)
  • WSL installed

Context

I am trying to write a runLinuxCommand that would run either on Windows (with Windows Subsystem for Linux) or on Linux (and perhaps OSX as it is Unix like).

I had some issues with exec("dir", $result, $code) returning $code ==> 1. I then changed the user running PHP in IIS to be my current logged in user (which is an administrator). I know, this is not ideal, but for now, I want to reach my goal. I'll try to reduce rights afterward. And... it worked!

Issue

So, I tried to execute exec("wsl date", $result, $code), but no luck, still an exit code of 1. Yes, opening a command prompt and executing wsl date does work. Either with the logged in user or as administrator.

The only thing I can see for now is it takes too much time to initialize WSL, but quite not sure at all.

Attempts

Attempt #1

The one in the issue section

Attempt #2

exec('C:\\Windows\\System32\\wsl.exe date', $result, $code);

Same result.

Attempt #3

exec('start /B /WAIT C:\Windows\System32\wsl.exe date', $result, $code);

Hanging... never getting through this line.

Attempt #4

exec('start /B /WAIT cmd /C C:\\Windows\\System32\\wsl.exe date', $result, $code);

No error. No result / output.

Attempt #5

$WshShell = new \com("WScript.Shell");
$oExec = $WshShell->Exec("C:\\Windows\\System32\\wsl.exe date");
$out = $oExec->StdOut->ReadLine();

Now I have a specific error message when running the second line: File not found. I can assure you that C:\Windows\System32\wsl.exe exists.

I already confirmed using $oExec = $WshShell->Run("whoami", 0 , true); as second line that the user is the one I am logged in (an administrator account from which I can test using a terminal).

Aside

I searched a lot about it, and I found nothing (well, everything I found was not specific).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

很糊涂小朋友 2025-02-09 11:10:44

在32位PHP上的好发现是核心问题。

既然是这样,我相信您可以通过使用Windows Sysnative接口来解决它,该界面旨在允许您从32位应用程序中调用64位应用程序。

从32位PHP中,尝试启动c:\ windows \ sysnative \ wsl.exe&lt; garmuments&gt;。它在虚拟文件夹中,因此您将无法从普通的64位探险器或类似的情况下看到它。参见此答案
(和其他与Sysnative相关的答案)有关更多详细信息。

Good find on 32-bit PHP being the core issue.

Since that's the case, I believe you can work around it quite simply by using the Windows Sysnative interface, which is designed to allow you to call 64-bit applications from within 32-bit applications.

From the 32-bit PHP, try launching C:\Windows\Sysnative\wsl.exe <arguments>. It's in a virtual folder, so you won't be able to see it from a normal 64-bit Explorer or similar. See this answer
(and other sysnative related answers) for more details.

拥醉 2025-02-09 11:10:44

因此,经过一些磨难,我发现这个问题来自PHP 32位版本。使用64位版本调用exec('wsl date',$ result,$ code);正常工作。

因此,对于对我构建的课程感兴趣的人:

class Host {
    private function __construct() {}
    
    /**
     * Get if the host is Windows
     * @return boolean
     */
    public static function isWindows() {
        $uname = strtolower(php_uname('s'));
        return strpos($uname, "win") === 0;
    }
    
    /**
     * Get if PHP is 64 bits or not (32 bits)
     * @ref https://code-boxx.com/check-php-version/#:~:text=To%20check%20if%20you%20are,and%208%20for%2064%2Dbit.
     * @return boolean
     */
    public static function isPhp64bits() {
        if (isset($_SERVER["PROCESSOR_ARCHITECTURE"])) {
            // Windows IIS validation
            return $_SERVER["PROCESSOR_ARCHITECTURE"] != "x86";
        }
        return PHP_INT_SIZE == 8;
    }
    
    public static function runLinuxCommand($command) {
        if (self::isWindows()) {
            if (self::isPhp64bits()) {
                $wslExecutor = "wsl";
            } else {
                $wslExecutor = "C:\\Windows\\Sysnative\\wsl.exe";
            }
            $command = "$wslExecutor $command";
        } else {
            putenv('LANG=en_US.UTF-8'); // Ensure the output is UTF-8
        }
        
        $result = [];
        $exitCode = -1;
        exec($command, $result, $exitCode);
        
        return new ExecReturn($result, $exitCode);
    }
}

这不再需要
对于Wslexecutor软件,很简单,但无论如何:
https://github.com/djon2003/wslexececor

我知道,我知道,框架呼叫不包括,框架呼叫,但是我不会发布整个框架。此外,它们是可以轻松实施的方法。

编辑#1

在notthedr01ds的帮助下,我不再需要C#软件WslexeCutor。

So, after some tribulations, I figured out the issue was coming from the PHP 32 bits version. Using the 64 bits version calling exec('wsl date', $result, $code); works perfectly.

So, for those interested in the class I built:

class Host {
    private function __construct() {}
    
    /**
     * Get if the host is Windows
     * @return boolean
     */
    public static function isWindows() {
        $uname = strtolower(php_uname('s'));
        return strpos($uname, "win") === 0;
    }
    
    /**
     * Get if PHP is 64 bits or not (32 bits)
     * @ref https://code-boxx.com/check-php-version/#:~:text=To%20check%20if%20you%20are,and%208%20for%2064%2Dbit.
     * @return boolean
     */
    public static function isPhp64bits() {
        if (isset($_SERVER["PROCESSOR_ARCHITECTURE"])) {
            // Windows IIS validation
            return $_SERVER["PROCESSOR_ARCHITECTURE"] != "x86";
        }
        return PHP_INT_SIZE == 8;
    }
    
    public static function runLinuxCommand($command) {
        if (self::isWindows()) {
            if (self::isPhp64bits()) {
                $wslExecutor = "wsl";
            } else {
                $wslExecutor = "C:\\Windows\\Sysnative\\wsl.exe";
            }
            $command = "$wslExecutor $command";
        } else {
            putenv('LANG=en_US.UTF-8'); // Ensure the output is UTF-8
        }
        
        $result = [];
        $exitCode = -1;
        exec($command, $result, $exitCode);
        
        return new ExecReturn($result, $exitCode);
    }
}

This is no more needed :
For the WSLExecutor software, quite simple, but anyhow:
https://github.com/djon2003/WSLExecutor

I know, the framework calls aren't included, but I won't post the whole framework. Moreover, they are methods that can be easily implemented.

Edit #1

With the help of NotTheDr01ds, I no more need the C# software WSLExecutor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文