我有一个NT
调用用 Delphi 7 编写的控制台程序的服务,让我们调用它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 服务器,但我已经在 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);
我研究了一天,但没有任何线索,希望有人能帮忙。谢谢。
补充说明——
服务器是 32 位 Win2k3。
试过域管理员,不行。
代码片段:
Procedure ExecConsoleApp(CommandLine: ansistring; Output, Errors: TStringList); var sa: TSECURITYATTRIBUTES; si: TSTARTUPINFO; pi: TPROCESSINFORMATION; hPipeOutputRead: THANDLE; hPipeOutputWrite: THANDLE; hPipeErrorsRead: THANDLE; hPipeErrorsWrite: THANDLE; Res, bTest: boolean; env: array[0..100] of char; szBuffer: array[0..256] of char; dwNumberOfBytesRead: DWORD; Stream: TMemoryStream; begin sa.nLength := sizeof(sa); sa.bInheritHandle := True; sa.lpSecurityDescriptor := nil; 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 := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; si.wShowWindow := SW_HIDE; si.hStdInput := 0; si.hStdOutput := hPipeOutputWrite; si.hStdError := hPipeErrorsWrite; (* Remember that if you want to execute an app with no parameters you nil the second parameter and use the first, you can also leave it as is with no problems. *) Res := CreateProcess(nil, PChar(CommandLine), nil, nil, True, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, @env, nil, si, pi); // Procedure will exit if CreateProcess fail if not Res then begin CloseHandle(hPipeOutputRead); CloseHandle(hPipeOutputWrite); CloseHandle(hPipeErrorsRead); CloseHandle(hPipeErrorsWrite); Exit; end; CloseHandle(hPipeOutputWrite); CloseHandle(hPipeErrorsWrite); //Read output pipe Stream := TMemoryStream.Create; try while True do begin bTest := ReadFile(hPipeOutputRead, szBuffer, 256, dwNumberOfBytesRead, nil); if not bTest then begin break; end; OemToAnsi(szBuffer, szBuffer); Stream.Write(szBuffer, dwNumberOfBytesRead); end; Stream.Position := 0; Output.LoadFromStream(Stream); finally Stream.Free; end; //Read error pipe Stream := TMemoryStream.Create; try while True do begin bTest := ReadFile(hPipeErrorsRead, szBuffer, 256, dwNumberOfBytesRead, nil); if not bTest then begin break; end; OemToAnsi(szBuffer, szBuffer); Stream.Write(szBuffer, dwNumberOfBytesRead); end; Stream.Position := 0; Errors.LoadFromStream(Stream); finally Stream.Free; end; WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(hPipeOutputRead); CloseHandle(hPipeErrorsRead); end; cmdstring := 'cmd.exe /c "' + GetSystemPath(WindRoot) + 'system32\netsh.exe interface ' + ip + ' delete address "' + NetworkInterfaceName + '" ' + VirtualFailoverIPAddress + '"'; logstr('cmdstring: ' + cmdstring); ExecConsoleApp(cmdstring, OutP, ErrorP); if OutP.Text <> '' then begin logstr('Delete IP Result: ' + OutP.Text); end else begin logstr('Delete IP Error: ' + ErrorP.Text); end;
尝试直接运行 netsh.exe 而不是“cmd.exe /c C:\Windows\system32\netsh.exe...”,得到相同的“系统找不到指定的文件”。错误。我还意外发现,如果我发出错误的 netsh 命令,netsh 实际上会返回错误,例如
netsh interface ip delete address "LocalArea Connection" 10.40.201.65
指定的接口 LocalArea Connection 无效。
如果我将拼写错误“LocalArea”更正为“Local Area”,则会返回以下内容。netsh 接口 ip 删除地址“本地连接”10.40.201.65
该系统找不到指定的文件。
同样,我必须重复,如果我通过命令提示符而不是从我的应用程序发出相同的命令,它可以正常工作。