Delphi Pages Forums  

Go Back   Delphi Pages Forums > Delphi Forum > General

Lost Password?

Reply
 
Thread Tools Display Modes
  #1  
Old 06-13-2005, 11:28 AM
Ouiji Ouiji is offline
Senior Member
 
Join Date: Nov 2001
Location: US of A
Posts: 478
Send a message via AIM to Ouiji
Default Hide DOS Console Window / Prevent it From Showing

I am calling a command that runs in a DOS shell, and it runs fine, but it pops up.. and it really doesnt need to.

I am calling it with..




FProcess := TChildProc.Create( 'app.exe', 'nil ', SW_HIDE );

Even with SW_Hide it still shows the window. Any ideas?



The unit im using to define TChildProc.Create is below.






unit workingtunit2;

interface

uses
Windows, SysUtils, StrUtils;

resourcestring sSetStdHandleMsg = 'SetStdHandle(STD_INPUT_HANDLE, Value)';
resourcestring sCreatePipeMsg = 'Pipe.'+Chr(13)+Chr(13)+'CreatePipe(FChildStdoutRd , FChildStdoutWr, saAttr, 0)';
resourcestring sDuplicateHandleMsg = 'DuplicateHandle(GetCurrentProcess(), FChildStdoutRd, GetCurrentProcess(), @FChildStdoutRdDup, 0, False, DUPLICATE_SAME_ACCESS)';
resourcestring sCreateChildProcessMsg = 'CreateChildProcess(ExeName, CommadLine, FChildStdoutWr)';


type

ESetStdHandleErr = class(Exception);
ECreatePipeErr = class(Exception);
EDuplicateHandleErr = class(Exception);
ECreateChildProcessErr = class(Exception);

{ THandledObject }

{ This is a generic class for all encapsulated WinAPI's which need to call
CloseHandle when no longer needed. This code eliminates the need for
3 identical destructors in the TEvent, TMutex, and TSharedMem classes
which are descended from this class. }

THandledObject = class(TObject)
protected
FHandle: THandle;
public
destructor Destroy; override;
property Handle: THandle read FHandle;
end;

{ TMutex }

{ This class encapsulates the concept of a Win32 mutex. See "CreateMutex"
in the Win32 reference for more information }

TMutex = class(THandledObject)
public
constructor Create(const Name: string);
function Get(TimeOut: Integer): Boolean;
function Release: Boolean;
end;

{ TChildProc }
TChildProc = class(TObject)
FStdIn: THandle;
FStdOut: THandle;
FsaAttr: PSecurityAttributes;
FChildStdoutRd: THandle;
FChildStdoutWr: THandle;
FChildStdinRd: THandle;
FChildStdinWr: THandle;
piProcInfo: TProcessInformation;
private
function CreateChildProcess(ExeName, CommadLine: String; StdIn: THandle; StdOut: THandle; ShowWindow: word): Boolean;
public
constructor Create(ExeName, CommadLine: String; ShowWindow: word);
destructor Destroy; override;
function ReadStrFromChild(Timeout: Integer=1000): String;
function WriteToChild(Data: String; Timeout: Integer=1000): Boolean;
function Running: boolean;
end;

implementation

{ THandledObject }

destructor THandledObject.Destroy;
begin
if FHandle <> 0 then
CloseHandle(FHandle);
end;

{ TMutex }

constructor TMutex.Create(const Name: string);
begin
FHandle := CreateMutex(nil, False, PChar(Name));
if FHandle = 0 then abort;
end;

function TMutex.Get(TimeOut: Integer): Boolean;
begin
Result := WaitForSingleObject(FHandle, TimeOut) = WAIT_OBJECT_0;
end;

function TMutex.Release: Boolean;
begin
Result := ReleaseMutex(FHandle);
end;

{ TChildProc }

constructor TChildProc.Create(ExeName, CommadLine: String; ShowWindow: word);
Var
Tmp1, Tmp2: THandle;
begin
New(FsaAttr);
Try
FsaAttr.nLength:=SizeOf(SECURITY_ATTRIBUTES);
FsaAttr.bInheritHandle:=True;
FsaAttr.lpSecurityDescriptor:=Nil;
If not CreatePipe(FChildStdoutRd, FChildStdoutWr, FsaAttr, 0) Then
raise ECreatePipeErr.CreateRes(@sCreatePipeMsg)
Else
If not CreatePipe(FChildStdinRd, FChildStdinWr, FsaAttr, 0) Then
raise ECreatePipeErr.CreateRes(@sCreatePipeMsg)
Else
begin
If not DuplicateHandle(GetCurrentProcess(), FChildStdoutRd, GetCurrentProcess(), @Tmp1, 0, False, DUPLICATE_SAME_ACCESS) Then
raise EDuplicateHandleErr.CreateRes(@sDuplicateHandleMsg )
Else
If not DuplicateHandle(GetCurrentProcess(), FChildStdinWr, GetCurrentProcess(), @Tmp2, 0, False, DUPLICATE_SAME_ACCESS) Then
raise EDuplicateHandleErr.CreateRes(@sDuplicateHandleMsg )
Else
begin
CloseHandle(FChildStdoutRd);
CloseHandle(FChildStdinWr);
FChildStdoutRd:=Tmp1;
FChildStdinWr:=Tmp2;
If not CreateChildProcess(ExeName, CommadLine, FChildStdinRd, FChildStdoutWr, ShowWindow ) Then
raise ECreateChildProcessErr.CreateRes(@sCreateChildProc essMsg)
end;
end;
Finally
Dispose(FsaAttr);
End;
end;

function TChildProc.CreateChildProcess(ExeName, CommadLine: String; StdIn,
StdOut: THandle; ShowWindow: word): Boolean;
Var
siStartInfo: TStartupInfo;
begin
// Set up members of STARTUPINFO structure.
ZeroMemory(@siStartInfo, SizeOf(TStartupInfo));
siStartInfo.cb:=SizeOf(TStartupInfo);
siStartInfo.hStdInput:=StdIn;
siStartInfo.hStdOutput:=StdOut;
siStartInfo.dwFlags:=STARTF_USESTDHANDLES;
//siStartInfo.wShowWindow := ShowWindow;
// Create the child process.
Result:=CreateProcess(Nil,
PChar(ExeName+' '+CommadLine), // command line
Nil, // process security attributes
Nil, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
Nil, // use parent's environment
Nil, // use parent's current directory
siStartInfo, // STARTUPINFO pointer
piProcInfo); // receives PROCESS_INFORMATION
end;

destructor TChildProc.Destroy;
begin
CloseHandle(FChildStdoutRd);
CloseHandle(FChildStdoutWr);
CloseHandle(FChildStdinRd);
CloseHandle(FChildStdinWr);
end;

function TChildProc.ReadStrFromChild(Timeout: Integer): String;
Var
i: Integer;
dwRead, BufSize, DesBufSize: DWORD;
chBuf: PChar;
Res: Boolean;
begin
Try
BufSize:=0;
New(chBuf);
Repeat
For i:=0 to 9 do
begin
Res:=PeekNamedPipe(FChildStdoutRd, nil, 0, nil, @DesBufSize, nil);
Res:=Res and (DesBufSize > 0);
If Res Then
Break;
Sleep(Round(Timeout/15));
end;
If Res Then
begin
If DesBufSize > BufSize Then
begin
FreeMem(chBuf);
GetMem(chBuf, DesBufSize);
BufSize:=DesBufSize;
end;
Res:=ReadFile(FChildStdoutRd, chBuf^, BufSize, dwRead, Nil);
Result:=Result+LeftStr(chBuf, dwRead);
end;
Until not Res;
Except
Result:='Read Err';
End;
end;


function TChildProc.Running: boolean;
var
tmpHandle: THandle;
begin
tmpHandle := OpenProcess( PROCESS_QUERY_INFORMATION, false,
piProcInfo.dwProcessId );

if tmpHandle > 0 then
begin
Result := true;
CloseHandle( tmpHandle );
end
else
Result := false;
end;

function TChildProc.WriteToChild(Data: String; Timeout: Integer=1000): Boolean;
Var
dwWritten, BufSize: DWORD;
chBuf: PChar;
begin
chBuf:=PChar(Data+Chr($0D)+Chr($0A));
BufSize:=Length(chBuf);
Result:=WriteFile(FChildStdinWr, chBuf^, BufSize, dwWritten, Nil);
Result:=Result and (BufSize = dwWritten);
end;

end.



"not quite smart enough to be dumb"
Reply With Quote
  #2  
Old 06-13-2005, 11:42 AM
douglas douglas is offline
Senior Member
 
Join Date: Jul 2001
Posts: 7,695
Default RE: Hide DOS Console Window / Prevent it From Showing

Execute the app with createprocess and specify DETACHED_PROCESS
for the dwCreationFlags parameter:




if not CreateProcess(nil, { pointer to application name }
PChar(Cmdline), { pointer to command line string }
nil, { pointer to process security attributes}
nil, { pointer to thread security attributes}
false, { handle inheritance flag }
DETACHED_PROCESS { creation flags }
nil, { pointer to new environment block}
nil, { pointer to current directory name}
StartupInfo, { pointer to STARTUPINFO}
ProcessInfo) then Result := null { pointer to PROCESS_INF }
else Result := ProcessInfo.hProcess;



If this Helps!, please accept as Answer!

UnSysApps
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump


All times are GMT. The time now is 11:43 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.