* Re: not really an Ada question (long answer)
2000-02-15 0:00 not really an Ada question Ehud Lamm
2000-02-16 0:00 ` Robert Dewar
@ 2000-02-17 0:00 ` DuckE
1 sibling, 0 replies; 7+ messages in thread
From: DuckE @ 2000-02-17 0:00 UTC (permalink / raw)
Windows NT (and Windows 95) prefer "CreateProcess" for creating another
process. I have
attached an example I put together quite a while back for NT.
In this particular example I start up a process to act as a slave to the
calling program. The stdin, stdout, and stderror files are mapped to pipes
used to drive the process.
While this isn't exactly what you asked for, it does give a working example
of the use of "CreateProcess", which is I believe what you need. The code
does rely on the Win32Ada binding.
SteveD
==== Launch.adb ====
WITH Win32;
WITH Win32.WinBase;
WITH Win32.WinNT;
WITH System;
WITH Interfaces.C;
USE Interfaces.C;
WITH Interfaces.C.Strings;
USE Interfaces.C.Strings;
WITH Ada.Text_Io;
WITH NTSntServerProcess;
USE NTSntServerProcess;
PROCEDURE Launch IS
PACKAGE WinBase RENAMES Win32.WinBase;
PACKAGE WinNT RENAMES Win32.WinNT;
PACKAGE Text_Io RENAMES Ada.Text_Io;
USE TYPE Win32.BOOL;
result : Win32.BOOL;
stdInLocHandle : ALIASED WinNT.HANDLE;
stdOutLocHandle : ALIASED WinNT.HANDLE;
stdErrLocHandle : ALIASED WinNT.HANDLE;
inputBuffer : CHAR_ARRAY(0..255);
bytesRead : ALIASED Win32.DWORD;
BEGIN
CreateSubprocessNTS( commandDirNTS => "",
commandLineNTS => "c:\csrc\hello.exe",
workDirNTS => "c:\csrc",
windowNameNTS => "Window name",
stdInNTS => stdInLocHandle,
stdOutNTS => stdOutLocHandle,
stdErrNTS => stdErrLocHandle );
Text_Io.Put_Line( "=== Start of output ===" );
LOOP
result := WinBase.ReadFile( stdOutLocHandle,
inputBuffer(0)'ADDRESS,
Win32.DWORD( 2 ), -- inputBuffer'LENGTH ),
bytesRead'UNCHECKED_ACCESS,
NULL );
EXIT WHEN result <= 0;
Text_Io.Put( To_Ada( inputBuffer )(1..Integer( bytesRead ) ) );
END LOOP;
Text_Io.Put_Line( "=== End of output ===" );
Text_Io.Put_Line( "Result = " & Win32.BOOL'IMAGE( result ) );
CloseFilesNTS( stdOutLocHandle, stdOutLocHandle, stdErrLocHandle );
-- result := WinBase.CloseHandle( stdInProcHandle );
-- result := WinBase.CloseHandle( stdOutProcHandle );
-- result := WinBase.CloseHandle( stdErrProcHandle );
END Launch;
=========== NTSntServerProcess.ads =============
WITH Win32.WinNT;
PACKAGE NTSntServerProcess IS
PACKAGE WinNT RENAMES Win32.WinNT;
-- Creates a separate process such that the standard input, standard
output, and standard
-- error files are redirected to pipes, and returns the file handles
associated with those
-- pipes.
PROCEDURE CreateSubprocessNTS( commandDirNTS : in String;
commandLineNTS : in String;
workDirNTS : in String;
windowNameNTS : in String;
stdInNTS : out WinNT.HANDLE;
stdOutNTS : out WinNT.HANDLE;
stdErrNTS : out WinNT.HANDLE );
PROCEDURE CloseFilesNTS( stdInNTS : in WinNT.HANDLE;
stdOutNTS : in WinNT.HANDLE;
stdErrNTS : in WinNT.HANDLE );
END NTSntServerProcess;
=========== NTSntServerProcess ==============
WITH Win32;
WITH Win32.WinBase;
WITH Win32.WinNT;
WITH System;
WITH Ada.Characters.Latin_1;
WITH Interfaces.C;
USE Interfaces.C;
WITH Interfaces.C.Strings;
USE Interfaces.C.Strings;
WITH Win32.WinNT;
PACKAGE BODY NTSntServerProcess IS
PACKAGE WinBase RENAMES Win32.WinBase;
USE TYPE Win32.BOOL;
-- Creates a separate process such that the standard input, standard
output, and standard
-- error files are redirected to pipes, and returns the file handles
associated with those
-- pipes.
PROCEDURE CreateSubprocessNTS( commandDirNTS : in String;
commandLineNTS : in String;
workDirNTS : in String;
windowNameNTS : in String;
stdInNTS : out WinNT.HANDLE;
stdOutNTS : out WinNT.HANDLE;
stdErrNTS : out WinNT.HANDLE ) IS
result : Win32.BOOL;
commandDir : CHAR_ARRAY := To_C( commandDirNTS );
commandLine : CHAR_ARRAY := To_C( commandLineNTS );
currentDir : CHAR_ARRAY := To_C( workDirNTS );
windowName : CHAR_ARRAY := To_C( windowNameNTS );
startupInfo : ALIASED WinBase.STARTUPINFOA;
processInfo : ALIASED WinBase.PROCESS_INFORMATION;
stdInLocHandle : ALIASED WinNT.HANDLE;
stdOutLocHandle : ALIASED WinNT.HANDLE;
stdErrLocHandle : ALIASED WinNT.HANDLE;
tmpInLocHandle : ALIASED WinNT.HANDLE;
tmpOutLocHandle : ALIASED WinNT.HANDLE;
tmpErrLocHandle : ALIASED WinNT.HANDLE;
stdInProcHandle : ALIASED WinNT.HANDLE;
stdOutProcHandle : ALIASED WinNT.HANDLE;
stdErrProcHandle : ALIASED WinNT.HANDLE;
securityAttrib : ALIASED WinBase.SECURITY_ATTRIBUTES;
BEGIN
securityAttrib.nLength := WinBase.SECURITY_ATTRIBUTES'SIZE/8;
securityAttrib.bInheritHandle := Win32.TRUE;
securityAttrib.lpSecurityDescriptor := NULL;
result := WinBase.CreatePipe( stdInProcHandle'UNCHECKED_ACCESS,
tmpInLocHandle'UNCHECKED_ACCESS,
securityAttrib'UNCHECKED_ACCESS,
0 );
result := WinBase.DuplicateHandle( WinBase.GetCurrentProcess,
tmpInLocHandle,
WinBase.GetCurrentProcess,
stdInLocHandle'UNCHECKED_ACCESS,
0,
Win32.FALSE,
WinNT.DUPLICATE_SAME_ACCESS );
result := WinBase.CloseHandle( tmpInLocHandle );
result := WinBase.CreatePipe( tmpOutLocHandle'UNCHECKED_ACCESS,
stdOutProcHandle'UNCHECKED_ACCESS,
securityAttrib'UNCHECKED_ACCESS,
0 );
result := WinBase.DuplicateHandle( WinBase.GetCurrentProcess,
tmpOutLocHandle,
WinBase.GetCurrentProcess,
stdOutLocHandle'UNCHECKED_ACCESS,
0,
Win32.FALSE,
WinNT.DUPLICATE_SAME_ACCESS );
result := WinBase.CloseHandle( tmpOutLocHandle );
result := WinBase.CreatePipe( tmpErrLocHandle'UNCHECKED_ACCESS,
stdErrProcHandle'UNCHECKED_ACCESS,
securityAttrib'UNCHECKED_ACCESS,
0 );
result := WinBase.DuplicateHandle( WinBase.GetCurrentProcess,
tmpErrLocHandle,
WinBase.GetCurrentProcess,
stdErrLocHandle'UNCHECKED_ACCESS,
0,
Win32.FALSE,
WinNT.DUPLICATE_SAME_ACCESS );
result := WinBase.CloseHandle( tmpErrLocHandle );
startupInfo.cb :=
Win32.DWORD( WinBase.STARTUPINFOA'SIZE/8 );
startupInfo.lpReserved := NULL; --
startupInfo.lpDesktop := NULL;
startupInfo.lpTitle :=
windowName(windowName'FIRST)'UNCHECKED_ACCESS;
startupInfo.dwX := 0;
startupInfo.dwY := 0;
startupInfo.dwXSize := 0;
startupInfo.dwYSize := 0;
startupInfo.dwXCountChars := 0;
startupInfo.dwYCountChars := 0;
startupInfo.dwFillAttribute := 0;
startupInfo.dwFlags := WinBase.STARTF_USESTDHANDLES;
startupInfo.wShowWindow := 0;
startupInfo.cbReserved2 := 0;
startupInfo.lpReserved2 := NULL;
startupInfo.hStdInput := stdInProcHandle;
startupInfo.hStdOutput := stdOutProcHandle;
startupInfo.hStdError := stdErrProcHandle;
result := WinBase.CreateProcess(
NULL, -- LPCTSTR pointer to
name of executable module
commandLine(commandLine'FIRST)'UNCHECKED_ACCESS, -- LPTSTR
pointer to command line string
NULL, --
LPSECURITY_ATTRIBUTES pointer to process security attributes
NULL, -- LPSECURITY_ATTRIBUTES
pointer to thread security attributes
Win32.TRUE, -- BOOL handle inheritance
flag
WinBase.DETACHED_PROCESS, -- DWORD creation flags
NULL, -- LPVOID pointer to new
environment block
currentDir(currentDir'FIRST)'UNCHECKED_ACCESS, -- LPCTSTR pointer
to current directory name
startupInfo'UNCHECKED_ACCESS, -- LPSTARTUPINFO pointer to
STARTUPINFO
processInfo'UNCHECKED_ACCESS -- LPPROCESS_INFORMATION
pointer to PROCESS_INFORMATION
);
result := WinBase.CloseHandle( stdInProcHandle );
result := WinBase.CloseHandle( stdOutProcHandle );
result := WinBase.CloseHandle( stdErrProcHandle );
stdInNTS := stdInLocHandle;
stdOutNTS := stdOutLocHandle;
stdErrNTS := stdErrLocHandle;
END CreateSubprocessNTS;
PROCEDURE CloseFilesNTS( stdInNTS : in WinNT.HANDLE;
stdOutNTS : in WinNT.HANDLE;
stdErrNTS : in WinNT.HANDLE ) IS
result : Win32.BOOL;
BEGIN
-- result := WinBase.CloseHandle( stdInProcHandle );
-- result := WinBase.CloseHandle( stdOutProcHandle );
-- result := WinBase.CloseHandle( stdErrProcHandle );
result := WinBase.CloseHandle( stdInNTS );
result := WinBase.CloseHandle( stdOutNTS );
result := WinBase.CloseHandle( stdErrNTS );
END CloseFilesNTS;
END NTSntServerProcess;
^ permalink raw reply [flat|nested] 7+ messages in thread