Jos*_*hua 5 windows delphi createprocess netsh
我有一个NT调用Delphi 7编写的控制台程序的服务,让我们调用它failover.exe,然后NETSH使用我发现的程序调用:
procedure ExecConsoleApp(CommandLine: ansistring; Output, Errors: TStringList);
Run Code Online (Sandbox Code Playgroud)
注意: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"
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
我研究了一天,但没有线索,希望有人可以提供帮助.谢谢.
补充评论 -
服务器是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;
Run Code Online (Sandbox Code Playgroud)尝试直接运行netsh.exe而不是"cmd.exe/c C:\ Windows\system32 \netsh.exe ...",并得到相同的"系统找不到指定的文件".错误.我还意外地发现,如果我发出错误的netsh命令,netsh实际上会返回错误,例如
netsh interface ip delete address"LocalArea Connection"10.40.201.65
指定的接口LocalArea连接无效.
如果我将拼写错误"LocalArea"更正为"Local Area",则返回以下内容.netsh interface ip delete address"Local Area Connection"10.40.201.65
该系统找不到指定的文件.
同样,我必须重复,如果我通过命令提示符而不是从我的应用程序发出它,相同的命令工作得很好.
小智 5
运行时,netsh interface portproxy delete v4tov4 ...如果我尝试删除的内容不存在,则会出现此错误。如果我尝试这样做,我也会收到此错误netsh interface portproxy delete v4tov4 all。那么,唯一适用于存在的项目的是,如果我同时指定端口和地址:netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=80。如果我只使用 thelistenaddress或仅使用 the,即使该项目存在,listenport我也会收到错误。The system cannot find the file specified.使用进程监视器,如果您使用除这两个参数之外的任何其他参数,它似乎netsh.exe会将无效参数传递给Win32 API。RegDeleteValue
你试过这个吗?
if not CreateProcess(PChar('C:\Windows\system32\netsh.exe'), PChar(Arguments), ...) then
begin
// Do somehting with `GetLastError`
end;
Run Code Online (Sandbox Code Playgroud)
当然,最好在C:\Windows\system32运行时检测 的路径,因为这可能位于另一个驱动程序或另一个目录中。
当您以这种方式运行它时,您可以使用 CreateProcess 之后的调用从 Windows 获取错误消息GetLastError。
该ExecConsoleApp过程是有缺陷的,因为它不返回失败的GetLastError指示,甚至不返回任何指示CreateProcess。
你应该先解决这个问题。也许在代码中添加raise EExecConsoleAppCreateProcessFailed.Create(SysErrorMessage(GetLastError))之前。Exit
您不应该用作cmd.exe /c前缀。它是多余的,并且使错误诊断变得更加困难。可能无法反映正确的错误代码,因为您将实际进程GetLastError的创建委托给.netsh.execmd
| 归档时间: |
|
| 查看次数: |
12674 次 |
| 最近记录: |