LazarusCompleteGuide:10.1

From 흡혈양파의 번역工房
Jump to navigation Jump to search

프로세스

프로세스는 다른 프로세스를 생성할 수 있다. 프로세스는 Windows, MacOS X, Unix/Linux에서 독립적 프로그램으로 간주되므로 프로그램이 다른 프로그램을 호출하여 새 프로세스 인스턴스를 생성함을 의미한다. 이를 위해선 운영체제가 필요한 커널 객체를 초기화하고 개별적 어드레스 공간을 이용할 수 있도록 만들어야 한다. 특히 Windows에서는 새 프로세스를 시작할 수 있는 여러 편리한 방법들이 제공된다. 그 중 가장 복잡한 방법은 CreateProcess API 가 제공한다. 파스칼에서 이것은 아래와 같이 캡슐화된다:

function CreateProcess(
           lpApplicationName   : PChar;
           lpCommandLine       : PChar;
           lpProcessAttributes,
           lpThreadAttributes  : PSecurityAttributes;
           bInheritHandles     : Bool;
           dwCreationFlags     : DWord;
           lpEnvironment       : Pointer;
           lpCurrentDirectory  : PChar;
           const lpStartupInfo : TStartupInfo;
           var lpProcessInformation : TProcessInformation) : Bool; StdCall;


라자루스는 Win32 API 함수에 대해 TProcess 라 불리는 래퍼(wrapper)를 제공한다. 이는 새 프로그램의 호출을 직접 제어한다. 다수의 옵션을 가진 그 정의에서 볼 수 있듯이, 우리는 많은 방법으로 새 프로그램의 시작에 영향을 미칠 수 있지만, LCL 래핑(wrapping) 덕분에 염려할 필요가 없다.


TProcess 컴포넌트는 많은 프로퍼티를 포함하는데, 대부분은 Windows API 함수 CreateProcess 의 인수와 일치한다.


이러한 프로퍼티를 간략하게 설명하자면:

  • Active: 해당 부울(Boolean) 프로퍼티가 True 일 경우, 프로그램은 명시된 옵션으로 실행될 것이다. 이는 Execute 메소드의 호출과 일치한다. 프로퍼티가 False 일 경우, 실행 중인 애플리케이션이 끝난다.
  • ApplicationName: 이 문자열 프로퍼티는 실행되어야 할 프로그램의 정확한 이름을 Windows에서 요하는 구문으로 포함한다. Windows는 실행될 프로그램을 경로에서 검색하지 않는다. 완전한 경로가 주어지지 않은 경우 현재 디렉터리만 검색한다. 확장자를 명시할 필요가 없다ㅡWindows는 기본적으로 .exe 파일로 가정한다. 이 프로퍼티는 빈값으로 놔둘 수도 있다.
    예제: C:\Windows\notepad.exe.
  • CommandLine: 해당 프로퍼티는 애플리케이션이 보게 될 명령 행을 포함한다. 이는 프로그램 이름 뒤에 프로그램으로 전송될 옵션으로 구성된다. Windows는 실행될 프로그램을 경로에서 검색한다. 비어 있을 경우, ApplicationName 프로퍼티가 대신 사용된다.
    예제: notepad process.pas
  • ConsoleTitle: 애플리케이션이 콘솔 프로그램일 경우, 이 문자열을 그 콘솔 창의 제목으로 이용할 것이다. 비어 있을 경우, 실행 가능 프로그램의 이름이 창 제목으로 사용될 것이다.
  • CurrentDirectory: 이 문자열 프로퍼티는 프로세스에 대한 시작 디렉터리를 명시한다. 설정 시, 프로그램의 시작 디렉터리는 이 값으로 설정될 것이다. 미설정 시, 호출하는 프로세스의 현재 디렉터리가 사용될 것이다.
  • Desktop: Windows NT에서 (Windows 2000에서도 어쩌면 가능) 이것은 애플리케이션의 초기 창이 표시될 데스크톱의 이름이다.
  • Environment: 새 프로세스에 대한 환경 변수로 사용될 Name=Value 쌍의 리스트. 리스트가 빈 경우 현재 프로세스의 환경이 사용될 것이다.
  • FileAttribute: 애플리케이션의 콘솔에 대한 초기 전경색과 배경색. 해당 옵션은 suoUseFillAttributes 값이 StartupOption 에 입력되었을 경우에만 사용할 수 있다. 해당 옵션에 관한 상세한 정보는 Win32 API Reference의 STARTUPINFO 레코드 도움말에서 찾을 수 있다.
  • InheritHandles: True 일 경우, 새 애플리케이션이 현재 애플리케이션의 모든 (파일) 핸들을 상속할 것이다. False 일 경우, 새로운 핸들 집합이 생성될 것이다.
  • Options: 옵션 집합으로, 각 옵션을 끄고 켤 수 있다. 상세한 내용은 후에 설명하겠다.
  • Priority: 생성할 프로세스의 스케줄링 우선순위. 표준 값은 ppNormal 이고 그 외 ppHigh, ppIdle, ppRealTime 값이 있다.
  • StartUpOptions: 이것은 애플리케이션이 실행 시 어떤 창 프로퍼티가 시행될 것인지를 제어한다. 옵션이 포함될 경우, 그에 일치하는 프로퍼티가 시행될 것이다.
  • ShowWindow: 생성된 프로세스의 창이 어떻게 표시될 것인지 결정한다. 값은 이름으로 그 기능을 알 수 있다. StartupOptions 가 suoUseWindow 값을 포함하지 않을 경우 해당 프로퍼티는 무시될 것이다.
  • WindowColumns 와 WindowRows: 콘솔 프로그램의 경우 이 값들은 콘솔 버퍼 내 행과 열의 수를 결정한다. StartupOptions가 WindowHeight 와 WindowWidth 값을 포함하지 않는 한 해당 프로퍼티는 무시된다.
  • WindowHeight 와 WindowWidth: 초기 창의 높이와 너비를 (픽셀) 결정한다. StartupOptions 는 효과를 나타내기 위해선 suoUseSize 값을 포함해야 한다.
  • WindowLeft, WindowTop: 초기 창의 상단 좌측 위치를 설정한다 (픽셀). StartupOptions 가 suoUsePosition 값을 포함하지 않을 경우 해당 프로퍼티는 무시된다.


모든 프로퍼티가 설정되었다면 컴포넌트의 Execute 메소드를 이용해 외부 프로그램을 호출할 수 있다.

옵션 영향을 받는 프로퍼티
suoUseShowWindow ShowWindow
suoUseSize WindowHeight, WindowWidth
suoUsePosition WindowTop, WindowLeft
suoUseCountChars WindowColumns, WindowRows
suoUseFillAttributeFill Attribute
표 10.1: StartupOptions Flags의 효과


Options 프로퍼티는 프로세스가 시작될 때 어떤 일이 발생할 것인지를 제어한다. 이 프로퍼티는 아래 요소 중 하나 또는 이상을 포함한 집합이다:

  • poRunSuspended: 프로세스가 생성될 때 일시정지(suspend) 상태에 있을 것이다; 즉, 프로그램은 Resume(다시시작) 명령을 수신할 때까지는 실행되지 않는다. 이 명령은 TProcess.Resume 메소드에 의해 프로세스로 전송된다. 이 옵션은 poWaitOnExit 옵션과 결합할 수 없다.
  • poWaitOnExit: 프로세스가 생성된 후 Execute 메소드가 호출될 경우, WaitOnExit 메소드를 호출함으로써 프로세스가 끝날 때가지 기다릴 것이다. 이 메소드는 poRunSuspended 옵션과 함께 사용할 수 없다.
  • poUsePipes: 새로 생성된 프로그램의 표준 입/출력 파일 기술자(descriptor)가 파이프(pipe)로 전환될 것이다.
  • poStderrToOutPut: 파이프가 생성될 때 동일한 파이프가 표준 오류 및 표준 출력 파일 기술자에 사용될 것이다. 따라서 동일한 스트림으로부터 표준 출력과 표준 오류를 모두 읽는 것이 가능해진다.
  • poNoConsole: 콘솔 애플리케이션용: 생성된 프로세스는 호출하는 애플리케이션의 콘솔로 접근이 허용되지 않는다. 이 옵션은 파이프로 이용해야 한다. poNewConsole 옵션과 함께 사용할 수 없다.
  • poNewConsole: 생성될 프로세스에 새 콘솔을 생성한다. 이 옵션은 poNoConsole 옵션과 함께 사용할 수 없다.
  • poDefaultErrorMode: 호출하는 프로세스의 오류 모드가 아니라 새 오류 모드의 생성이다. 이 옵션에 대한 상세한 정보는 CreateProcess 함수를 참고한다.
  • poNewProcessGroup: 새 프로세스 그룹을 생성한다. 이 옵션에 대한 상세한 정보는 CreateProcess 함수를 참고한다.
  • poDebutProcess: 현재 프로세스가 디버거(debugger)일 경우, 이 옵션은 생성될 프로세스로부터 디버그 이벤트의 수신을 허용한다.
  • poDebugOnlyThisProcess: 현재 프로세스가 디버깅되고 있을 경우, CreateProcess 가 생성한 프로세스도 디버깅하는 것이 기본 행위이다. 이 옵션은 이러한 일을 미연에 방지하여 새 프로세스가 디버깅되지 않도록 한다.


또한 프로세스가 실행 중이거나 끝난 후에 아래 published 프로퍼티를 살펴볼 수 있겠다.

  • IsRunning: 프로세스가 실행 중인지 끝났는지 나타낸다.
  • ProcessInformation: Windows가 리턴한 프로세스 정보.
  • Handle: 새로 생성된 프로세스의 핸들. (프로세스 정보 레코드이다.)
  • ExitStatus: 프로세스가 끝난 후 리턴 상태(return status)를 제공한다.
  • ThreadHandle: 프로세스의 메인 스레드의 핸들을 리턴한다. 이 핸들은 프로세스의 일시정지(suspending), 재시작(resuming), 또는 종료에 이용할 수 있다.


poUsePipes 옵션이 TProcess.Options 프로퍼티에 포함된 경우, 새 프로세스의 표준 입력, 출력, 표준 오류에 대해 새 스트림이 생성될 것이다:

  • Input: 새로 생성된 프로세스의 입력 파일을 쓰기 위한 스트림 자손. 정보를 전송 후 스트림을 해제(release)하는 것이 중요하며, 이를 어길 시 프로세스는 파일 조건(file condition) 끝을 감지할 수 없게 된다.
  • Ouput: 새로 생성된 프로세스가 표준 출력 파일로 쓰는 데이터를 읽기 위한 스트림 자손.
  • StdErr: 새로 생성된 프로세스가 표준 오류 파일로 쓰는 데이터를 읽기 위한 스트림 자손.


poStdErrToOutput 상수가 Options에 포함된 경우, Output 과 StdErr 가 동일한 스트림으로 전송될 것이다.


새로 생성된 프로세스는 그 표준 입력, 출력, 오류 파일로 접근하기 위해 표준 핸들을 사용해야 함을 명심하도록 한다. 프로세스가 이러한 파일 기술자들을 사용하지 않을 시, 호출하는 프로세스에 파이프 스트림을 읽거나 쓰는 것이 차단될 것이다. 델파이로 생성한 프로그램들은 입력 및 출력 파일에 이러한 표준 파일 기술자를 사용하지 않는 반면 프리 파스칼로 생성한 콘솔 애플리케이션들은 사용한다. 이러한 표준 파일 기술자들은 아래 호출로 얻을 수 있다:

  var StdInputHandle, StdOutputHandle, StdErrorHandle: INTEGER;
begin
  StdInputHandle  := GetStdHandle(STD_INPUT_HANDLE);
  StdOutputHandle := GetStdHandle(STD_OUTPUT_HANDLE);
  StdErrorHandle  := GetStdHandle(STD_ERROR_HANDLE);
end;


이러한 핸들을 이용해 THandleStream을 생성하거나, SysUtils 유닛으로부터 파일 처리 루틴을 호출할 수 있다.

메소드 설명
Execute 프로세스를 생성한 후 각 프로퍼티에 설명된 파라미터로 프로세스를 실행한다.
CreateProcess 호출이 실패할 경우 예외가 발생한다. poWaitOnExit 옵션이 활성화되면 호출자 애플리케이션은 생성된 프로세스가 끝날 때까지 Execute로의 호출에서 중단된 채로 남는다.
Suspend 실행되는 프로세스의 일시정지 계수기(suspend counter)를 증가시킨다. 결과적으로 함수는 이 숫자를 리턴하고, 값이 0이 아닐 경우 생성된 프로세스는 중단될 것이다.
Resume 실행되는 프로그램의 일시정지 계수기(suspend counter)를 감소시킨다. 결과적으로 함수는 이 숫자를 리턴하고, 값이 0일 경우 생성된 프로세스는 다시 시작될 것이다.
Terminate(AExitCode: Integer) 이 함수는 Process의 실행을 중단한다. AExitCode 종료 코드(exit code)로 닫는다. 함수는 성공할 경우 True를 리턴하고, 실패할 경우 False를 리턴한다.
WaitOnExit 이 함수는 우선 기다리다가, 생성된 프로그램이 완료될 때만 리턴한다. 이 함수는 성공 여부에 따라 부울 값을 리턴할 것이다. 윈도우에서 함수가 실패한다면 WaitForSingleObject의 함수에 문제가 생겼을 가능성이 큰 반면 UNIX에서 실패한다면 fpWaitPid 함수에 문제로 인해 야기되었을 것이다.
표 10.2: TProcess의 메소드


TProcess 컴포넌트의 public 메소드와 함수를 표 10.2에 요약하였다. 이 컴포넌트는 용도가 다양하지만 매우 복잡하기도 하여 그와 관련된 정의를 다시 한 번 요약하고자 한다:

type
  TProcessOption = (poRunSuspended,     poWaitOnExit,
                    poUsePipes,         poStderrToOutPut,
                    poNoConsole,        poNewConsole,
                    poDefaultErrorMode, poNewProcessGroup,
                    poDebugProcess,     poDebugOnlyThisProcess);

  TShowWindowOptions = (swoNone, swoHIDE, swoMaximize, swoMinimize,
             swoRestore, swoShow, swoShowDefault, swoShowMaximized,
                   swoShowMinimized, swoshowMinNOActive, swoShowNA,
                                 swoShowNoActivate, swoShowNormal);

  TStartupOption = (suoUseShowWindow, suoUseSize, suoUsePosition,
                            suoUseCountChars, suoUseFillAttribute);

  TProcessPriority = (ppHigh, ppIdle, ppNormal, ppRealTime);

  TProcessOptions = set of TProcessOption;
  TStartupOptions = set of TStartupOption;

type
  TProcess = Class(TComponent)
  private // omitted
  protected // omitted
  public
    constructor Create (AOwner : TComponent); Override;
    destructor Destroy; Override;
    procedure Execute; Virtual;
    procedure CloseInput; Virtual;
    procedure CloseOutput; Virtual;
    procedure CloseStderr; Virtual;
    function Resume: Integer; Virtual;
    function Suspend: Integer; Virtual;
    function Terminate(AExitCode: Integer): Boolean; Virtual;
    function WaitOnExit: Boolean;
    property WindowRect: TRect Read GetWindowRect
                               Write SetWindowRect;
    property Handle: THandle Read FProcessHandle;
    property ProcessHandle: THandle Read FProcessHandle;
    property ThreadHandle: THandle Read FThreadHandle;
    property ProcessID: Integer Read FProcessID;
    property ThreadID: Integer Read FThreadID;
    property Input: TOutputPipeStream Read FInputStream;
    property Output: TInputPipeStream Read FOutputStream;
    property Stderr: TInputPipeStream Read FStderrStream;
    property ExitStatus: Integer Read GetExitStatus;
    property InheritHandles: Boolean Read FInheritHandles Write FInheritHandles;


  published
    property Active: Boolean Read GetRunning Write SetActive;
    property ApplicationName: String Read FApplicationName
                                 Write SetApplicationName;
    property CommandLine: String Read FCommandLine Write FCommandLine;
    property ConsoleTitle: String Read FConsoleTitle
                                 Write FConsoleTitle;
    property CurrentDirectory: String Read FCurrentDirectory
                                 Write FCurrentDirectory;
    property Desktop: String Read FDesktop Write FDesktop;
    property Environment: TStrings Read Fenvironment
                                 Write SetEnvironment;
    property Options: TProcessOptions Read FProcessOptions
                                  Write SetProcessOptions;
    property Priority: TProcessPriority Read FProcessPriority
                                 Write FProcessPriority;
    property StartupOptions: TStartupOptions Read FStartupOptions
                                 Write FStartupOptions;
    property Running: Boolean Read GetRunning;
    property ShowWindow: TShowWindowOptions Read FShowWindow
                                 Write SetShowWindow;
    property WindowColumns: Cardinal Read dwXCountChars
                                 Write SetWindowColumns;
    property WindowHeight: Cardinal Read dwYSize
                                Write SetWindowHeight;
    property WindowLeft: Cardinal Read dwX Write SetWindowLeft;
    property WindowRows: Cardinal Read dwYCountChars
                                 Write SetWindowRows;
    property WindowTop: Cardinal Read dwY Write SetWindowTop;
    property WindowWidth: Cardinal Read dwXSize Write SetWindowWidth;
    property FillAttribute: Cardinal Read FFillAttribute Write FFillAttribute;
end;


지금까지는 윈도우만 언급했지만 이 컴포넌트는-프리 파스칼에서 항상 그렇듯-모든 지원되는 플랫폼에서 사용 가능하다. TProcess 는 호출된 프로그램을 관리하는 데에도 사용할 수 있는데, 이를 사소하게 볼 수만은 없는 것이 결국 프로세스는 상호 의존적이어야 하기 때문이다. WaitOnExit 메소드는 이를 책임진다. 여기서 우리는 동기식 호출에 관해 논하고 있다. 외부 프로그램으로의 일반 호출은 훨씬 간단하지만 비동기적이다. 호출하는 프로그램은 자식 프로세스에 대해 어떤 제어력도 없다.


윈도우는 다른 프로그램을 시작할 때 사용할 수 있는 두 개의 API 함수 모임(family)을 가진다. 셸 API의 루틴이 훨씬 사용하기가 간단하다. 기본 함수는 ShellExecuteA 또는 ShellExecuteW 라고 불린다:

function ShellExecuteA/W(hWnd: HWND;
                         Operation, FileName, Parameters,
                         Directory: Pchar; ShowCmd: Integer): HINST


ShellExecute 의 흥미로운 특성으로, 프로그램을 실행하는 것 이상의 기능을 들 수 있다.


어떤 데이터 파일 이름이든 파라미터로서 취해 이 루틴을 호출할 경우, API는 레지스트리 내 프로그램 파일이 그 확장자와 연결되어 있는지 확인한 후 파일을 파라미터로 프로그램을 로딩할 것이다. 해당 파일명 확장자에 적절한 프로그램을 찾을 수 없는 경우 윈도우 셸은 사용자에게 지금 아니면 추후에 프로그램을 하나 명시할 것을 요청한다. ShellExecute의 성능은 실행 프로그램으로 제한되지 않는다. 윈도우 익스플로러에서 디렉터리를 열거나 프린터로 파일을 전송 시에도 사용된다 (표 10.3 참고).

문자열 설명
open lpFile 파라미터 내 파일이 열릴 것이다. 이 파일은 실행 파일이거나 문서일 수 있다. 디렉터리 또한 가능한데, 이 경우 윈도우 익스플로러를 이용해 표시될 것이다.
print lpFile 파라미터 내 파일이 인쇄될 것이다. 이 파일은 문서여야 한다. 실행 파일이 전달 시 열기 옵션을 선택한 것과 같이 파일이 열릴 것이다.
explore lpFile이 명시한 폴더의 내용이 윈도우 익스플로러를 이용해 표시될 것이다.
표 10.3: ShellExecute 함수의 lpOperation 함수에 대한 문자열


hWnd 파라미터는 부모 창의 핸들을 전달 시 사용 가능하다. 이 부모 창의 핸들은 오류 메시지 창이 (혹은 다른 어떤 창이든) 애플리케이션에 의해 생성되어야 할 경우 필요하다. lpOperation 은 실행되어야 할 연산을 나타내는 널 종료(null-terminated) 문자열을 가리키는 포인터이다. lpFile 은 열어야 하는 파일 또는 열거나 인쇄해야 하는 파일을 참조하는 널 종료 문자열에 대한 포인터이다.

API 상수 설명
0 운영체제에 이용 가능한 메모리나 리소스가 더 이상 없다.
ERROR_FILE_NOT_FOUND 2 주어진 파일을 찾을 수 없다.
ERROR_PATH_NOT_FOUND 3 주어진 경로를 찾을 수 없다.
ERROR_BAD_FORMAT 11 주어진 실행 파일이 (.exe) 유효하지 않다.
(Win32-exe 파일이 아니거나, 손상되었다).
SE_ERR_ACCESSDENIED 5 운영체제가 주어진 파일로 접근을 허용하지 않는다. 이 오류는 주로 사용자에게 파일 접근 권한이 없어서 발생한다.
SE_ERR_ASSOCINCOMPLETE 27 파일명의 확장자가 완전하지 않거나 유효하지 않다.
SE_ERR_DDEBUSY 30 다른 DDE 트랜잭션이 진행 중이어서 DDE 트랜잭션을 완료할 수 없다.
SE_ERR_DDEFAIL 29 DDE 트랜잭션이 실패하였다.
SE_ERR_DDETIMEOUT 28 DDE 트랜잭션을 완료할 수 없다; 타임아웃(timeout)이 발생하였다.
SE_ERR_DLLNOTFOUND 32 선택된 DDL을 찾을 수 없다.
SE_ERR_FNF 2 선택된 파일을 찾을 수 없다.
SE_ERR_NOASSOC 31 명시된 파일명 확장자와 관련된 애플리케이션을 찾을 수 없다.
SE_ERR_OOM 8 연산을 완료하는데 필요한 메모리가 충분하지 않다.
SE_ERR_PNF 3T 선택된 경로를 찾을 수 없다.
SE_ERR_SHARE 26 접근 충돌이 발견되었다.
표 10.4: ShellExecute 함수의 가능한 리턴 값 (Windows만 해당)


실행 파일을 위한 파라미터를 포함하는 널 종료 문자열에 대한 포인터를 전달하는 데에는 lpParameters를 이용한다. 문서의 경우 NIL을 전달해야 한다. lpDirectory는 호출하는 애플리케이션에 대한 표준 디렉터리를 나타내는 문자열의 포인터이다. lpFile 은 실행 파일을 나타내고, nShowCmd 는 이 프로그램을 어떻게 표시할 것인지를 제어한다. 문서의 경우 0을 전달해야 한다.


아래 짧은 프로그램은 이 함수의 사용이 얼마나 쉬운지를 보여준다. 이는 Windows Cds에 전형적인 shellexec.exe를 구현한다:

program shellexec; { shellexec.lpr }
{$APPTYPE GUI}  (* Very important in this Program *)
{$mode Delphi}

(* direct import of API function saves space *)
function ShellExecute(HWND: LongInt;
                      lpOperation, lpFile, lpParameters, lpDirectory:
                      PChar; nShowCmd: Integer): LongInt; StdCall;
  External 'Shell32.dll' Name 'ShellExecuteA';

  var  s: String;
begin
  if ParamCount > 0 then
  begin
    s := ParamStr(1);
    (* only use ParamStr(1) ー no parent handle or other information *)
    ShellExecute(0, 'open', PChar(s), nil, '', 0);
    Halt(0);     // No error analysis done ー just quit the program
  end
  else
    Halt(1);     // No parameter given, so quit with error indication
end.


이 명령 행에서 파일명을 이 프로그램으로 전달하거나 실행 프로그램 파일에 데이터 파일을 드롭할 경우, 관련 프로그램이 실행될 것이며, 애플리케이션이 허용한다면 즉시 선택된 파일이 로딩될 것이다.

API 상수 설명
SW_HIDE 0 창이 숨겨지고 다른 창이 활성화될 것이다.
SW_MAXIMIZE 3 창이 활성화되고 화면에 가득 차도록 최대화될 것이다.
SW_MINIMIZE 6 창이 작업 표시줄에 아이콘으로 표시되고 프로그램 z-order에서 다음 창이 활성화될 것이다.
SW_RESTORE 9 창이 활성화되고 표시될 것이다. 이전에 최대화되었던 창이라면 다시 최대화될 것이고, 아니라면 이전 크기와 위치에서 표시될 것이다. 이 옵션은 최소화된 창을 복구시키는 데에 사용해야 한다.
SW_SHOW 5 창이 현재 위치와 크기에 표시될 것이다.
SW_SHOWDEFAULT 10 SW_ 플래그를 기반으로 프로그램을 시작하는 CreateProcess 호출의 STARTUPINFO 레코드에 명시된 옵션과 함께 창이 표시될 것이다. 애플리케이션은 ShowWindow를 호출 시 본래 표시 상태를 설정하기 위해 이 플래그를 설정해야 한다.
SW_SHOWMAXIMIZED 3 창이 활성화되고 화면에 가득 차도록 최대화될 것이다.
SW_SHOWMINIMIZED 2 창이 활성화되고 작업 표시줄에 아이콘으로 표시될 것이다.
SW_SHOWMINNOACTIVE 7 창이 작업 표시줄에 아이콘으로 표시될 것이다. 현재 활성화 창은 활성화된 채로 남는다.
SW_SHOWNA 8 창이 현재 위치와 크기로 표시될 것이다. 현재 활성화된 창은 활성화된 채로 남는다.
SW_SHOWNOACTIVATE 4 SW_SHOWNA와 동일하다.
SW_SHOWNORMAL 1 창이 활성화되고 표시될 것이다. 현재 최대화 또는 최소화되어 있다면 윈도우는 최대화/최소화 전의 크기와 위치로 복구시킨다. 애플리케이션은 처음으로 창을 표시할 때 이 플래그를 설정해야 한다.
표 10.5: ShellExecute 함수에 대한 nShowCmd 파라미터의 값 (Windows만 해당)


ShellExecute 함수 외에도 셸 API는 ShellExecuteEx 함수도 제공하는데, 이 함수가 취하는 파라미터 수는 더 적다. 모든 데이터는 단일 구조로 전송되지만 동일한 기능을 제공한다.


데이터 파일을 클릭할 때 관련 프로그램을 호출하는 것은 다른 플랫폼으로 이식할 수 없는 윈도우만의 기능이다. 다른 플랫폼에서 이와 같은 기능을 제공하려면 사전 정의된 파일 결합이 없는 확장자에 대해 윈도우가 제공하는 것과 비슷한 초기화(initialization) 대화창을 생성해야 한다.


ShellExecute는 윈도우에서만 이용 가능하므로 플랫폼 독립적으로 유도된 프로그램들은 이를 사용해선 안 된다 (또는 그 사용을 조건부 컴파일로 제한해선 안 된다). 하지만 CreateProcess의 복잡한 파라미터로 작업할 필요가 없다.


SysUtils 유닛은 다른 프로그램들을 호출할 수 있는 더 간단한 방법을 제공한다:

function ExecuteProcess(const Path: AnsiString;
                        const ComLine: AnsiString): Integer;
function ExecuteProcess(const Path: AnsiString;
                        const ComLine: array of AnsiString): Integer;


이는 오래된 WinExec 를 (Vista 또는 Win7에선 더 이상 이용할 수 없는) 대체하는 윈도우에서조차 더 선호되는 함수이다. 이 함수는 Path 에 명시된 프로그램을 시작하고, ComLine 내 파라미터를 프로그램으로 전송한다. 함수는 프로그램이 끝날 때까지 기다린 후에 Exitcode를 리턴 값으로 리턴한다. 하나의 문자열만 ComLine 으로 전달될 경우 (위에 표시된 첫 변형), 함수는 일반 구분 문자와 마스킹 문자로 파라미터를 위해 파싱할 것이다. 실행할 프로그램을 찾을 수 없는 경우 함수는 EOSError 타입의 예외를 던질 것이다. 이는 아래와 같이 sysutilsh.inc 에서 선언된다:

type  EOSError = class(Exception)
public
  ErrorCode: LongInt; // operating system error code.
end;


ExecuteProcess의 파라미터 이름, Path 에서 짐작하듯이, 시작할 프로그램은 실행 파일의 이름뿐만 아니라 전체 경로명으로 명시되어야 한다. Linux 와 FreeBSD에서는 대부분의 프로그램들이 /usr/bin (Linux) 또는 /usr/local/bin (FreeBSD) (프로그램 이름을 이 디렉터리에서 검색하기도 한다) 에 상주하기 때문에 수월하다. PC BSD에서는 조금 더 까다롭고, Windows에서는 일반 프로그램의 경우 이보다 더 복잡하고 실행이 불가능하다. 자식 애플리케이션에 전체 경로를 명시하는 것은 설계 요구조건인데, Trojan의 확률을 감소시키기 때문이다. 윈도우 최신 버전에선 대부분 프로그램이 PATH 시스템 변수를 파싱하지 않으므로 파싱할 필요가 없다.