Solved

CreateProcess and sw_hide

Posted on 1999-01-26
10
1,473 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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses
Course of the Month5 days, 23 hours left to enroll

627 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