Solved

CreateProcess and sw_hide

Posted on 1999-01-26
10
1,416 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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

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…
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…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

762 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

17 Experts available now in Live!

Get 1:1 Help Now