我試圖用delphi發送命令到命令提示符。 但是,我無法這樣做,因爲我使用CreateProcess方法來做到這一點。 我試圖改變StdOutPipeWrite,但是,CreateProcess似乎不允許來自CreateProcess的初始命令通過後的命令。 有什麼辦法可以利用這個句柄繼續發送和接收來自命令提示符和delphi的命令和消息嗎?通過Delphi與命令提示通信
4
A
回答
9
我的同伴Glenn9999來自tek-tips.com wrote a nice FAQ on this subject。 我不知道他是不是這樣,但他值得所有這一個功勞。 我將這個頁面的代碼拷貝到這裏供將來參考。他使用管道進行控制檯和delphi之間的通信。
unit mcunit;
{ written by Glenn9999 @ tek-tips.com. Posted here 6/21/2011 }
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
monitor = class(TThread) // pipe monitoring thread for console output
private
TextString: String;
procedure UpdateCaption;
protected
procedure Execute; override;
end;
TForm1 = class(TForm)
CommandText: TMemo;
CommandRun: TComboBox;
Button2: TButton;
SaveDialog1: TSaveDialog;
procedure FormDestroy(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
cmdcount: integer;
end;
var
Form1: TForm1;
InputPipeRead, InputPipeWrite: THandle;
OutputPipeRead, OutputPipeWrite: THandle;
ErrorPipeRead, ErrorPipeWrite: THandle;
ProcessInfo : TProcessInformation;
myThread: monitor;
implementation
{$R *.DFM}
procedure WritePipeOut(OutputPipe: THandle; InString: string);
// writes Instring to the pipe handle described by OutputPipe
var
byteswritten: DWord;
begin
// most console programs require CR/LF after their input.
InString := InString + #13#10;
WriteFile(OutputPipe, Instring[1], Length(Instring), byteswritten, nil);
end;
function ReadPipeInput(InputPipe: THandle; var BytesRem: Integer): String;
{
reads console output from InputPipe. Returns the input in function
result. Returns bytes of remaining information to BytesRem
}
var
TextBuffer: array[1..32767] of char;
TextString: String;
BytesRead: Integer;
PipeSize: Integer;
begin
Result := '';
PipeSize := Sizeof(TextBuffer);
// check if there is something to read in pipe
PeekNamedPipe(InputPipe, nil, PipeSize, @BytesRead, @PipeSize, @BytesRem);
if bytesread > 0 then
begin
ReadFile(InputPipe, TextBuffer, pipesize, bytesread, nil);
// a requirement for Windows OS system components
OemToChar(@TextBuffer, @TextBuffer);
TextString := String(TextBuffer);
SetLength(TextString, BytesRead);
Result := TextString;
end;
end;
procedure monitor.Execute;
{ monitor thread execution for console output. This must be threaded.
checks the error and output pipes for information every 40 ms, pulls the
data in and updates the memo on the form with the output }
var
BytesRem: DWord;
begin
while not Terminated do
begin
// read regular output stream and put on screen.
TextString := ReadPipeInput(OutputPipeRead, BytesRem);
if TextString <> '' then
Synchronize(UpdateCaption);
// now read error stream and put that on screen.
TextString := ReadPipeInput(ErrorPipeRead, BytesRem);
if TextString <> '' then
Synchronize(UpdateCaption);
sleep(40);
end;
end;
procedure monitor.UpdateCaption;
// synchronize procedure for monitor thread - updates memo on form.
begin
With Form1.CommandText.Lines do
Add(TextString);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
WritePipeOut(InputPipeWrite, 'EXIT'); // quit the CMD we started
MyThread.Terminate;
// close process handles
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
// close pipe handles
CloseHandle(InputPipeRead);
CloseHandle(InputPipeWrite);
CloseHandle(OutputPipeRead);
CloseHandle(OutputPipeWrite);
CloseHandle(ErrorPipeRead);
CloseHandle(ErrorPipeWrite);
end;
procedure TForm1.Button2Click(Sender: TObject);
{ takes the input from the command edit box and processes it }
var
UpText: String;
begin
UpText := UpperCase(CommandRun.Text); // done to eliminate case-sensitivity
if UpText = 'CLR' then // clear the memo
begin
CommandText.Clear;
WritePipeOut(InputPipeWrite, #13);
end
else
if UpText = 'SAVELOG' then // save the memo box to a file.
begin
if SaveDialog1.Execute then
begin
CommandText.Lines.SaveToFile(SaveDialog1.FileName);
CommandText.Lines.Add('Log file saved.');
end
else
CommandText.Lines.Add('Log file not saved.');
end
// expand this, it needs to catch any variation where the command-interpreter
// is called. Any different ideas?
else
if UpText = 'CMD' then
inc(cmdcount)
else
if UpText = 'COMMAND' then
inc(cmdcount)
// terminate app if user types exit, else let alone
else
if UpText = 'EXIT' then
begin
if cmdcount = 1 then
Application.Terminate
else
dec(cmdcount);
end
else
WritePipeOut(InputPipeWrite, CommandRun.Text);
CommandRun.Items.Add(CommandRun.Text);
CommandRun.Text := '';
CommandRun.SetFocus;
end;
procedure TForm1.FormCreate(Sender: TObject);
{ upon form creation, this calls the command-interpreter, sets up the three
pipes to catch input and output, and starts a thread to monitor and show
the output of the command-interpreter }
var
DosApp: String;
DosSize: Integer;
Security : TSecurityAttributes;
start : TStartUpInfo;
begin
CommandText.Clear;
// get COMSPEC variable, this is the path of the command-interpreter
SetLength(Dosapp, 255);
DosSize := GetEnvironmentVariable('COMSPEC', @DosApp[1], 255);
SetLength(Dosapp, DosSize);
// create pipes
With Security do
begin
nlength := SizeOf(TSecurityAttributes) ;
binherithandle := true;
lpsecuritydescriptor := nil;
end;
CreatePipe(InputPipeRead, InputPipeWrite, @Security, 0);
CreatePipe(OutputPipeRead, OutputPipeWrite, @Security, 0);
CreatePipe(ErrorPipeRead, ErrorPipeWrite, @Security, 0);
// start command-interpreter
FillChar(Start,Sizeof(Start),#0) ;
start.cb := SizeOf(start) ;
start.hStdInput := InputPipeRead;
start.hStdOutput := OutputPipeWrite;
start.hStdError := ErrorPipeWrite;
start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
start.wShowWindow := SW_HIDE;
if CreateProcess(nil, PChar(DosApp), @Security, @Security, true,
CREATE_NEW_CONSOLE or SYNCHRONIZE,
nil, nil, start, ProcessInfo) then
begin
MyThread := monitor.Create(false); // start monitor thread
MyThread.Priority := tpHigher;
end;
Button2.Enabled := true;
cmdcount := 1;
end;
end.
-2
首先聲明的用途:
ShellAPI
然後用這個:
ShellExecute(0, nil, 'cmd.exe', '/c **YOUR_COMMAND_HERE**', nil, HIDE_WINDOW);
+1
這個問題假設初始命令已經成功通過,所以這似乎沒有任何進一步的東西。 –
相關問題
- 1. 通過命令提示符連接mysql
- 2. 通過命令提示符查找
- 3. 如何使用C++與命令提示符(CMD)進行通信?
- 4. 通過flex運行命令提示符命令
- 5. 通過命令行與應用程序通信
- 6. 通過php,AT命令發送短信
- 7. Cookie不會通過javascript命令執行提示和提醒
- 8. 通過提交命令的Git結賬
- 9. 通過命令行
- 10. 通過命令行
- 11. 通過命令行
- 12. Delphi中的管道命令提示符
- 13. 通過Windows命令提示符通過密碼驗證執行ssh
- 14. 差異 - 通過java執行unix命令並通過提示即正常執行
- 15. 通過PHP與.net通信
- 16. 通過C與iDevice通信?
- 17. 短信通過AT命令與GSM手機給出錯誤
- 18. 通過HDMI通過命令行發送CEC命令
- 19. 通過批量命令全屏顯示?
- 20. 通過SQL顯示MySQL主機命令
- 21. 調用命令提示符並通過VBA中的Shell Exec執行命令
- 22. 通過命令行與JNI調用
- 23. AT命令通過藍牙hm10與Android
- 24. 發送命令通過ssh與參數
- 25. 如何通過命令行監視Windows上的網絡通信
- 26. 通過IP進行串口通信拒絕命令MODBUS?
- 27. 用戶控件通過命令進行通信 - 如何?
- 28. 如何通過命令提示編譯C#應用程序
- 29. 安裝,並通過命令提示符「C#」
- 30. 如何通過命令提示符運行c#應用程序?
您可能需要使用/ C選項來傳遞你想執行的CMD.EXE實例的命令你由CreateProcess開始。打開一個命令窗口並輸入'help cmd'獲取更多信息。但請注意,這隻允許傳遞一個命令。如果您需要執行多個命令,則可以寫出一個批處理文件並將其作爲要執行的命令傳遞。 –