Solved

Running a DOS program from within a DELPHI program

Posted on 1997-08-19
9
183 Views
Last Modified: 2010-04-04
I need to know how to run a DOS program (32-bit) from within a DELPHI 3.0 program.

Usually, the DOS program is run in a DOS window and accepts a command line parameter.  I need my program to automatically create such a window and to call the program together with its command line parameter.

I know about the CreateProcess function but I can't get it to work.  I would appreciate being able to look at a working example if you have one and don't mind parting with it.

Thanks in advance.

Len

0
Comment
Question by:LenB
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 5

Expert Comment

by:ronit051397
ID: 1341969
WinExec('c:\something.exe', SW_SHOW);
This command is 16bit based but it will work with delphi3.
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1341970
I only know something about it for Delphi 2.0 & Delphi 1.0 but I think Delphi 3.0 won't be that different from Delphi 2.0, I can give you some code, but there are a lot of components around with the full source and an example, so I think you can look at them first. If you still want some code, I can give it to you, but look at the next lines and proposals first :

This question is already asked for a 16bit environment. But there is also the answer for 32bit environments. It's a little bit difficult for 16bit. Because of that they proposed a component called XSpawn from HyperAct. It's freeware now and because of that they don't give support anymore. I took it from their site and i'm using it. The great thing of this component is that you can use it on every OS (Windows 3.1/3.11/95/NT, OS/2)

But if you just want a component (with source) for 32bit and windows 95 and NT you can also use the following component :

http://SunSITE.icm.edu.pl/delphi/ftp/d10free/execfl32.zip

I've also used this component, it's great with a good documentation. It's written by Kevin Savko


Hope you're something with this, if not just give a comment and I'll see what I can do.

                                                 ZifNab


0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1341971
Oh yes, something else. The component of Kevin Savko doesn't support the error codes of your dos program. I mean, if the DOS program gives an error when it exits, you can't get it. But that isn't a big deal, because I've changed the code a little bit, and now you can get the error code from the program. So if you want the changed code, just ask!
                              c.u. ZifNab

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:mirek071497
ID: 1341972
WinExec is for compatibility with 16bit programs but it call CreateProcess so can run all program's. Why you can't use this.
Try WinExec( 'your.exe param1 param2', SW_SHOW ) this work fine!
0
 
LVL 8

Accepted Solution

by:
ZifNab earned 50 total points
ID: 1341973
Hi all,

Sorry, but I thought WinExec, is only for windows-based applications, not DOS? Am I wrong? But try this, it' s the heart of Kevin Savko's code, which I earlier mentioned.


function TExecFile.Execute: Boolean;
var zCommandLine: array[0..512] of Char;
zFAssFName: array[0..255] of Char;
zFAssFDir: array[0..255] of Char;
zFAssFDoc: array[0..255] of Char;
FSuccess: Boolean;
begin

FillChar(StartupInfo,Sizeof(StartupInfo),#0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

If FWindowStyle = wsNorm then StartupInfo.wShowWindow := SW_SHOWNORMAL;
If FWindowStyle = wsMinimize then StartupInfo.wShowWindow := SW_SHOWMINIMIZED;
If FWindowStyle = wsMaximize then StartupInfo.wShowWindow := SW_SHOWMAXIMIZED;
If FWindowStyle = wsHide then StartupInfo.wShowWindow := SW_HIDE;
If FWindowStyle = wsMinNoActivate then StartupInfo.wShowWindow := SW_SHOWMINNOACTIVE;
If FWindowStyle = wsShowNoActivate then StartupInfo.wShowWindow := SW_SHOWNA;

If FPriorityClass = pcHigh then FPriorityValue := HIGH_PRIORITY_CLASS;
If FPriorityClass = pcIdle then FPriorityValue := IDLE_PRIORITY_CLASS;
If FPriorityClass = pcNormal then FPriorityValue := NORMAL_PRIORITY_CLASS;
If FPriorityClass = pcRealTime then FPriorityValue := REALTIME_PRIORITY_CLASS;

StrPCopy(zCommandLine,FCommandLine+' '+FFParams);

FSuccess := CreateProcess(nil,
      zCommandLine,           { pointer to command line string }
      nil,                    { pointer to process security attributes }
      nil,                    { pointer to thread security attributes }
      false,                  { handle inheritance flag }
      CREATE_NEW_CONSOLE or   { creation flags }
      FPriorityValue,
      nil,                    { pointer to new environment block }
      nil,                    { pointer to current directory name }
      StartupInfo,            { pointer to STARTUPINFO }
      ProcessInfo);

If not FSuccess then begin
 If FAss then begin StrPCopy(zFAssFDoc,FCommandLine);
  If findExecutable(zFAssFDoc,zFAssFDir,zFAssFName)<32 then begin
   FError := GetLastError(); If Assigned(FOnFail) then FOnFail(Self);
   Result := False; exit;
  end else begin FAssFName := zFAssFName;
   StrPCopy(zCommandLine,FAssFName+' '+FCommandLine+' '+FFParams);
   FSuccess := CreateProcess(nil,
      zCommandLine,           { pointer to command line string }
      nil,                    { pointer to process security attributes }
      nil,                    { pointer to thread security attributes }
      false,                  { handle inheritance flag }
      CREATE_NEW_CONSOLE or   { creation flags }
      FPriorityValue,
      nil,                    { pointer to new environment block }
      nil,                    { pointer to current directory name }
      StartupInfo,            { pointer to STARTUPINFO }
      ProcessInfo);
  end
 end;
end;

If FSuccess then begin
  If FWait then begin FIsWaiting := True; FStopWaiting := False;
   If FWaitStyle = wRegular then begin
    repeat
     While PeekMessage(FMsg,0,0,0,PM_REMOVE) do begin
     If FMsg.Message = WM_QUIT then halt(FMsg.wParam);
     TranslateMessage(FMsg); DispatchMessage(FMsg); end;
     If WaitforSingleObject(ProcessInfo.hProcess,0)<>WAIT_TIMEOUT then begin
     FStopWaiting := True; Application.ProcessMessages; end;
     Until FStopWaiting; end
   else begin
   WaitForSingleObject(ProcessInfo.hProcess,INFINITE); end;
  FIsWaiting := False; Result:= True; end;
end else begin
 FError := GetLastError(); If Assigned(FOnFail) then FOnFail(Self);
 Result := False; end;

end;
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1341974
ZifNab - Yes you are wrong !  WinExec is for dos program's too and work fine win WinNT too it is very easy for runnig program's. You must go to CreateProcess only if You need acces  to this new process (for example exit code or when you need terminate this process).
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1341975
Mirek & Len,

Mirek,

Thanks for correcting my mistake!
But as I can read from your comment, you need to use CreateProcess if you want the exit codes of a DOS program. Am I correct, because if not I'll get a heart attack? Then I've always  worked too much. And all that work can be combined in one code-line. Please don't say, that I've worked too much!!!

Len,

If you don't need the exit codes, if you just want to start a program, then please reject my answer and use mireks answer. That's far more easier!!! Otherwise, look at the examples I gave  you and see if they work out for you.

c.u.

ZifNab
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1341976
Hi ZifNab.
Sorry for my comment. You'r code is ok, but LenB don't say so must wait for terminate process and When reject answer from ronit he(/she) dont say why.
Of course you made mistake with words about WinExec.

p.s. Nice to see New Expert. Here are many qestions awaiting answers.
0
 

Author Comment

by:LenB
ID: 1341977
Thanks to all three Experts who commented on my question.

I apologize for not being specific enough about what I wanted.


The reason I was after a solution involving CreateProcess is as follows:

The DOS program is not interactive but processes instructions from a text file given as a command line parameter.  It can take a long time to run (2 to 60 minutes - depending on the instruction file).  Whilst running, it will be writing some stuff (text and numeric parameters) to its DOS window.  I would like the DOS window to be invisible, and to be able to capture this text and use dialog boxes to display the parameters as the DOS process runs.  

The DOS program does a lot of least-squares refinements on a lot of data, and if the Esc key is pressed, it will neatly jump to the next cycle.  If the Ctrl-C key is pressed, it will treat the current refinement as the last cycle and terminate neatly.
So, I would like to be able to feed either an Esc character or a Ctrl_C to the DOS window if the user wants to cut the run short (by pressing an appropriate button in a dialog box) - but I don't necessarily want the ability to kill the process outright.

I didn't think I would be able to do all this with a simple call to WinExec - but maybe I can?  I'm pretty new to Windows programming.


0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
select query - oracle 16 101
drawing animated level bar based on numbers 3 112
How to convert memory stream to PDF file 6 183
DBCtrlGrid, Delphi, Scroll 7 33
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question