Recent

Author Topic: Need help with Runcommand and cmd.exe  (Read 12879 times)

rave08

  • Newbie
  • Posts: 3
Need help with Runcommand and cmd.exe
« on: January 05, 2016, 07:54:50 am »
Hello,

I did not introduce myself until now, so my name is Julian, I am 22 years old and I am living in Germany.
I learned how to program with Delphi 7 and then discovered Lazarus. And now I enjoy using Lazarus and doing some hobby projects.
I'm now working with Lazarus 1.4.4 and fpc 2.6.4 , Windows 7x64.

I often found answers to my questions in this Forum, but now I can't find an answer.

I have a problem with Runcommand (found here: http://wiki.freepascal.org/Executing_External_Programs)
 in combination with executing cmd.exe and parameters, it doesn't seem to work for me.


If i execute the example
Code: Pascal  [Select][+][-]
  1. RunCommand('c:\windows\system32\cmd.exe', ['/c', 'dir /s c:\windows'], s);
it just shows an empty black cmd window and nothing else happens.
Admin rights are not the problem as it doesn't work with d:\ either.

If I manually open a cmd window and input
Code: Pascal  [Select][+][-]
  1. dir /s c:\windows
it works and shows the content of c:\windows.
Code: Pascal  [Select][+][-]
  1.   ShellExecute(0, nil,Pchar('c:\windows\system32\cmd.exe'),Pchar('/c dir /s c:\windows'), nil, SW_SHOWNORMAL);    
this also works but I do not want to use shellexecute as the program continues and does not wait for the external program.


Can you please help me ?

Thanks in advance !




« Last Edit: January 05, 2016, 08:05:23 am by rave08 »

balazsszekely

  • Guest
Re: Need help with Runcommand and cmd.exe
« Reply #1 on: January 05, 2016, 08:47:21 am »
Hi rave08,

Try this:
Code: Pascal  [Select][+][-]
  1. uses Process;
  2.  
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. var
  5.   Process: TProcess;
  6. begin
  7.   Process := TProcess.Create(nil);
  8.   try
  9.     Process.Executable := 'cmd.exe';
  10.     Process.Parameters.Add('/c');
  11.     Process.Parameters.Add('dir');
  12.     Process.Parameters.Add('/s');
  13.     Process.Parameters.Add('c:\windows\');
  14.     Process.Options := Process.Options + [poWaitOnExit];
  15.     Process.Execute;
  16.   finally
  17.     Process.Free;
  18.   end;
  19.   ShowMessage('done');
  20. end;
  21.  


regards,
GetMem

balazsszekely

  • Guest
Re: Need help with Runcommand and cmd.exe
« Reply #2 on: January 05, 2016, 09:01:16 am »
If you want to go with ShellExecute use the Ex version instead:
Code: Pascal  [Select][+][-]
  1. uses JwaWindows, ShellApi;
  2.  
  3. procedure ExecuteAndWait(FileName, Params, Directory: WideString);
  4. var
  5.   SEInfo: TShellExecuteInfoW;
  6.   ExitCode: DWORD;
  7. begin
  8.   FillChar(SEInfo, SizeOf(SEInfo), 0) ;
  9.   SEInfo.cbSize := SizeOf(TShellExecuteInfoW) ;
  10.   with SEInfo do
  11.   begin
  12.     fMask := SEE_MASK_NOCLOSEPROCESS;
  13.     Wnd := Form1.Handle;
  14.     lpFile := PWideChar(FileName);
  15.     lpParameters := PWideChar(Params);
  16.     lpDirectory := PWideChar(Directory);
  17.     nShow := SW_SHOW;
  18.   end;
  19.   if ShellExecuteExW(@SEInfo) then
  20.   begin
  21.     repeat
  22.       Application.ProcessMessages;
  23.       GetExitCodeProcess(SEInfo.hProcess, ExitCode) ;
  24.     until (ExitCode <> STILL_ACTIVE) or  Application.Terminated;
  25.   end;
  26. end;
  27.  
  28. procedure TForm1.Button2Click(Sender: TObject);
  29. begin
  30.   ExecuteAndWait('c:\windows\system32\cmd.exe', '/c dir /s c:\windows\system32', '');
  31.   ShowMessage('ok');
  32. end;  
  33.  

You can even hide the cmd window by setting  nShow to SW_HIDE.

rave08

  • Newbie
  • Posts: 3
Re: Need help with Runcommand and cmd.exe
« Reply #3 on: January 05, 2016, 09:25:27 am »
Wow, thank you both for the fast answers, both are working fine for me :)

Just out of interest, any idea why the example from the wiki does not work ?


greetings, Julian

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12645
  • FPC developer.
Re: Need help with Runcommand and cmd.exe
« Reply #4 on: January 05, 2016, 10:01:41 am »
runcommand should capture the output in variable s ?

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Need help with Runcommand and cmd.exe
« Reply #5 on: January 05, 2016, 10:08:06 am »
runcommand should capture the output in variable s ?
It should, but doesn't seem to.

As TS mentioned, indeed runcommand seems 'stuck'.

I've tried with RunCommandInDir as well, and this also seems 'stuck'.

The console opens and a cursor is shown, but nothing else seems to happen. The program is simply 'stuck'. Only a ctrl-c/d is able to break it.

FPC trunk as well as 3.0 release.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Need help with Runcommand and cmd.exe
« Reply #6 on: January 05, 2016, 10:17:46 am »
I can confirm this issue through wine, when I change the command (after /c) to simply 'ver', then it works. Is the large output handling code inside runcommand buggy?

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12645
  • FPC developer.
Re: Need help with Runcommand and cmd.exe
« Reply #7 on: January 05, 2016, 10:21:03 am »
Not known buggy. There was a known issue with mixed output to stdin and stdout, but that fix is in 3.0 afaik.

Please file a bug.

rave08

  • Newbie
  • Posts: 3
Re: Need help with Runcommand and cmd.exe
« Reply #8 on: January 05, 2016, 11:13:59 am »
Please file a bug.

done....never did this before, hope it's correct.

http://bugs.freepascal.org/view.php?id=29338


By the way, I changed Getmem's code to a more General one...is this good code or any suggested improvements ?

Code: Pascal  [Select][+][-]
  1. uses process
  2. ...
  3. procedure processexecute(exepath:string; params:array of string);
  4. var
  5. Process: TProcess;
  6. i:integer;
  7. begin
  8.   Process := TProcess.Create(nil);
  9.   try
  10.     Process.Executable := exepath;
  11.     for i:=0 to high(params)do
  12.     Process.Parameters.Add(params[i]);
  13.     Process.Options := Process.Options + [poWaitOnExit];
  14.     Process.Execute;
  15.   finally
  16.     Process.Free;
  17.   end;
  18. end;
  19.  
  20.  
  21.  
  22. procedure TForm1.Button1Click(Sender: TObject);
  23. begin
  24.   processexecute('c:\Windows\System32\cmd.exe',['/c', 'dir', '/s', 'c:\windows']);
  25. end;  
  26.  
  27.  

//edit: it also works this way, without a Loop


Code: Pascal  [Select][+][-]
  1. procedure processexecute(exepath,params: string);
  2. var Process: TProcess;
  3. begin
  4.   Process := TProcess.Create(nil);
  5.   try
  6.     Process.Executable := exepath;
  7.     Process.Parameters.Add(params);
  8.     Process.Options := Process.Options + [poWaitOnExit];
  9.     Process.Execute;
  10.   finally
  11.     Process.Free;
  12.   end;
  13. end;
  14.  
  15. procedure TForm1.Button1Click(Sender: TObject);
  16. begin
  17.   processexecute('c:\Windows\System32\cmd.exe','/c dir /s c:\windows');
  18. end;  
  19.  

« Last Edit: January 05, 2016, 01:26:12 pm by rave08 »

PizzaProgram

  • Jr. Member
  • **
  • Posts: 60
  • ...developing Delphi apps since 25 years.
Re: Need help with Runcommand and cmd.exe
« Reply #9 on: December 14, 2025, 11:12:32 am »
An interesting fact: (after 10 years past, Lazarus 4.4 FPC 3.2.2)

Runcommand is still not on the top  :o
Spent 20+ hours to find out, that using it instead of direct TProcess is causing the problem.
(Followed the recommended way at the WIKI https://wiki.lazarus.freepascal.org/Executing_External_Programs#.28Process..29RunCommand )

It does not deal correctly with the parameters I've added.
 (If I copy the same to a standard Command window, everything is fine. Win2016 Server edition on a VPS.)

Code: Pascal  [Select][+][-]
  1.     e := 'C:\Program Files (x86)\Firebird\Firebird_2_5\bin\gfix.exe';
  2.     param := '-shut full -force 3 -USER SYSDBA -PASSWORD masterkey 10.8.10.10:E:\DEMO.FDB' ;
  3.  
  4.     if RunCommand(e, [param], s, [poWaitOnExit, poStderrToOutPut]) then
  5.         c := clLime
  6.     else
  7.         c := clRed;
  8.     Form1.AddLog('GFIX : '+ s, c);
  9.  

Also tried to separate the parameters in the array, it that case the output error listed only the first as error:
Quote
GFIX : invalid switch -shut full
please retry, specifying an option
plausible options are:
   -activate   activate shadow file for database usage
...

PS:
 I've added my post to this topic because it's first place at DuckDuckGo search
« Last Edit: December 14, 2025, 11:15:16 am by PizzaProgram »
x86_64-win64 --Win7 PRO 64bit HUN

Thausand

  • Sr. Member
  • ****
  • Posts: 458
Re: Need help with Runcommand and cmd.exe
« Reply #10 on: December 14, 2025, 12:45:28 pm »
It does not deal correctly with the parameters I've added.
That because is wrong parameter.

Quote
(If I copy the same to a standard Command window, everything is fine. Win2016 Server edition on a VPS.)
Runcommand not same function that have windows shell.

Quote
Also tried to separate the parameters in the array, it that case the output error listed only the first as error:
This is how work runcommand when not execute shell.

Quote
GFIX : invalid switch -shut full
And that is correct answer. -shut is no firebird option (no more)

https://www.firebirdsql.org/file/documentation/html/en/firebirddocs/gfix/firebird-gfix.html

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12645
  • FPC developer.
Re: Need help with Runcommand and cmd.exe
« Reply #11 on: December 14, 2025, 12:46:25 pm »
An interesting fact: (after 10 years past, Lazarus 4.4 FPC 3.2.2)

Runcommand is still not on the top  :o

Or you are doing something wrong.

Quote
It does not deal correctly with the parameters I've added.
 (If I copy the same to a standard Command window, everything is fine. Win2016 Server edition on a VPS.)

Unfortunately that doesn't say anything. But the parameters should be as separate parameters, every word.

So -shut is one, full is one, -force is one , 3 is one etc.  10.8.10.10:E:\DEMO.FDB is the last one, as a whole (no spaces in it).

Basically split by spaces, but when arguments with spaces come in to play, so does quoting, and that is a mess.

But if it is a simple case, and you are to lazy to split the arguments, let FPC do it:

Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2.  
  3. uses sysutils,process;
  4.  
  5. var s : string;
  6.  
  7. begin
  8.   RunCommand( 'C:\Program Files (x86)\Firebird\Firebird_2_5\bin\gfix.exe','-shut full -force 3 -USER SYSDBA -PASSWORD masterkey 10.8.10.10:E:\DEMO.FDB'.split([' ']),s);
  9.   WriteLn(s);
  10. end.
  11.  
« Last Edit: December 14, 2025, 01:00:41 pm by marcov »

 

TinyPortal © 2005-2018