Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Hasło nie zostało zweryfikowane
Niniejsze hasło zostało opracowane, jednak nie zostało ono zweryfikowane przez administrację serwisu. Jeżeli znalazłeś błędy merytoryczne w niniejszym dokumencie, prosimy o ich zgłoszenie na forum w dziale Znalezione błędy.
Opracował: pekfos
Biblioteki C/C++

CreateProcess

[funkcja] Tworzy nowy proces i jego główny wątek.

Składnia

C/C++
#include <windows.h>

BOOL WINAPI CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);

Argumenty

ArgumentOpis
lpApplicationNameNazwa modułu do wykonania. Musi zawierać rozszerzenie pliku. W przypadku 16-bitowych aplikacji, lpApplicationName powinno być ustawione na NULL, a ścieżka do programu wraz z jego parametrami powinna być podana jako lpCommandLine. By wykonać plik wsadowy należy jako lpApplicationName podać ścieżkę do interpretera (np cmd.exe) a w lpCommandLine podać następujące argumenty: /c nazwa_pliku. (argument opcjonalny)
lpCommandLinePolecenie do wykonania. Maksymalnie 32768 znaków wraz z \0 kończącym łańcuch. Unikodowa wersja tej funkcji, CreateProcessW, może modyfikować ten argument. Wtedy ten argument nie może wskazywać na pamięć tylko do odczytu. W przeciwnym razie funkcja może spowodować błąd naruszenia ochrony pamięci. Jeśli lpCommandLine jest ustawiony na NULL, funkcja wykorzystuje lpApplicationName jako wiersz polecenia. Jeśli lpCommandLine i lpApplicationNAme są prawidłowymi łańcuchami zakończonymi zerem, lpApplicationName określa ścieżkę do pliku wykonywalnego a lpCommandLine określa argumenty przekazywane do programu. Jeśli lpApplicationName jest równe NULL, ścieżką do programu jest podłańcuch kończący się na pierwszym napotkanym białym znaku. W przypadku długich ścieżek do pliku zawierających białe znaki, należy umieścić ścieżkę w cudzysłowach. Jeśli ścieżka do pliku nie kończy się rozszerzeniem, dołączane jest rozszerzenie .exe. Jednak gdy plik ma inne rozszerzenie, trzeba je podać. Jeśli nazwa pliku kończy się na '.', nie jest dołączane żadne rozszerzenie. System dzieli podany łańcuch zerem dla oddzielenia nazwy pliku od argumentów dla ich oddzielnego przetwarzania. (argument opcjonalny)
lpProcessAttributeswskaźnik na strukturę SECURITY_ATTRIBUTES która określa, czy zwrócony uchwyt na obiekt nowego procesu może być dziedziczony przez procesy potomne. Jeśli ten argument jest ustawiony na NULL, uchwyt nie może być dziedziczony. Składowa lpSecurityDescriptor z tej struktury określa deskryptor dla nowego procesu. Jeżeli lpProcessAttributes jest równe NULL lub lpSecurityDescriptor jest równe NULL, proces otrzymuje domyślny deskryptor. (argument opcjonalny)
lpThreadAttributesWskaźnik na strukturę SECURITY_ATTRIBUTES która określa, czy zwrócony uchwyt na obiekt nowego wątku może być dziedziczony przez procesy potomne. Jeśli ten argument jest równy NULL, uchwyt nie może być dziedziczony. Składowa lpSecurityDescriptor z tej struktury określa deskryptor dla głównego wątku. Jeżeli lpThreadAttributes jest równe NULL lub lpSecurityDescriptor jest równe NULL, wątek otrzymuje domyślny deskryptor. (argument opcjonalny)
bInheritHandlesJeśli ten argument jest ustawiony na TRUE, każdy uchwyt z wywołującego procesu który może być dziedziczony jest dziedziczony przez nowy proces. (Uchwyty w nowym procesie mają te same wartości i te same prawa dostępu jak te z wywołującego procesu.) Jeśli jest ustawiony na FALSE, uchwyty nie są dziedziczone.
dwCreationFlagsFlagi kontrolujące priorytet i tworzenie procesu.
lpEnvironmentWskaźnik na blok środowiska dla nowego procesu. Jeśli ten argument jest ustawiony na NULL, nowy proces używa środowiska procesu wywołującego. Blok środowiska składa się z zakończonego zerem bloku zakończonych zerem łańcuchów. Każdy z nich ma następującą formę: name=value\0. Znak równości jest tu używany jako separator. Nie może się on znajdować w nazwie zmiennej środowiskowej. Blok środowiska może zawierać zarówno znaki ANSI jak i UNICODE. Jeśli wskazany blok zawiera znaki UNICODE, upewnij się, że do dwCreationFlags jest dodana flaga CREATE_UNICODE_ENVIORMENT. W przypadku gdy lpEnvironment jest równe NULL a środowisko procesu wywołującego zawiera znaki UNICODE, również trzeba ustawić flagę CREATE_UNICODE_ENVIRONMENT. W wersji ANSI tej funkcji (CreateProcessA), blok środowiska dla procesu musi mieć rozmiar mniejszy niż 32768 znaków. Należy pamiętać, że blok środowiska ANSI kończy się dwoma zerami (jedno kończy ostatni łańcuch, a drugie kończy blok), a środowisko UNICODE kończy się czterema zerami (dwa kończą ostatni łańcuch, a kolejne dwa - ostatni blok).
lpCurrentDirectoryPełna ścieżka do katalogu roboczego dla nowego procesu. Jeśli ten argument jest równy NULL, nowy proces będzie miał ten sam katalog startowy co proces wywołujący (argument opcjonalny).
lpStartupInfoWskaźnik na strukturę STARTUPINFO lub STARTUPINFOEX. By użyć rozszerzonych atrybutów, użyj struktury STARTUPINFOEX oraz dodaj do dwCreationFlags flagę EXTENDED_STARTUPINFO_PRESENT. Uchwyty w strukturze STARTUPINFO muszą zostać zamknięte przez CloseHandle gdy nie będą już potrzebne.
lpProcessInformationWskaźnik na strukturę PROCESS_INFORMATION która otrzyma informacje o nowo utworzonym procesie. Uchwyty w strukturze PROCESS_INFORMATION muszą zostać zamknięte przez CloseHandle gdy nie będą już potrzebne.

Zwracana wartość

Jeśli funkcja zakończy się powodzeniem, zwrócona wartość jest niezerowa. W przeciwnym razie, funkcja zwraca zero. Aby otrzymać informacje o błędzie, wywołaj GetLastError().

Należy pamiętać, że funkcja kończy się zanim proces zakończy inicjalizację. Jeśli proces nie będzie mógł znaleźć wymaganych plików lub nie będzie mógł się zainicjalizować, proces zostanie zakończony. Aby otrzymać informacje o zakończeniu procesu, wywołaj GetExitCodeProcess().

Opis szczegółowy

Proces ma przypisany identyfikator procesu (PID). Ten identyfikator jest prawidłowy aż do zakończenia procesu. Może być użyty do identyfikacji procesu lub do otwarcia uchwytu do procesu przez OpenProcess(). Główny wątek również ma przypisany identyfikator. Jest on poprawny dopóki wątek nie zostanie zakończony. Można go użyć w OpenThread() do otwarcia uchwytu tego wątku. Te identyfikatory są zwrócone w strukturze PROCESS_INFORMATION.
Nazwa pliku wykonywalnego w wierszu poleceń który system zapewnia procesowi nie musi być identyczna z nazwą podaną w funkcji CreateProcess. System może podać procesowi pełną ścieżkę do pliku wykonywalnego gdy w funkcji jest podana niepełna ścieżka.
Proces wywołujący może wywołać funkcję WaitForInputIdle() by zaczekać na pełną inicjalizację nowego procesu i jego gotowość do przyjmowania danych gdy (już) nie ma żadnych oczekujących danych wejściowych. To może być pomocne w synchronizacji procesu wywołującego i potomnego gdyż funkcja CreateProcess() nie czeka na zakończenie inicjalizacji nowego procesu.
Najlepszym sposobem na zakończenie procesu jest wywołanie ExitProcess(), ponieważ funkcja ta wysyła komunikat informujący o zbliżającym się końcu procesu do wszystkich plików DLL dołączonych do tego procesu. Inne sposoby zakańczania procesu nie informują dołączonych plików DLL. Gdy wątek wywołuje ExitProcess(), pozostałe wątki procesu są zakańczane bez możliwości wykonania żadnego dodatkowego kodu.
Proces wywołujący może bezpośrednio zmieniać zmienne środowiskowe procesu potomnego podczas jego tworzenia. To jedyna sytuacja, gdy proces może bezpośrednio zmieniać ustawienia środowiskowe innego procesu.
Jeśli proces jest utworzony z ustawioną flagą CREATE_NEW_PROCESS_GROUP, zostaje wykonane niejawne wywołanie SetConsoleCtrlHandler(NULL, TRUE) w imieniu nowego procesu. To oznacza, że nowy proces ma wyłączone Ctrl+C. To pozwala na inną obsługę skrótu Ctrl+C przez powłoki lub selektywne wysyłanie tego sygnału do podprocesów. Ctrl+Break nie jest wyłączone i można w ten sposób zakończyć proces lub grupę procesów.

Przykład

C/C++
#include <windows.h>
#include <cstdio>

const char * cmd = "prog";

int main() {
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
   
    ZeroMemory( & pi, sizeof( pi ) );
    ZeroMemory( & si, sizeof( si ) );
    si.cb = sizeof( si );
   
    if( !CreateProcess( NULL,
    ( LPSTR ) cmd,
    NULL,
    NULL,
    FALSE,
    0,
    NULL,
    NULL,
    & si,
    & pi ) )
    {
        printf( "Could not create process. (%ld)", GetLastError() );
        return 1;
    }
   
    WaitForSingleObject( pi.hProcess, INFINITE );
   
    DWORD exitcode;
    if( !GetExitCodeProcess( pi.hProcess, & exitcode ) ) {
        printf( "Could not get process exit code. (%ld)", GetLastError() );
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
        return 1;
    }
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
    printf( "Process returned: %ld", exitcode );
}
C/C++
//prog.cpp
int main() {
    return 42;
}
Process returned: 42

Wymagania

Minimalny obsługiwany klientWindows 2000 Professional
Minimalny obsługiwany serwerWindows 2000 Server
BibliotekaKernel32.lib
DLLKernel32.dll

Dodatkowe informacje

Niniejsze pojęcie jeszcze nie zostało wyczerpująco przez nas opracowane. Więcej informacji na temat niniejszego hasła znajdziesz pod adresem http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx.

Linki zewnętrzne