views:

2015

answers:

2

I need to execute a Windows "find" command from a Delphi software. I've tried to use the ShellExecute command, but it doesn't seem to work. In C, I'd use the system procedure, but here... I don't know. I'd like to do something like this:

System('find "320" in.txt > out.txt');

Edit : Thanks for the answer :) I was trying to run 'Find' as an executable, not as argument for cmd.exe.

+5  A: 

An example using ShellExecute():

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShellExecute(0, nil, 'cmd.exe', '/C find "320" in.txt > out.txt', nil, SW_HIDE);
  Sleep(1000);
  Memo1.Lines.LoadFromFile('out.txt');
end;

Note that using CreateProcess() instead of ShellExecute() allows for much better control of the process.

Ideally you would also call this in a secondary thread, and call WaitForSingleObject() on the process handle to wait for the process to complete. The Sleep() in the example is just a hack to wait some time for the program started by ShellExecute() to finish - ShellExecute() will not do that. If it did you couldn't for example simply open a notepad instance for editing a file, ShellExecute() would block your parent app until the editor was closed.

mghie
Shouldn't that be Memo1.Lines.LoadFromFile('out.txt');
IanH
Indeed, thanks for spotting it.
mghie
Er, if the windows is hidden (SW_HIDE), why should we put a Sleep(1000) after the ShellExecute ?
gramm
I'm working with 100MB text files so I'm going for the WaitForSingleObject option. thanks ! :)
gramm
`ShellExecute()` will start the application but not wait for it to finish - otherwise you couldn't really use it to open a standard GUI program. It may not matter with running `find` on a small text file, but for longer executing tasks you have to make sure they are finished before you process the results in `out.txt`. That's why using `CreateProcess()` and waiting on the process handle is a much better way to do it.
mghie
Alternatively use ShellExecuteEx, which can be used with wait functions
Gerry
+3  A: 

If you want to catch the output, you're looking for CreateProcess, with the handles in place to catch standard-input:

http://www.delphi3000.com/articles/article%5F3361.asp (and many others if you Google around)

Stijn Sanders
Not necessary if the executed application accepts input from a file whose name is given as a parameter.
mghie
This IS the way to go. Redirect the output to your application and you circumvent problems with missing IO permissions and file deletion after processing the output.
Scoregraphic
@Scoregraphic: I agree that `CreateProcess()` is the way to go. Input redirection however isn't always necessary. Output redirection may be necessary, but that's for the OP to decide. There is value in developing only as much as strictly necessary.
mghie