Solved

CreateProcess and sw_hide

Posted on 1999-01-26
10
1,458 Views
Last Modified: 2008-02-01
Hi All,

I need to execute um App using CreateProcess() but I want the window of the app be in "sw_hide" or another one I can select. So I need to know the parameters.
Note that I'm using this to execute one "ARJ a -je -y app.exe app.ext" and again to "app.exe -y" so it generates one MS-DOS prompt.
I'm not using WinExec because I'll wait until the decompression finish to start another tasks.

regards
Paulo
0
Comment
Question by:sergio_2001
[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
  • 4
  • 4
  • 2
10 Comments
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1363407
sergio:

Pass a StartUpInfo structure to CreateProcess with wShowWindow = False (you also need to set dwFlags as shown in the code fragment below)

Var
    StartupInfo: TStartupInfo;

begin
    With StartupInfo Do Begin
      cb := 18; lpReserved := Nil;     { Must be Null }
      lpDesktop := Nil; lpTitle := Nil;
      dwX := 0;     dwY := 0;     { Ignored unless dwFlags STARTF_USEPOSITION }
      dwXSize := 0; dwYSize := 0; { Ignored unless dwFlags STARTF_USESIZE }
      dwXCountChars := 0;    { Ignored unless dwFlags STARTF_USECOUNTCHARS }
      dwYCountChars := 0;    { Ignored unless dwFlags STARTF_USECOUNTCHARS }
      dwFillAttribute := 0;  { Ignored unless dwFlags STARTF_USEFILLATTRIBUTE }
      dwFlags := 0;
      wShowWindow := 0;      { Ignored unless dwFlags STARTF_USESHOWWINDOW }
      cbReserved2 := 0;      { Must be Zero }
      lpReserved2 := Nil;    { Must be Null }
      hStdInput  := 0;       { Ignored unless dwFlags STARTF_USESTDHANDLES }
      hStdOutput := 0;       { Ignored unless dwFlags STARTF_USESTDHANDLES }
      hStdError  := 0;       { Ignored unless dwFlags STARTF_USESTDHANDLES }
    End;

    ProcCreated := CreateProcess(Nil, FullPath,
                                 Nil, Nil, False, Normal_Priority_Class,
                                 Nil, Nil, StartupInfo, ProcessInfo);



Cheers,

Raymond,
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1363408
Perhaps this helps?

unit runThread_;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, tools, ddraw,
  ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen}
  public
    { Public-Deklarationen}
  end;

var Form1 : TForm1 = nil;

implementation

{$R *.DFM}

const unitName = 'runThread_.';

type TRunThread = class(TThread)
  private
    processHandle : cardinal;
    processReady  : boolean;
    waitingThread : cardinal;
    procedure Execute; override;
  end;

procedure TRunThread.Execute;
begin
  WaitForSingleObject(processHandle,INFINITE);   // This call does not return, unless copy is stopped
  processReady:=true;                            // Set "processReady" flag for main thread
  PostThreadMessage(waitingThread,WM_NULL,0,0);  // Wake up main thread
                                                 // If you call Application.HandleMessage (see below) in the
                                                 // main thread, the main thread is sleeping the most time in
                                                 // winAPI "waitMessage". So we send a "dummy" message in order
                                                 // to let the main thread return from Application.HandleMessage
end;

procedure TForm1.Button1Click(Sender: TObject);
var si : TStartupInfo;
    pi : TProcessInformation;
begin
  caption:='start copy...';
  ZeroMemory(@si,sizeOf(si)); si.cb:=sizeOf(si);
  si.dwFlags:=STARTF_USESHOWWINDOW; si.wShowWindow:=SW_HIDE;
  if CreateProcess(nil,'c:\command.com /c copy c:\autoexec.bat c:\test.bat >c:\output.txt',nil,nil,false,0,nil,nil,si,pi) then begin
    caption:='copy started...';
    with TRunThread.Create(true) do         // create the thread object, but do not start it now...
      try
        processHandle:=pi.hProcess;         // tell the thread what process it has to watch
        processReady:=false;                // flag for the loop (see below)
        waitingThread:=GetCurrentThreadID;  // the current threadID for the wakeup message (see above)
        caption:='wait for copy...';
        Resume;                             // now all information is prepared; so let's start the thread
        repeat
          Application.HandleMessage;        // message loop
        until Application.Terminated or processReady;  // continue with normal program when either the
                                                       // started process has stopped or our program is closed
        caption:='copy stopped...';
      finally Free end;
    CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Never forget to close handles...
    caption:='ready...';
  end else caption:='could not start copy...';
end;

end.

Regards, Madshi.
0
 

Author Comment

by:sergio_2001
ID: 1363409
Hi rwilson,

I'll evaluate your answer as soon as possible. I'm without time right now.

regards
Paulo

0
Independent Software Vendors: 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 12

Expert Comment

by:rwilson032697
ID: 1363410
Sergio: I'm in no hurry. When you have it all going to your satisfaction come back and grade it.

Cheers,

Raymond.

0
 

Author Comment

by:sergio_2001
ID: 1363411
Madshi,

Your answer almost fit my needs but If I use  si.dwFlags:=STARTF_USESHOWWINDOW;
si.wShowWindow:=SW_HIDE;
the program never finish. I use
si.wShowWindow:=SW_normal;
to close the DOS window after compression so the program continues.
There are any problem in this loop that can't detect the thread finish
repeat
      Application.HandleMessage;                     // message loop
until Application.Terminated or processReady;  // continue with normal...

regards
Paulo
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1363412
sergio,

have you tried running my example?
I think, "your" dos program doesn't quit automatically. You'll have to configure it in that way that it really terminates when all work is done (like 'c:\command.com /c copy c:\autoexec.bat c:\test.bat >c:\output.txt' does). The thread finish detection works fine. The problem MUST be that the dos program is simply not terminated.
Hmm. Which dos program do you start? Perhaps you just have to change some settings?

Regards, Madshi.
0
 

Author Comment

by:sergio_2001
ID: 1363413
Madshi,

I didn't tried your example. I'm sure it works. I'm using ARJ to compress files.
If I create one .pif configured to close the app it works fine but If I can close the program automatically would be better. Anyway send me the answer to grade you.

regards Paulo.
0
 
LVL 20

Accepted Solution

by:
Madshi earned 50 total points
ID: 1363414
Thank you, Paulo.

You could automatically terminate ARJ (using TerminateProcess). However, WHEN do you want to close it? You can't ask if it is ready, if it is not configured to close automatically...   :-(

Regards, Madshi.
0
 

Author Comment

by:sergio_2001
ID: 1363415
Madshi,

Why do you use:
 var Form1 : TForm1 = nil;  // = nil???

and:
      const unitName = 'runThread_.';

regards
Paulo

0
 
LVL 20

Expert Comment

by:Madshi
ID: 1363416
Hi Paolo,

you can delete both the "= nil" and the "const unitName...".
In bigger projects I'm creating the forms dynamically. Then I have to check whether Form1 is already created or not. I guess Delphi sets Form1 automatically to "nil", but I wanted to be sure.
Then I'm using a kind of exception stack in my bigger projects, where I need such a constant in every unit...   :-)

Regards, Madshi.
0

Featured Post

Technology Partners: 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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

734 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