Pchar,CMDline,string

8 отговора 213 прегледа
#1

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, нея ли да ползвам по някакъв начин? Дано да ви е станало ясно, какво искам, и какво се получава...

Отговор
в отговор на ShaDoW #2

Re: Pchar,CMDline,string

Ууу, една камара грешки съм допуснал в предишния си пост...да си сменям клавиатурата

Отговор
в отговор на ShaDoW #3

Re: Pchar,CMDline,string

Здравей!
Защо използваш тази стара функция?
Ако няма някаква специална причина да държиш на нея по-добре го направи с shellexecute декларирана е в shellapi.
shellexecute(handle,'open',PChar(cmdedit.text),'>C:\1.tmp',nil,sw_hide);

Отговор
в отговор на v_automation #4

Мне..

Пак не става... дори трябва да е :


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() - винаги ми е вършила хубава работа, и рядко ми се е налагало да ползвам възможности, които не може...
е, явно сега ми се наложи :) Предложения?

Отговор
в отговор на ShaDoW #5

Re: Pchar,CMDline,string

сигурно може да тане и с WinExec или с ShellExecute, ама етиго с CreateProcess:


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.
Отговор
в отговор на Hateras #6

Re: Pchar,CMDline,string

Не ми се рови сега но си мисля, че символа ">" не е параметър на командния ред, а е инструкция към командния интерпретатор да пренасочи стандартния изход. В такъв случай трябва да се търси решение чрез структурата STARTUPINFO. Там някъде имаше начин да се укаже стандартния изход.

Отговор
в отговор на Hateras #7

Re: Pchar,CMDline,string

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

Отговор
в отговор на NDeu #8

На прав път си....

бях правил за 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;

---
Колкото повече, толкова повече.
Отговор
в отговор на PhantomAS #9

Re: На прав път си....

ej tva e qko naistina s pipe-a

Отговор