Fungsi CreateProcessA (processthreadsapi.h)

Membuat proses baru dan utas utamanya. Proses baru berjalan dalam konteks keamanan proses panggilan.

Jika proses panggilan meniru pengguna lain, proses baru menggunakan token untuk proses panggilan, bukan token peniruan. Untuk menjalankan proses baru dalam konteks keamanan pengguna yang diwakili oleh token peniruan identitas, gunakan fungsi CreateProcessAsUser atau CreateProcessWithLogonW .

Sintaks

BOOL CreateProcessA(
  [in, optional]      LPCSTR                lpApplicationName,
  [in, out, optional] LPSTR                 lpCommandLine,
  [in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,
  [in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,
  [in]                BOOL                  bInheritHandles,
  [in]                DWORD                 dwCreationFlags,
  [in, optional]      LPVOID                lpEnvironment,
  [in, optional]      LPCSTR                lpCurrentDirectory,
  [in]                LPSTARTUPINFOA        lpStartupInfo,
  [out]               LPPROCESS_INFORMATION lpProcessInformation
);

Parameter

[in, optional] lpApplicationName

Nama modul yang akan dijalankan. Modul ini bisa menjadi aplikasi berbasis Windows. Ini bisa menjadi beberapa jenis modul lain (misalnya, MS-DOS atau OS/2) jika subsistem yang sesuai tersedia di komputer lokal.

String dapat menentukan jalur lengkap dan nama file modul yang akan dijalankan atau dapat menentukan nama parsial. Dalam kasus nama parsial, fungsi menggunakan drive saat ini dan direktori saat ini untuk menyelesaikan spesifikasi. Fungsi tidak akan menggunakan jalur pencarian. Parameter ini harus menyertakan ekstensi nama file; tidak ada ekstensi default yang diasumsikan.

Parameter lpApplicationName dapat berupa NULL. Dalam hal ini, nama modul harus menjadi token pertama yang dibatasi spasi putih dalam string lpCommandLine . Jika Anda menggunakan nama file panjang yang berisi spasi, gunakan string yang dikutip untuk menunjukkan di mana nama file berakhir dan argumen dimulai; jika tidak, nama file ambigu. Misalnya, pertimbangkan string "c:\program files\sub dir\program name". String ini dapat ditafsirkan dalam sejumlah cara. Sistem mencoba menafsirkan kemungkinan dalam urutan berikut:

  1. c:\program.exe
  2. c:\files\sub.exeprogram
  3. c:\program files\sub dir\program.exe
  4. c:\program files\sub dir\program name.exe

Jika modul yang dapat dieksekusi adalah aplikasi 16-bit, lpApplicationName harus NULL, dan string yang ditunjukkan oleh lpCommandLine harus menentukan modul yang dapat dieksekusi serta argumennya.

Untuk menjalankan file batch, Anda harus memulai penerjemah perintah; atur lpApplicationName ke cmd.exe dan atur lpCommandLine ke argumen berikut: /c ditambah nama file batch.

[in, out, optional] lpCommandLine

Baris perintah yang akan dijalankan.

Panjang maksimum string ini adalah 32.767 karakter, termasuk karakter null penghentian Unicode. Jika lpApplicationName adalah NULL, bagian nama modul dari lpCommandLine terbatas pada MAX_PATH karakter.

Versi Unicode dari fungsi ini, CreateProcessW, dapat memodifikasi konten string ini. Oleh karena itu, parameter ini tidak dapat menjadi penunjuk ke memori baca-saja (seperti variabel const atau string literal). Jika parameter ini adalah string konstanta, fungsi dapat menyebabkan pelanggaran akses.

Parameter lpCommandLine dapat berupa NULL. Dalam hal ini, fungsi menggunakan string yang diacu oleh lpApplicationName sebagai baris perintah.

Jika lpApplicationName dan lpCommandLine bukan NULL, string yang diakhiri null yang ditunjukkan oleh lpApplicationName menentukan modul yang akan dijalankan, dan string yang diakhiri null yang ditunjukkan oleh lpCommandLine menentukan baris perintah. Proses baru dapat menggunakan GetCommandLine untuk mengambil seluruh baris perintah. Proses konsol yang ditulis dalam C dapat menggunakan argumen argc dan argv untuk mengurai baris perintah. Karena argv[0] adalah nama modul, programmer C umumnya mengulangi nama modul sebagai token pertama di baris perintah.

Jika lpApplicationName adalah NULL, token spasi putih pertama dari baris perintah menentukan nama modul. Jika Anda menggunakan nama file panjang yang berisi spasi, gunakan string yang dikutip untuk menunjukkan di mana nama file berakhir dan argumen dimulai (lihat penjelasan untuk parameter lpApplicationName ). Jika nama file tidak berisi ekstensi, .exe ditambahkan. Oleh karena itu, jika ekstensi nama file adalah .com, parameter ini harus menyertakan ekstensi .com. Jika nama file berakhiran titik (.) tanpa ekstensi, atau jika nama file berisi jalur, .exe tidak ditambahkan. Jika nama file tidak berisi jalur direktori, sistem akan mencari file yang dapat dieksekusi dalam urutan berikut:

  1. Direktori tempat aplikasi dimuat.
  2. Direktori saat ini untuk proses induk.
  3. Direktori sistem Windows 32-bit. Gunakan fungsi GetSystemDirectory untuk mendapatkan jalur direktori ini.
  4. Direktori sistem Windows 16-bit. Tidak ada fungsi yang mendapatkan jalur direktori ini, tetapi dicari. Nama direktori ini adalah Sistem.
  5. Direktori Windows. Gunakan fungsi GetWindowsDirectory untuk mendapatkan jalur direktori ini.
  6. Direktori yang tercantum dalam variabel lingkungan PATH. Perhatikan bahwa fungsi ini tidak mencari jalur per aplikasi yang ditentukan oleh kunci registri Jalur Aplikasi . Untuk menyertakan jalur per aplikasi ini dalam urutan pencarian, gunakan fungsi ShellExecute .
Sistem menambahkan karakter null yang mengakhiri ke string baris perintah untuk memisahkan nama file dari argumen. Ini membagi string asli menjadi dua string untuk pemrosesan internal.

[in, optional] lpProcessAttributes

Penunjuk ke struktur SECURITY_ATTRIBUTES yang menentukan apakah handel yang dikembalikan ke objek proses baru dapat diwariskan oleh proses anak. Jika lpProcessAttributes adalah NULL, handel tidak dapat diwariskan.

Anggota lpSecurityDescriptor dari struktur menentukan deskriptor keamanan untuk proses baru. Jika lpProcessAttributes adalah NULL atau lpSecurityDescriptor adalah NULL, prosesnya akan mendapatkan pendeskripsi keamanan default. ACL dalam deskriptor keamanan default untuk proses berasal dari token utama pembuat. Windows XP: ACL dalam deskriptor keamanan default untuk proses berasal dari token utama atau peniruan dari pembuat. Perilaku ini berubah dengan Windows XP dengan SP2 dan Windows Server 2003.

[in, optional] lpThreadAttributes

Penunjuk ke struktur SECURITY_ATTRIBUTES yang menentukan apakah handel yang dikembalikan ke objek utas baru dapat diwariskan oleh proses anak. Jika lpThreadAttributes adalah NULL, handel tidak dapat diwariskan.

Anggota lpSecurityDescriptor dari struktur menentukan deskriptor keamanan untuk utas utama. Jika lpThreadAttributes adalah NULL atau lpSecurityDescriptor adalah NULL, utas akan mendapatkan deskriptor keamanan default. ACL dalam deskriptor keamanan default untuk utas berasal dari token proses. Windows XP: ACL dalam deskriptor keamanan default untuk utas berasal dari token utama atau peniruan dari pembuat. Perilaku ini berubah dengan Windows XP dengan SP2 dan Windows Server 2003.

[in] bInheritHandles

Jika parameter ini TRUE, setiap handel yang dapat diwariskan dalam proses panggilan diwariskan oleh proses baru. Jika parameter adalah FALSE, handel tidak diwariskan. Perhatikan bahwa handel yang diwariskan memiliki nilai dan hak akses yang sama dengan handel asli. Untuk diskusi tambahan tentang handel yang dapat diwariskan, lihat Keterangan.

Layanan Terminal: Anda tidak dapat mewarisi handel di seluruh sesi. Selain itu, jika parameter ini TRUE, Anda harus membuat proses dalam sesi yang sama dengan pemanggil.

Proses Cahaya Proses Terlindungi (PPL): Pewarisan handel generik diblokir ketika proses PPL membuat proses non-PPL karena PROCESS_DUP_HANDLE tidak diizinkan dari proses non-PPL ke proses PPL. Lihat Keamanan Proses dan Hak Akses

[in] dwCreationFlags

Bendera yang mengontrol kelas prioritas dan pembuatan proses. Untuk daftar nilai, lihat Bendera Pembuatan Proses.

Parameter ini juga mengontrol kelas prioritas proses baru, yang digunakan untuk menentukan prioritas penjadwalan utas proses. Untuk daftar nilai, lihat GetPriorityClass. Jika tidak ada bendera kelas prioritas yang ditentukan, kelas prioritas default ke NORMAL_PRIORITY_CLASS kecuali kelas prioritas proses pembuatan IDLE_PRIORITY_CLASS atau BELOW_NORMAL_PRIORITY_CLASS. Dalam hal ini, proses anak menerima kelas prioritas default dari proses panggilan.

Jika parameter dwCreationFlags memiliki nilai 0:

  • Proses ini mewarisi mode kesalahan pemanggil dan konsol induk.
  • Blok lingkungan untuk proses baru diasumsikan berisi karakter ANSI (lihat parameter lpEnvironment untuk informasi tambahan).
  • Aplikasi berbasis Windows 16-bit berjalan di komputer Virtual DOS bersama (VDM).

[in, optional] lpEnvironment

Penunjuk ke blok lingkungan untuk proses baru. Jika parameter ini NULL, proses baru menggunakan lingkungan proses panggilan.

Blok lingkungan terdiri dari blok string null-terminated dari string yang dihentikan null. Setiap string dalam bentuk berikut:

Nama=value\0

Karena tanda sama dengan digunakan sebagai pemisah, tanda tersebut tidak boleh digunakan dalam nama variabel lingkungan.

Blok lingkungan dapat berisi karakter Unicode atau ANSI. Jika blok lingkungan yang diarahkan oleh lpEnvironment berisi karakter Unicode, pastikan bahwa dwCreationFlags menyertakan CREATE_UNICODE_ENVIRONMENT.

Versi ANSI dari fungsi ini, CreateProcessA gagal jika ukuran total blok lingkungan untuk proses melebihi 32.767 karakter.

Perhatikan bahwa blok lingkungan ANSI dihentikan oleh dua byte nol: satu untuk string terakhir, satu lagi untuk mengakhiri blok. Blok lingkungan Unicode dihentikan oleh empat byte nol: dua untuk string terakhir, dua lagi untuk mengakhiri blok.

[in, optional] lpCurrentDirectory

Jalur lengkap ke direktori saat ini untuk proses tersebut. String juga dapat menentukan jalur UNC.

Jika parameter ini NULL, proses baru akan memiliki drive dan direktori saat ini yang sama dengan proses panggilan. (Fitur ini disediakan terutama untuk shell yang perlu memulai aplikasi dan menentukan drive awal dan direktori kerjanya.)

[in] lpStartupInfo

Penunjuk ke struktur STARTUPINFO atau STARTUPINFOEX .

Untuk mengatur atribut yang diperluas, gunakan struktur STARTUPINFOEX dan tentukan EXTENDED_STARTUPINFO_PRESENT dalam parameter dwCreationFlags .

Handel di STARTUPINFO atau STARTUPINFOEX harus ditutup dengan CloseHandle ketika tidak lagi diperlukan.

Penting Pemanggil bertanggung jawab untuk memastikan bahwa bidang handel standar di STARTUPINFO berisi nilai handel yang valid. Bidang-bidang ini disalin tidak berubah ke proses anak tanpa validasi, bahkan ketika anggota dwFlags menentukan STARTF_USESTDHANDLES. Nilai yang salah dapat menyebabkan proses anak salah tingkah atau crash. Gunakan alat verifikasi runtime Pemverifikasi Aplikasi untuk mendeteksi handel yang tidak valid.
 

[out] lpProcessInformation

Penunjuk ke struktur PROCESS_INFORMATION yang menerima informasi identifikasi tentang proses baru.

Handel di PROCESS_INFORMATION harus ditutup dengan CloseHandle saat tidak lagi diperlukan.

Mengembalikan nilai

Jika fungsi berhasil, nilai yang dikembalikan bukan nol.

Jika fungsi gagal, nilai yang dikembalikan adalah nol. Untuk mendapatkan informasi kesalahan yang diperluas, hubungi GetLastError.

Perhatikan bahwa fungsi kembali sebelum proses selesai diinisialisasi. Jika DLL yang diperlukan tidak dapat ditemukan atau gagal diinisialisasi, proses dihentikan. Untuk mendapatkan status penghentian proses, panggil GetExitCodeProcess.

Keterangan

Proses ini diberi pengidentifikasi proses. Pengidentifikasi valid sampai proses berakhir. Ini dapat digunakan untuk mengidentifikasi proses, atau ditentukan dalam fungsi OpenProcess untuk membuka handel ke proses. Utas awal dalam proses juga diberi pengidentifikasi utas. Ini dapat ditentukan dalam fungsi OpenThread untuk membuka handel ke utas. Pengidentifikasi valid sampai utas berakhir dan dapat digunakan untuk mengidentifikasi utas secara unik dalam sistem. Pengidentifikasi ini dikembalikan dalam struktur PROCESS_INFORMATION .

Nama yang dapat dieksekusi di baris perintah yang disediakan sistem operasi untuk proses belum tentu identik dengan itu di baris perintah yang diberikan proses panggilan ke fungsi CreateProcess . Sistem operasi dapat menambahkan jalur yang sepenuhnya memenuhi syarat ke nama yang dapat dieksekusi yang disediakan tanpa jalur yang sepenuhnya memenuhi syarat.

Utas panggilan dapat menggunakan fungsi WaitForInputIdle untuk menunggu sampai proses baru selesai inisialisasinya dan menunggu input pengguna tanpa input tertunda. Ini dapat berguna untuk sinkronisasi antara proses induk dan anak, karena CreateProcess kembali tanpa menunggu proses baru selesai inisialisasinya. Misalnya, proses pembuatan akan menggunakan WaitForInputIdle sebelum mencoba menemukan jendela yang terkait dengan proses baru.

Cara yang disukai untuk mematikan proses adalah dengan menggunakan fungsi ExitProcess , karena fungsi ini mengirimkan pemberitahuan tentang penghentian mendekati ke semua DLL yang terpasang pada proses. Cara lain untuk mematikan proses tidak memberi tahu DLL yang terlampir. Perhatikan bahwa ketika utas memanggil ExitProcess, utas proses lainnya dihentikan tanpa kesempatan untuk menjalankan kode tambahan apa pun (termasuk kode penghentian utas DLL yang dilampirkan). Untuk informasi selengkapnya, lihat Mengakhiri Proses.

Proses induk dapat langsung mengubah variabel lingkungan dari proses anak selama pembuatan proses. Ini adalah satu-satunya situasi ketika proses dapat langsung mengubah pengaturan lingkungan dari proses lain. Untuk informasi selengkapnya, lihat Mengubah Variabel Lingkungan.

Jika aplikasi menyediakan blok lingkungan, informasi direktori saat ini dari drive sistem tidak secara otomatis disebarluaskan ke proses baru. Misalnya, ada variabel lingkungan bernama =C: yang nilainya adalah direktori saat ini pada drive C. Aplikasi harus meneruskan informasi direktori saat ini secara manual ke proses baru. Untuk melakukannya, aplikasi harus secara eksplisit membuat string variabel lingkungan ini, mengurutkannya menurut abjad (karena sistem menggunakan lingkungan yang diurutkan), dan memasukkannya ke dalam blok lingkungan. Biasanya, mereka akan pergi di depan blok lingkungan, karena urutan sortir blok lingkungan.

Salah satu cara untuk mendapatkan informasi direktori saat ini untuk drive X adalah dengan melakukan panggilan berikut: GetFullPathName("X:", ...). Itu menghindari aplikasi harus memindai blok lingkungan. Jika jalur lengkap yang dikembalikan adalah X:, tidak perlu meneruskan nilai tersebut sebagai data lingkungan, karena direktori akar adalah direktori default saat ini untuk drive X dari proses baru.

Ketika proses dibuat dengan CREATE_NEW_PROCESS_GROUP ditentukan, panggilan implisit ke SetConsoleCtrlHandler(NULL,TRUE) dibuat atas nama proses baru; ini berarti bahwa proses baru telah menonaktifkan CTRL+C. Ini memungkinkan shell menangani CTRL+C sendiri, dan secara selektif meneruskan sinyal tersebut ke sub-proses. CTRL+BREAK tidak dinonaktifkan, dan dapat digunakan untuk mengganggu proses/grup proses.

Secara default, meneruskan TRUE sebagai nilai parameter bInheritHandles menyebabkan semua handel yang dapat diwariskan diwariskan oleh proses baru. Ini bisa bermasalah untuk aplikasi yang membuat proses dari beberapa utas secara bersamaan namun menginginkan setiap proses untuk mewarisi handel yang berbeda. Aplikasi dapat menggunakan fungsi UpdateProcThreadAttributeList dengan parameter PROC_THREAD_ATTRIBUTE_HANDLE_LIST untuk menyediakan daftar handel yang akan diwarisi oleh proses tertentu.

Keterangan Keamanan

Parameter pertama, lpApplicationName, dapat berupa NULL, dalam hal ini nama yang dapat dieksekusi harus berada dalam string yang dibatasi spasi putih yang ditunjukkan oleh lpCommandLine. Jika nama yang dapat dieksekusi atau jalur memiliki ruang di dalamnya, ada risiko bahwa executable yang berbeda dapat dijalankan karena cara fungsi mengurai spasi. Contoh berikut berbahaya karena fungsi akan mencoba menjalankan "Program.exe", jika ada, alih-alih "MyApp.exe".
	LPTSTR szCmdline = _tcsdup(TEXT("C:\\Program Files\\MyApp -L -S"));
	CreateProcess(NULL, szCmdline, /* ... */);

Jika pengguna jahat membuat aplikasi yang disebut "Program.exe" pada sistem, program apa pun yang salah memanggil CreateProcess menggunakan direktori Program Files akan menjalankan aplikasi ini alih-alih aplikasi yang dimaksudkan.

Untuk menghindari masalah ini, jangan lewati NULL untuk lpApplicationName. Jika Anda melewati NULL untuk lpApplicationName, gunakan tanda kutip di sekitar jalur yang dapat dieksekusi di lpCommandLine, seperti yang ditunjukkan pada contoh di bawah ini.

	LPTSTR szCmdline[] = _tcsdup(TEXT("\"C:\\Program Files\\MyApp\" -L -S"));
	CreateProcess(NULL, szCmdline, /*...*/);

Contoh

Misalnya, lihat Membuat Proses.

Catatan

Header processthreadsapi.h mendefinisikan CreateProcess sebagai alias yang secara otomatis memilih versi ANSI atau Unicode dari fungsi ini berdasarkan definisi konstanta praprosesor UNICODE. Mencampur penggunaan alias encoding-netral dengan kode yang tidak mengodekan-netral dapat menyebabkan ketidakcocokan yang mengakibatkan kesalahan kompilasi atau runtime. Untuk informasi selengkapnya, lihat Konvensi untuk Prototipe Fungsi.

Persyaratan

   
Klien minimum yang didukung Windows XP [aplikasi desktop | Aplikasi UWP]
Server minimum yang didukung Windows Server 2003 [aplikasi desktop | Aplikasi UWP]
Target Platform Windows
Header processthreadsapi.h (termasuk Windows.h pada Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2)
Pustaka Kernel32.lib
DLL Kernel32.dll

Lihat juga

CloseHandle

ShellExecuteA

CreateProcessAsUser

CreateProcessWithLogonW

ExitProcess

GetCommandLine

GetEnvironmentStrings

GetExitCodeProcess

GetFullPathName

GetStartupInfo

OpenProcess

PROCESS_INFORMATION

Fungsi Proses dan Utas

Proses

SECURITY_ATTRIBUTES

STARTUPINFO

STARTUPINFOEX

SetErrorMode

TerminateProcess

WaitForInputIdle