Pchar,CMDline,string
8 отговора
213 прегледа
Pchar,CMDline,string
Имам един досаден проблем.
Някой пробвал ли е да пише в CMD конзолката на XP/2k команди по следния начин (примерно) :
net send localhost just a test > C:\1.txt
да, резултата от тези команди ще се запише в файла C:\1.txt
Именно по този начин искам да чета резултата от някоя команда, и взависимост от него, моята програма да прави нещо.
Искам обаче да пускам тези команди от програмата ми, и ето какъв всъщност е проблема:
cmdl:=cmdedit.text+' >C:\1.tmp';
WinExec(PChar(cmdl),sw_hide);
Но така ">" се възприема не като спецялен символ, а като продължение на командата..така че резултата не се запазва във 1.tmp както е в случая, и командата става абсолютно невалидна и грешна :)
Как да стартирам това което ми трябва както трябва?? Ясно, низа от команди трябва да е PChar, но как да го постигна? Видях че има една променлива CmdLine : Pchar в System.pas, нея ли да ползвам по някакъв начин? Дано да ви е станало ясно, какво искам, и какво се получава...
Някой пробвал ли е да пише в CMD конзолката на XP/2k команди по следния начин (примерно) :
net send localhost just a test > C:\1.txt
да, резултата от тези команди ще се запише в файла C:\1.txt
Именно по този начин искам да чета резултата от някоя команда, и взависимост от него, моята програма да прави нещо.
Искам обаче да пускам тези команди от програмата ми, и ето какъв всъщност е проблема:
cmdl:=cmdedit.text+' >C:\1.tmp';
WinExec(PChar(cmdl),sw_hide);
Но така ">" се възприема не като спецялен символ, а като продължение на командата..така че резултата не се запазва във 1.tmp както е в случая, и командата става абсолютно невалидна и грешна :)
Как да стартирам това което ми трябва както трябва?? Ясно, низа от команди трябва да е PChar, но как да го постигна? Видях че има една променлива CmdLine : Pchar в System.pas, нея ли да ползвам по някакъв начин? Дано да ви е станало ясно, какво искам, и какво се получава...
Re: Pchar,CMDline,string
Ууу, една камара грешки съм допуснал в предишния си пост...да си сменям клавиатурата


Re: Pchar,CMDline,string
Здравей!
Защо използваш тази стара функция?
Ако няма някаква специална причина да държиш на нея по-добре го направи с shellexecute декларирана е в shellapi.
shellexecute(handle,'open',PChar(cmdedit.text),'>C:\1.tmp',nil,sw_hide);
Защо използваш тази стара функция?
Ако няма някаква специална причина да държиш на нея по-добре го направи с shellexecute декларирана е в shellapi.
shellexecute(handle,'open',PChar(cmdedit.text),'>C:\1.tmp',nil,sw_hide);
Мне..
Пак не става... дори трябва да е :
shellexecute(handle,'open','net','send localhost fdfd >C:\1.tmp',nil,sw_hide);
а не
shellexecute(handle,'open',PChar(cmdedit.text),' >C:\1.tmp',nil,sw_hide);
Т.е. не трябва да слагам целия команден ред, ами само програмката, която ще пускам. Само че отново ">" не се възприема като спецялен символ, казващ на програмата да записва резултата във файл, а като част от низа, който трябва да се изпрати до някъде, както е в примера който съм посочил.
Иначе защо ползвам WinExec() - винаги ми е вършила хубава работа, и рядко ми се е налагало да ползвам възможности, които не може...
е, явно сега ми се наложи :) Предложения?
shellexecute(handle,'open','net','send localhost fdfd >C:\1.tmp',nil,sw_hide);
а не
shellexecute(handle,'open',PChar(cmdedit.text),' >C:\1.tmp',nil,sw_hide);
Т.е. не трябва да слагам целия команден ред, ами само програмката, която ще пускам. Само че отново ">" не се възприема като спецялен символ, казващ на програмата да записва резултата във файл, а като част от низа, който трябва да се изпрати до някъде, както е в примера който съм посочил.
Иначе защо ползвам WinExec() - винаги ми е вършила хубава работа, и рядко ми се е налагало да ползвам възможности, които не може...
е, явно сега ми се наложи :) Предложения?
Re: Pchar,CMDline,string
сигурно може да тане и с WinExec или с ShellExecute, ама етиго с CreateProcess:
Am I evil?
Yes I am.
procedure TForm1.Button1Click(Sender: TObject);
var sSendTo : String;
sMessage : String;
CMDLine : String;
OutDest : String;
si : STARTUPINFO;
procinfo : PROCESS_INFORMATION;
begin
sSendTo := 'mycomputername'; //тури си туканка името на компа :-)))
sMessage := 'just a test';
OutDest := '>C:\tst2.txt';
CMDLine := 'cmd /c net send ' + sSendTo + ' "' + sMessage + '"' + OutDest;
GetStartupInfo(si);
CreateProcess(nil, PChar(CMDLine), nil, nil, false, 0, nil, nil, si, procinfo)
end;
Am I evil?
Yes I am.
Re: Pchar,CMDline,string
Не ми се рови сега но си мисля, че символа ">" не е параметър на командния ред, а е инструкция към командния интерпретатор да пренасочи стандартния изход. В такъв случай трябва да се търси решение чрез структурата STARTUPINFO. Там някъде имаше начин да се укаже стандартния изход.

Re: Pchar,CMDline,string
Да, определено този суич ( /c ) помогна много :) Това беше момчета, благодаря за помоща!


На прав път си....
бях правил за VC6 преди време - ама сега го изрових и за Делфи
function GetDosOutput(const CommandLine:string): string;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of Char;
BytesRead: Cardinal;
WorkDir, Line: String;
begin
Application.ProcessMessages;
with SA do
begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
// create pipe for standard output REDIRECTion
CreatePipe(StdOutPipeRead, // read handle
StdOutPipeWrite, // write handle
@SA, // security attributes
0 // number of bytes reserved for pipe - 0
default
);
try
// Make child process use StdOutPipeWrite as standard out,
// and make sure it does not show on SCREEN.
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't REDIRECT std
input
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
// launch the command line compiler
WorkDir := ExtractFilePath(CommandLine);
WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil,
PChar(WorkDir), SI, PI);
// Now that the handle has been inherited, close write to be safe.
// We don't want to read or write to it accidentally.
CloseHandle(StdOutPipeWrite);
// if process could be created then handle its output
if not WasOK then
raise Exception.Create('Could not execute command line!')
else
try
// get all output until dos app finishes
Line := '';
repeat
// read block of characters (might contain carriage returns and
line feeds)
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
// has anything been read?
if BytesRead > 0 then
begin
// finish buffer to PChar
Buffer[BytesRead] := #0;
// combine the buffer with the rest of the last run
Line := Line + Buffer;
end;
until not WasOK or (BytesRead = 0);
// wait for console app to finish (should be already at this point)
WaitForSingleObject(PI.hProcess, INFINITE);
finally
// Close all remaining handles
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
result:=Line;
CloseHandle(StdOutPipeRead);
end;
end;
---
Колкото повече, толкова повече.
function GetDosOutput(const CommandLine:string): string;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of Char;
BytesRead: Cardinal;
WorkDir, Line: String;
begin
Application.ProcessMessages;
with SA do
begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
// create pipe for standard output REDIRECTion
CreatePipe(StdOutPipeRead, // read handle
StdOutPipeWrite, // write handle
@SA, // security attributes
0 // number of bytes reserved for pipe - 0
default
);
try
// Make child process use StdOutPipeWrite as standard out,
// and make sure it does not show on SCREEN.
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't REDIRECT std
input
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
// launch the command line compiler
WorkDir := ExtractFilePath(CommandLine);
WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil,
PChar(WorkDir), SI, PI);
// Now that the handle has been inherited, close write to be safe.
// We don't want to read or write to it accidentally.
CloseHandle(StdOutPipeWrite);
// if process could be created then handle its output
if not WasOK then
raise Exception.Create('Could not execute command line!')
else
try
// get all output until dos app finishes
Line := '';
repeat
// read block of characters (might contain carriage returns and
line feeds)
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
// has anything been read?
if BytesRead > 0 then
begin
// finish buffer to PChar
Buffer[BytesRead] := #0;
// combine the buffer with the rest of the last run
Line := Line + Buffer;
end;
until not WasOK or (BytesRead = 0);
// wait for console app to finish (should be already at this point)
WaitForSingleObject(PI.hProcess, INFINITE);
finally
// Close all remaining handles
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
result:=Line;
CloseHandle(StdOutPipeRead);
end;
end;
---
Колкото повече, толкова повече.