comp.lang.ada
 help / color / mirror / Atom feed
From: "DuckE" <nospam_steved@pacifier.com>
Subject: Re: not really an Ada question (long answer)
Date: 2000/02/17
Date: 2000-02-17T00:00:00+00:00	[thread overview]
Message-ID: <38accd7b.0@news.pacifier.com> (raw)
In-Reply-To: Pine.A41.3.96-heb-2.07.1000215155013.63302B-100000@pluto.mscc.huji.ac.il

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;







      parent reply	other threads:[~2000-02-17  0:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-02-15  0:00 not really an Ada question Ehud Lamm
2000-02-16  0:00 ` Robert Dewar
2000-02-16  0:00   ` Ehud Lamm
2000-02-16  0:00     ` Ehud Lamm
2000-02-17  0:00       ` Charles Hixson
2000-02-17  0:00       ` Robert A Duff
2000-02-17  0:00 ` DuckE [this message]
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox