Solved

Running a DOS program from within a DELPHI program

Posted on 1997-08-19
9
181 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
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
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

816 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

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now