当我从CreateProcess运行NETSH时,“系统找不到指定的文件”,但它在命令提示符下运行正常吗?

时间:2011-11-17 12:07:50

标签: windows delphi createprocess netsh

我有一个NT服务调用用Delphi 7编写的控制台程序,我们称之为failover.exe,然后使用我找到的程序调用{​​{1}}:

NETSH

注意:ExecConsoleApp使用CreateProcess,请参阅以下链接获取完整代码:http://www.delphisources.ru/pages/faq/base/createprocess_console.html

在调用procedure ExecConsoleApp(CommandLine: ansistring; Output, Errors: TStringList); 之前,我会将以下内容传递给CommandLine:

ExecConsoleApp

cmd.exe /c "C:\Windows\system32\netsh.exe interface delete address "Wireless Network Connection" 192.168.0.36" 将返回错误:

  

系统找不到指定的文件

但是,如果我在命令提示符下运行它,它会完美运行。

奇怪的是,我记得它在第一次尝试2003服务器上工作,但在那之后,无论我尝试多少次都失败了。在其中一次尝试中,我还尝试将登录作为管理员用户分配给服务,但无济于事。也没有摆弄文件安全帮助。

我没有Win 2003服务器可以在办公室进行测试,但我已经在XP和Win7上测试了它,ExecConsoleApp完美地工作,虽然在XP上,我不得不修改ExecConsoleApp到从ExecConsoleApp执行以使其正常工作:

system32\wbem

我研究了一天,但没有线索,希望有人可以提供帮助。感谢。

补充说明 -

  1. 服务器是32位Win2k3。

  2. 尝试过域管理员,不起作用。

  3. 代码段:

     Res := CreateProcess(nil, PChar(CommandLine), nil, nil, True,
      // **** Attention: Amended by to point current directory to system32\wbem, this is to solve an error returned by netsh.exe if not done otherwise.
     //   CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, @env, nil, si, pi);
       CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, @env, pchar(GetSystemPath(WindRoot) + 'system32\wbem'), si, pi);
    
  4. 尝试直接运行netsh.exe而不是“cmd.exe / c C:\ Windows \ system32 \ netsh.exe ...”,并得到相同的“系统找不到指定的文件”。错误。我还意外地发现,如果我发出错误的netsh命令,netsh实际上会返回错误,例如

  5. netsh interface ip delete address“LocalArea Connection”10.40.201.65

      

    指定了无效的接口LocalArea Connection。

    如果我将拼写错误“LocalArea”更正为“Local Area”,则会返回以下内容。 netsh interface ip delete address“Local Area Connection”10.40.201.65

      

    系统找不到指定的文件。

    同样,我必须重复一遍,如果我通过命令提示符而不是从我的应用程序发出它,那么相同的命令工作正常。

2 个答案:

答案 0 :(得分:2)

你试过这个吗?

if not CreateProcess(PChar('C:\Windows\system32\netsh.exe'), PChar(Arguments), ...) then
begin
  // Do somehting with `GetLastError`
end;

当然最好在运行时检测C:\Windows\system32的路径,因为这可能在另一个驱动程序或另一个目录中。

以这种方式运行时,您可以在CreateProcess之后立即使用GetLastError调用从Windows获取错误消息。

ExecConsoleApp程序存在缺陷,因为它不会返回GetLastError甚至是CreateProcess失败的任何迹象。

你应该先解决这个问题。也许在raise EExecConsoleAppCreateProcessFailed.Create(SysErrorMessage(GetLastError))之前将Exit添加到代码中。

您不应使用cmd.exe /c作为前缀。这是多余的,它使错误诊断更加困难。 GetLastError可能无法反映正确的错误代码,因为您将正常netsh.exe流程的创建委托给cmd

答案 1 :(得分:0)

如果可执行文件所需的隐式加载的DLL不可用,也可能出现“找不到指定的文件”错误。在这种情况下,这是最可能的原因 - 当netsh.exe在非交互式上下文中运行时,找不到某些必需的DLL。

使用Process Monitor(可从Microsoft网站下载)记录尝试期间发生的文件系统操作。在服务进程的上下文中或在netsh.exe进程的上下文中查找未找到文件的错误。