【问题标题】:system() call returns "Permission Denied" on Windows XPsystem() 调用在 Windows XP 上返回“Permission Denied”
【发布时间】:2011-02-08 14:40:32
【问题描述】:

我在 Windows XP 上运行的 C 程序遇到问题,当它尝试调用 system() 时出现 Permission Denied (EACCES) 错误。

我在命令字符串中输入什么似乎并不重要,这些命令都是手动工作的,但是通过 system() 执行时会出现 Permission Denied 错误

另一件有趣的事是该程序在其他 XP 机器上也能正常工作,但不是这台机器。这让它感觉像是某种操作系统设置,但我不完全确定 system() 在后台做了什么,并且想了解这里发生了什么。

这是我的测试代码:

fprintf( stderr, "DEBUG: Running test of system(NULL) call...\n" );
if ( ( ret = system( NULL ) ) != 0)
    fprintf( stderr, "  DEBUG: ret: %d: errno: %d, %s\n", ret, errno, strerror( errno ) );

fprintf( stderr, "DEBUG: Running test of system(\"sleep 1\") call...\n" );
if ( ( ret = system( "sleep 1" ) ) != 0 )
    fprintf( stderr, "  DEBUG: ret: %d: errno: %d, %s\n", ret, errno, strerror( errno ) );

这会产生一个输出

DEBUG: Running test of system(NULL) call...
  DEBUG: ret: 1: errno: 0, No error
DEBUG: Running Test of system("sleep 1") call...
  DEBUG: ret: -1: errno: 13, Permission denied

谢谢。

更新:我还修改了我的代码以使用 CreateProcess() 而不是 system(),但我仍然收到“拒绝访问”错误 (5)。这使它听起来更像是一个操作系统设置,但我不知道在哪里看。

UPDATE2:进程监视器显示对路径“D:\cmd.exe”的“QueryOpen”调用失败,该路径不存在。所有其他调用都是针对 C:\WINDOWS\system32\cmd.exe,所以我不知道为什么一个调用是错误的。

【问题讨论】:

    标签: c windows windows-xp


    【解决方案1】:

    您是否尝试过使用Process Monitor 运行您的程序? Process Monitor 将向您显示您的程序进行的所有系统调用,以及有关调用的许多其他元数据(例如它们的参数和它们的返回值)。它可以帮助您调试为什么会收到“Permission Denied”错误。

    【讨论】:

    • 我得尝试一下,看看是否能得到更多信息。
    • 好的,所以在运行进程监视器后,问题似乎是对“D:\cmd.exe”上的 QueryOpen 的一次调用,该调用不存在。所有其他系统调用都是对正常的 C:\WINDOWS\system32\cmd.exe,所以我不知道是什么让它看起来在错误的地方。
    • @bde:您的%PATH% 环境变量设置正确吗?
    【解决方案2】:

    您确定您正在正确地检查故障吗? MSDN doesn't list EACCES 可能失败。 EACCES 可能只是在之前代码的 errno 中。

    int how_to_test_system(char const* command) {
      int rc;
      switch ((rc = system(command))) {
      case -1: // an error happened in calling system() itself
        perror("system"); // prints "system: <msg>"
        break;
    
      case 0: // command completed successfully
        break;
    
      default: // command executed, but had a non-zero return code
        // you might want to log something here
        // (otherwise you can simplify this switch into a single if for -1)
        break;
      }
      return rc;
    }
    

    【讨论】:

    • 错误来自执行命令但返回码非零的情况。从 MSDN“如果命令不是 NULL,系统返回命令解释器返回的值”,我认为这就是我得到 EACCES 错误的方式。我可以试试 system(NULL) 看看是否可行。
    • @bde: 执行程序的返回码不一定是errno常量;它的含义取决于执行的确切程序,除了零表示“成功”而非零表示“某种失败”。你有一个简短的测试用例吗? (用它更新问题文本。)
    • @Roger,我之前错了,我明白你的意思了。我用一个说明我所看到的测试用例更新了这个问题。
    【解决方案3】:

    COMSPEC 环境变量设置不正确或被覆盖

    在中查找 COMSPEC 1. 内置系统变量

    1. 在 HKEY_LOCAL_MACHINE 配置单元中找到系统变量

    2. 在 HKEY_CURRENT_USER 配置单元中找到局部变量

    3. Autoexec.bat 文件中设置的所有环境变量和路径

    4. 登录脚本中设置的所有环境变量和路径(如果存在)

    5. 在脚本或批处理文件中交互使用的变量

    真正的工作原理在这里...... http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds_shelloverview.mspx?mfr=true

    【讨论】:

    • 我同意 COMSPEC 环境变量似乎已被覆盖,但在我运行进程的环境中键入“echo %COMSPEC%”会显示“C:\WINDOWS\system32\cmd .exe”,这似乎是正确的。如果 COMSPEC 在创建进程的 shell 中是正确的,那么它如何被覆盖?
    • @bde 如果您以自己的身份登录 - 您在上面说您正在以系统身份运行。 a) 检查系统中的值 b) 确保您没有覆盖上述 3,4 或 5 中的 COMSPEC
    【解决方案4】:

    终于解决了,问题原来是后台运行的防病毒服务以某种方式干扰事物。

    感谢大家的帮助。

    【讨论】:

      猜你喜欢
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-16
      • 2020-06-29
      • 2012-05-03
      • 2022-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多