Forum > Beginners

Launching external CMD application, and waiting for it to exit?

(1/2) > >>

FiftyTifty:
Got a wee bit of an issue with both ExecuteProcess, and ShellExecute. I've made a command line tool, which calls another command line tool.

Here are the calls:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---ExecuteProcess(strAppDir + 'bsarch.exe', strCommandLine, []);                 if ShellExecute(0, nil, PChar(strAppDir + 'bsarch.exe'), PChar(strCommandLine), nil, 1) > 32 then        WriteLn('BSArch Success! ');
The commands are valid. But there are two problems.

ExecuteProcess Needs the file to have all permissions for user accounts, which is a total faff for the end user. Especially when I'm not writing to the file, just reading it. There is no documentation for TExecuteFlags, so I've no idea what to put in [].

ShellExecute Works, but the external program is ran and my code continues after it has launched. What I want to do, is run the program, and wait for it to close automatically.

How do I go about this?

Bart:
Why not use TProcess?
Include opWaitForExit in it's options.

Bart

marcov:
TProcess (and its easier sibbling Runcommand) also use CreateProcess, so the permissions probably also be a problem there.

But if the permissions for the target differ from your own, keeping control over it will be hard any which way, since if you could launch an executable with higher permissions yet control it, you essentially would have increased your permissions?

FiftyTifty:

--- Quote from: Bart on April 11, 2022, 06:43:46 pm ---Why not use TProcess?
Include opWaitForExit in it's options.

Bart

--- End quote ---

TProcess Looked like a bit of a cludge, while the other two commands looked much easier to work with. I won't be needing to capture the output, so it should be okay if I use the simple example from with Wiki, yeah?


--- Quote from: marcov on April 11, 2022, 06:58:02 pm ---TProcess (and its easier sibbling Runcommand) also use CreateProcess, so the permissions probably also be a problem there.

But if the permissions for the target differ from your own, keeping control over it will be hard any which way, since if you could launch an executable with higher permissions yet control it, you essentially would have increased your permissions?

--- End quote ---

It's odd. If I call the program from CMD, it works just fine with the exact same arguments. But if I call it through ExecuteProcess(), it doesn't work. But ShellExecute does?

I'd like to have a go at ShllExecuteEx, but the docs were designed with a Forms application, rather a command line one like I've got. Any idea how I work with that?

Edit: TProcess was the way to go. It just works. Here's my code that calls it:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure ExtractArchives(out tstrlistArchives: TStringList);var   processBSArch: TProcess;   strCommandLine, strCurrent: string;   iCounter: integer;begin   FindAllFiles(tstrlistArchives, strAppDir, '*.bsa', false);   for iCounter := tstrlistArchives.Count - 1 downto 0 do begin     strCurrent := StringReplace(ExtractFileName(tstrlistArchives[iCounter]), '.bsa', '', []);     WriteLn( 'Found archive: ' + strCurrent );     if tstrlistBSAArchiveNames.IndexOf( strCurrent ) = -1 then        tstrlistArchives.Delete(iCounter);   end;   WriteLn('Number of archives: ' + IntToStr(tstrlistArchives.Count));   for iCounter := 0 to tstrlistArchives.Count - 1 do begin     WriteLn('Iterating!');     processBSArch := TProcess.Create(nil);          processBSArch.Options := processBSArch.Options + [poWaitOnExit];     strCurrent := tstrlistArchives[iCounter];     WriteLn(strCurrent);     strCurrent := StringReplace(strCurrent, '.bsa', '', []);    CreateDir(strCurrent);     strCommandLine := strAppDir + 'bsarch.exe ' + 'unpack "' +                                                                        tstrlistArchives[iCounter] + '" "' + strCurrent + '\"';     WriteLn(strCommandLine);           processBSArch.Executable := strCommandLine;    processBSArch.Execute;     processBSArch.Free;   end; end;

Zvoni:
Your Line 10 to 19
How is that supposed to work?
FindAllFiles returns the Full path to a File (e.g. "c:\test\SomeFolder\SomeFile.bsa")
In Line 12 you extract the Filename ("SomeFile.bsa") and remove the Extension, resulting in "SomeFile"
In Line 16 you look in your StringList for the Index of "SomeFile" --> which is never going to be found! resulting in, basically, emptying out the StringList again.

Or did i miss something?

Navigation

[0] Message Index

[#] Next page

Go to full version