我有一个NT
服务,它调用用Delphi7编写的控制台程序,让我们称它为failover.exe
,然后使用我找到的过程调用NETSH
:
procedure ExecConsoleApp(CommandLine: ansistring; Output, Errors: TStringList);
注意: ExecConsoleApp使用CreateProcess,请参阅下面的完整代码链接:http://www.delphisources.ru/pages/faq/base/createprocess_console.html
在调用CommandLine之前,我会将以下内容传递给ExecConsoleApp
:
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
执行以使其工作:
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.
过程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接口ip删除地址"LocalArea连接“10.40.201.65
指定的
无效接口LocalArea连接。
如果我将"LocalArea“错误更正为”LocalArea“,则返回以下内容。netsh接口ip删除地址“本地连接”10.40.201.65
系统找不到指定的文件。
同样,我必须重申,如果通过命令提示符而不是从我的应用程序发出命令,相同的命令可以很好地工作。
发布于 2011-11-17 13:01:05
你试过这个吗?
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
。
发布于 2011-11-19 05:14:17
如果可执行文件所要求的隐式加载DLL不可用,“无法找到指定的文件”错误也可能发生。在这种情况下,这是最有可能的原因-一些必要的DLL是找不到的时候,netsh.exe是运行在一个非交互式的上下文。
使用Process (可从Microsoft网站下载)记录在尝试过程中正在进行的文件系统操作。在服务流程的上下文或netsh.exe流程的上下文中查找未找到的文件。
https://stackoverflow.com/questions/8166840
复制相似问题