Tworzenie nowego procesu (programowo)
#1
Najpopularniejszym dziś sposobem tworzenia nowego procesu jest odwołanie się do odpowiedniej funkcji, gdzie deklarujemy podstawowe informacje o procesie.  Funkcja zwraca nam potem uchwyt do tego procesu (ang. handle) za pomocą którego możemy na nim operować.

Teraz stworzymy program, który uruchamia daną aplikację, a następnie czeka na jej zakończenie. Wykorzystamy w nim funkcję WinAPI (windows.h) CreateProcess (funkcja ta przyjmuje bardzo dużo parametrów, z czego potrzebne jest nam tylko kilka).

Kod:
#include <windows.h>
#include <stdio.h>
#include <string>
#include <iostream>

int main(void)
{
    PROCESS_INFORMATION pInfo;
    STARTUPINFO sInfo = { sizeof(pInfo) };
    std::string a;
   puts("Podaj ścieżkę do uruchamianego programu:\n");
    std::cin >> a;
    BOOL res = CreateProcess(a.c_str(), NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &sInfo, &pInfo);
    if (!res) return 1;
    CloseHandle(pInfo.hThread);
    printf("Process started with ID: %u, waiting for exit...\n", static_cast<unsigned int>(pInfo.dwProcessId));
    WaitForSingleObject(pInfo.hProcess, INFINITE);
    CloseHandle(pInfo.hProcess);
    puts("Process exited");
    return 0;
}

Przeanalizujmy kod linijka po linijce. Pierwsze dwie, są to dwie dobrze nam znane zaimportowane biblioteki – standardowa (stdio.h / cstdio), druga to WinAPI (windows.h)., trzecia to biblioteka obsługująca stringi a ostatnia iostream (wykorzystam z niej funkcje cin).

Tworzymy główną część naszego programu (int main) bez żadnych parametrów (void).
Teraz tworzymy dwa obiekty  PROCESS_INFORMATION oraz STARTUPINFO – potrzebne są one nam do uruchamiania nowego procesu.
Potem tworzymy string a nazwie a, i prosimy użytkownika o wpisanie ścieżki do programu.
Potem  widzimy zmienną logiczną BOOL nazwaną res  – służy ona do sprawdzenia, czy uruchomienie procesu się powiodło (CreateProcessW również jest typem BOOL). Jeżeli zwróci on wartość TRUE – kontynnujmy, inaczej return 1.
Przeanalizujmy teraz strukturę CreateProcess. Ma ona, jak to wiele komend z WinAPI, wiele parametrów, w większości niepotrzebnych. Najważniejsze dla nas są:
  • lpApplicationName – ścieżka do uruchamianej aplikacji
  • lpStartupInfo – zawiera parametry nowego procesu
  • lpProcessInformation – zawiera informacje o nowym procesie i uchwyty (Handle) do niego
Po uruchomieniu pliku możemy zacząć zamykać uchwyty. Służy do tego funkcja CloseHandle, w której zamykamy dostęp do wątku (nie ingerujemy w niego). Kolejna linijka służy do „wyczekiwania” przez nieskończoną ilość czasu  na zamknięcie procesu. Kiedy już się to zdarzy, całkowicie zamykamy uchwyt. Wypisujemy potem na konsoli „Process exited” i zwracamy wartość (tu 0).
Kompilacja i uruchomienie (TDM-GCC 4.9.2 32-bit DEBUG) wygląda tak:
[Obrazek: tAENaG4.png]
[Obrazek: f2DHYVn.png]

Jak widać, wszystko wykonuje się tak, jak powinno.
To by było na tyle, w razie czego pytajcie Smile
0x DEADBEEF
Odpowiedz
#2
XD używasz pliku nagłówkowego iostream żeby skorzystać tylko że strumienia, skoro jednocześnie dodałeś stdio i nie użyłeś scanf...
1. Zawsze mam rację.
2. Jeśli nie mam racji, patrz pkt 1.
Odpowiedz
#3
(10.04.2016, 13:12)Tajny Współpracownik napisał(a): XD używasz pliku nagłówkowego iostream żeby skorzystać tylko że strumienia, skoro jednocześnie dodałeś stdio i nie użyłeś scanf...
Osobista preferencja, nie lubie scanf z char* Craze
0x DEADBEEF
Odpowiedz
#4
"Bżydko to wyglonda Sad"
1. Zawsze mam rację.
2. Jeśli nie mam racji, patrz pkt 1.
Odpowiedz




Użytkownicy przeglądający ten wątek: 2 gości