如何从Delphi中调用C#控制台程序并获取返回值?
方案1:通过控制台标准输出传递返回值(适合返回字符串等任意文本内容)
C#端修改代码
直接把要返回的内容通过Console.WriteLine输出到标准输出流即可:
using System; namespace Test { class Program { static int Main() { // 要返回给Delphi的内容 Console.WriteLine("hello world"); // 退出码,0表示执行正常,可自定义其他状态码标识执行结果 return 0; } } }
编译后记录C#程序的exe路径,比如C:\test\TestCSharp.exe。
Delphi端修改代码
通过创建子进程捕获C#程序的标准输出内容,直接用Windows API实现即可:
program Project2; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Winapi.Windows, Winapi.ShellAPI; function GetConsoleOutput(const CommandLine: string; out Output: string): Integer; var Security: TSecurityAttributes; ReadPipe, WritePipe: THandle; Startup: TStartupInfo; ProcessInfo: TProcessInformation; Buffer: array[0..4095] of AnsiChar; BytesRead: DWORD; begin Result := -1; Output := ''; ZeroMemory(@Security, SizeOf(Security)); Security.nLength := SizeOf(Security); Security.bInheritHandle := True; Security.lpSecurityDescriptor := nil; if not CreatePipe(ReadPipe, WritePipe, @Security, 0) then Exit; try ZeroMemory(@Startup, SizeOf(Startup)); Startup.cb := SizeOf(Startup); Startup.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; Startup.wShowWindow := SW_HIDE; Startup.hStdOutput := WritePipe; Startup.hStdError := WritePipe; if CreateProcess(nil, PChar(CommandLine), nil, nil, True, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, Startup, ProcessInfo) then begin CloseHandle(WritePipe); WritePipe := 0; WaitForSingleObject(ProcessInfo.hProcess, INFINITE); GetExitCodeProcess(ProcessInfo.hProcess, DWORD(Result)); while ReadFile(ReadPipe, Buffer[0], SizeOf(Buffer), BytesRead, nil) and (BytesRead > 0) do begin Output := Output + string(Copy(Buffer, 0, BytesRead)); end; CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); end; finally if WritePipe <> 0 then CloseHandle(WritePipe); CloseHandle(ReadPipe); end; end; begin try var CSharpExePath := 'C:\test\TestCSharp.exe'; // 替换成你自己的C#程序实际路径 var ReturnValue: string; var ExitCode := GetConsoleOutput(CSharpExePath, ReturnValue); Writeln('C#程序退出码:', ExitCode); Writeln('C#返回的内容:', Trim(ReturnValue)); Readln; // 暂停查看结果 except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.
运行Delphi程序就能直接拿到C#返回的hello world字符串并打印。
方案2:通过进程退出码传递返回值(仅适合返回整数类型结果)
如果只需要返回整数状态,不需要字符串内容,可以直接用进程退出码传递,实现更简单:
C#端代码
using System; namespace Test { class Program { static int Main() { // 直接返回整数,范围0-255最佳,避免兼容问题 return 123; } } }
Delphi端代码
program Project2; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Winapi.Windows, Winapi.ShellAPI; function GetProcessExitCode(const ExePath: string): Integer; var ShExecInfo: TShellExecuteInfo; begin Result := -1; ZeroMemory(@ShExecInfo, SizeOf(ShExecInfo)); ShExecInfo.cbSize := SizeOf(ShExecInfo); ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd := 0; ShExecInfo.lpVerb := 'open'; ShExecInfo.lpFile := PChar(ExePath); ShExecInfo.lpParameters := nil; ShExecInfo.lpDirectory := nil; ShExecInfo.nShow := SW_HIDE; if ShellExecuteEx(@ShExecInfo) then begin WaitForSingleObject(ShExecInfo.hProcess, INFINITE); GetExitCodeProcess(ShExecInfo.hProcess, DWORD(Result)); CloseHandle(ShExecInfo.hProcess); end; end; begin try var CSharpExePath := 'C:\test\TestCSharp.exe'; // 替换成你自己的C#程序实际路径 var ExitCode := GetProcessExitCode(CSharpExePath); Writeln('C#程序返回的退出码:', ExitCode); Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.
内容的提问来源于stack exchange,提问作者Maik Hasler
相关产品推荐
相关产品推荐

