Solved

CreateProcess and sw_hide

Posted on 1999-01-26
10
1,425 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
  • 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
proper way to parse url in delphi 2 168
Wininet read php file from internet issue 6 83
Run video youtube webbrowse 10 58
URL for downloading Google Chrome for Win XP 2 126
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 I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…

863 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

22 Experts available now in Live!

Get 1:1 Help Now