首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当我从CreateProcess运行NETSH时,得到“系统找不到指定的文件”,但它在命令提示符下工作正常吗?

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

Stack Overflow用户
提问于 2011-11-17 12:07:50
回答 2查看 15.4K关注 0票数 6

我有一个NT服务,它调用用Delphi7编写的控制台程序,让我们称它为failover.exe,然后使用我找到的过程调用NETSH

代码语言:javascript
运行
复制
procedure ExecConsoleApp(CommandLine: ansistring; Output, Errors: TStringList); 

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

在调用CommandLine之前,我会将以下内容传递给ExecConsoleApp

代码语言:javascript
运行
复制
cmd.exe /c "C:\Windows\system32\netsh.exe interface delete address "Wireless Network Connection" 192.168.0.36" 

ExecConsoleApp将返回一个错误:

系统找不到指定的文件

但是如果我要在命令提示符中运行它,它就运行得很完美。

奇怪的是,我记得它第一次在那个2003 Server上运行,但在那之后,不管我尝试了多少次,它都失败了。在其中一次尝试中,我还尝试将登录作为管理员用户分配给服务,但没有成功。篡改文件安全也没有帮助。

我没有一个Win 2003服务器可以在office上进行测试,但我已经在XP上测试过它,Win7和ExecConsoleApp工作得很好,尽管在XP上,我不得不修改ExecConsoleApp以从system32\wbem执行以使其工作:

代码语言:javascript
运行
复制
 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);

我研究了一天,但没有线索,希望有人能帮忙。谢谢。

补充意见-

Win2k3.

  • Tried服务器是32位域管理员,不能工作。
  1. 代码片段:

过程ExecConsoleApp(CommandLine: ansistring;输出、错误: TStringList);var sa: TSECURITYATTRIBUTES;si: TSTARTUPINFO;pi: TPROCESSINFORMATION;hPipeOutputRead: THANDLE;hPipeOutputWrite: THANDLE;hPipeErrorsRead: THANDLE;hPipeErrorsWrite: THANDLE;Res、bTest:布尔;env: array0.CreatePipe(hPipeOutputRead,hPipeOutputWrite,@sa,0);CreatePipe(hPipeErrorsRead,hPipeErrorsWrite,@sa,0);ZeroMemory(@env,SizeOf(env));ZeroMemory(@si,SizeOf(si));ZeroMemory(@pi,SizeOf(pi));si.cb := SizeOf(si);si.dwFlags := :=或SizeOf;env 20;en23# 0;en25#;si.hStdError := hPipeErrorsWrite;(*请记住,如果您想要执行没有参数的应用程序,您可以不使用第二个参数并使用第一个参数,您也可以保持原样,没有问题。* Res := CreateProcess (0,PChar(CommandLine),0,nil,True,CREATE_NEW_CONSOLE或NORMAL_PRIORITY_CLASS,@env,nil,si,pi);//如果CreateProcess失败则退出,如果CreateProcess失败,则开始CloseHandle(hPipeOutputRead);CloseHandle(hPipeOutputWrite);CloseHandle(hPipeErrorsRead);CloseHandle(hPipeErrorsWrite);Exit;end;CloseHandle(hPipeOutputWrite);CloseHandle(hPipeErrorsWrite);CloseHandle(HPipeErrorsWrite);//读取输出管道流:= TMemoryStream.Create;试试看True确实开始bTest := ReadFile(hPipeOutputRead,szBuffer,256,dwNumberOfBytesRead,nil);如果不是bTest,则开始中断;结束;OemToAnsi(szBuffer,szBuffer);Stream.Write(szBuffer,dwNumberOfBytesRead);end;Stream.Position := 0;Stream.Position( Stream );最后Stream.Free;结束;//读取错误管道流:= TMemoryStream.Create;尝试True确实开始bTest := ReadFile(hPipeErrorsRead,szBuffer,256,dwNumberOfBytesRead,0);如果不是bTest,则开始中断;结束;OemToAnsi(szBuffer,szBuffer);Stream.Write(szBuffer,dwNumberOfBytesRead);end;Stream.Position Stream.Position 0;Errors.LoadFromStream(流);Stream.Free;end;WaitForSingleObject(pi.hProcess,无穷);CloseHandle(pi.hProcess);CloseHandle(hPipeOutputRead);CloseHandle(hPipeErrorsRead);end;cmdstring := 'cmd.exe /c“+ GetSystemPath(WindRoot) + 'system32\netsh.exe interface‘+ ip +’删除地址‘’+ NetworkInterfaceName + '”;logstr('cmdstring:‘+cmdstring:’+ cmdstring);ExecConsoleApp(cmdstring,OutP,ErrorP);如果OutP.Text <> '‘然后开始logstr('Delete结果:’+ OutP.Text);end of开始logstr(‘删除IP错误:’‘+ ErrorP.Text);

  • 尝试直接运行netsh.exe而不是"cmd.exe /c C:\Windows\system32\netsh.exe.“,并得到了相同的”系统找不到指定的文件“。错误。我还意外地发现,如果我发出错误的netsh命令,netsh实际上会返回一个错误,例如

netsh接口ip删除地址"LocalArea连接“10.40.201.65

指定的

无效接口LocalArea连接。

如果我将"LocalArea“错误更正为”LocalArea“,则返回以下内容。netsh接口ip删除地址“本地连接”10.40.201.65

系统找不到指定的文件。

同样,我必须重申,如果通过命令提示符而不是从我的应用程序发出命令,相同的命令可以很好地工作。

EN

回答 2

Stack Overflow用户

发布于 2011-11-17 13:01:05

你试过这个吗?

代码语言:javascript
运行
复制
if not CreateProcess(PChar('C:\Windows\system32\netsh.exe'), PChar(Arguments), ...) then
begin
  // Do somehting with `GetLastError`
end;

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

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

ExecConsoleApp过程有缺陷,因为它不返回GetLastError,甚至不返回CreateProcess失败的任何指示。

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

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

票数 2
EN

Stack Overflow用户

发布于 2011-11-19 05:14:17

如果可执行文件所要求的隐式加载DLL不可用,“无法找到指定的文件”错误也可能发生。在这种情况下,这是最有可能的原因-一些必要的DLL是找不到的时候,netsh.exe是运行在一个非交互式的上下文。

使用Process (可从Microsoft网站下载)记录在尝试过程中正在进行的文件系统操作。在服务流程的上下文或netsh.exe流程的上下文中查找未找到的文件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8166840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档