mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
support more process creation options on Windows
Adds a CreateProcessFlags packed struct for all the possible flags to CreateProcessW on windows. In addition, propagates the existing `start_suspended` option in std.process.Child which was previously only used on Darwin. Also adds a `create_no_window` option to std.process.Child which is a commonly used flag for launching console executables on windows without causing a new console window to "pop up".
This commit is contained in:
parent
8a8b3019f3
commit
1408288b95
@ -1918,13 +1918,48 @@ pub const CreateProcessError = error{
|
||||
Unexpected,
|
||||
};
|
||||
|
||||
pub const CreateProcessFlags = packed struct(u32) {
|
||||
debug_process: bool = false,
|
||||
debug_only_this_process: bool = false,
|
||||
create_suspended: bool = false,
|
||||
detached_process: bool = false,
|
||||
create_new_console: bool = false,
|
||||
normal_priority_class: bool = false,
|
||||
idle_priority_class: bool = false,
|
||||
high_priority_class: bool = false,
|
||||
realtime_priority_class: bool = false,
|
||||
create_new_process_group: bool = false,
|
||||
create_unicode_environment: bool = false,
|
||||
create_separate_wow_vdm: bool = false,
|
||||
create_shared_wow_vdm: bool = false,
|
||||
create_forcedos: bool = false,
|
||||
below_normal_priority_class: bool = false,
|
||||
above_normal_priority_class: bool = false,
|
||||
inherit_parent_affinity: bool = false,
|
||||
inherit_caller_priority: bool = false,
|
||||
create_protected_process: bool = false,
|
||||
extended_startupinfo_present: bool = false,
|
||||
process_mode_background_begin: bool = false,
|
||||
process_mode_background_end: bool = false,
|
||||
create_secure_process: bool = false,
|
||||
_reserved: bool = false,
|
||||
create_breakaway_from_job: bool = false,
|
||||
create_preserve_code_authz_level: bool = false,
|
||||
create_default_error_mode: bool = false,
|
||||
create_no_window: bool = false,
|
||||
profile_user: bool = false,
|
||||
profile_kernel: bool = false,
|
||||
profile_server: bool = false,
|
||||
create_ignore_system_default: bool = false,
|
||||
};
|
||||
|
||||
pub fn CreateProcessW(
|
||||
lpApplicationName: ?LPCWSTR,
|
||||
lpCommandLine: ?LPWSTR,
|
||||
lpProcessAttributes: ?*SECURITY_ATTRIBUTES,
|
||||
lpThreadAttributes: ?*SECURITY_ATTRIBUTES,
|
||||
bInheritHandles: BOOL,
|
||||
dwCreationFlags: DWORD,
|
||||
dwCreationFlags: CreateProcessFlags,
|
||||
lpEnvironment: ?*anyopaque,
|
||||
lpCurrentDirectory: ?LPCWSTR,
|
||||
lpStartupInfo: *STARTUPINFOW,
|
||||
|
||||
@ -314,7 +314,7 @@ pub extern "kernel32" fn CreateProcessW(
|
||||
lpProcessAttributes: ?*SECURITY_ATTRIBUTES,
|
||||
lpThreadAttributes: ?*SECURITY_ATTRIBUTES,
|
||||
bInheritHandles: BOOL,
|
||||
dwCreationFlags: DWORD,
|
||||
dwCreationFlags: windows.CreateProcessFlags,
|
||||
lpEnvironment: ?LPVOID,
|
||||
lpCurrentDirectory: ?LPCWSTR,
|
||||
lpStartupInfo: *STARTUPINFOW,
|
||||
|
||||
@ -80,9 +80,13 @@ expand_arg0: Arg0Expand,
|
||||
/// Darwin-only. Disable ASLR for the child process.
|
||||
disable_aslr: bool = false,
|
||||
|
||||
/// Darwin-only. Start child process in suspended state as if SIGSTOP was sent.
|
||||
/// Darwin and Windows only. Start child process in suspended state. For Darwin it's started
|
||||
/// as if SIGSTOP was sent.
|
||||
start_suspended: bool = false,
|
||||
|
||||
/// Windows-only. Sets the CREATE_NO_WINDOW flag in CreateProcess.
|
||||
create_no_window: bool = false,
|
||||
|
||||
/// Set to true to obtain rusage information for the child process.
|
||||
/// Depending on the target platform and implementation status, the
|
||||
/// requested statistics may or may not be available. If they are
|
||||
@ -854,6 +858,12 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void {
|
||||
const app_name_w = try unicode.wtf8ToWtf16LeAllocZ(self.allocator, app_basename_wtf8);
|
||||
defer self.allocator.free(app_name_w);
|
||||
|
||||
const flags: windows.CreateProcessFlags = .{
|
||||
.create_suspended = self.start_suspended,
|
||||
.create_unicode_environment = true,
|
||||
.create_no_window = self.create_no_window,
|
||||
};
|
||||
|
||||
run: {
|
||||
const PATH: [:0]const u16 = process.getenvW(unicode.utf8ToUtf16LeStringLiteral("PATH")) orelse &[_:0]u16{};
|
||||
const PATHEXT: [:0]const u16 = process.getenvW(unicode.utf8ToUtf16LeStringLiteral("PATHEXT")) orelse &[_:0]u16{};
|
||||
@ -889,7 +899,7 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void {
|
||||
dir_buf.shrinkRetainingCapacity(normalized_len);
|
||||
}
|
||||
|
||||
windowsCreateProcessPathExt(self.allocator, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo) catch |no_path_err| {
|
||||
windowsCreateProcessPathExt(self.allocator, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo) catch |no_path_err| {
|
||||
const original_err = switch (no_path_err) {
|
||||
// argv[0] contains unsupported characters that will never resolve to a valid exe.
|
||||
error.InvalidArg0 => return error.FileNotFound,
|
||||
@ -917,7 +927,7 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void {
|
||||
const normalized_len = windows.normalizePath(u16, dir_buf.items) catch continue;
|
||||
dir_buf.shrinkRetainingCapacity(normalized_len);
|
||||
|
||||
if (windowsCreateProcessPathExt(self.allocator, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo)) {
|
||||
if (windowsCreateProcessPathExt(self.allocator, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo)) {
|
||||
break :run;
|
||||
} else |err| switch (err) {
|
||||
// argv[0] contains unsupported characters that will never resolve to a valid exe.
|
||||
@ -1016,6 +1026,7 @@ fn windowsCreateProcessPathExt(
|
||||
cmd_line_cache: *WindowsCommandLineCache,
|
||||
envp_ptr: ?[*]u16,
|
||||
cwd_ptr: ?[*:0]u16,
|
||||
flags: windows.CreateProcessFlags,
|
||||
lpStartupInfo: *windows.STARTUPINFOW,
|
||||
lpProcessInformation: *windows.PROCESS_INFORMATION,
|
||||
) !void {
|
||||
@ -1166,7 +1177,7 @@ fn windowsCreateProcessPathExt(
|
||||
else
|
||||
full_app_name;
|
||||
|
||||
if (windowsCreateProcess(app_name_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_ptr, lpStartupInfo, lpProcessInformation)) |_| {
|
||||
if (windowsCreateProcess(app_name_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_ptr, flags, lpStartupInfo, lpProcessInformation)) |_| {
|
||||
return;
|
||||
} else |err| switch (err) {
|
||||
error.FileNotFound,
|
||||
@ -1221,7 +1232,7 @@ fn windowsCreateProcessPathExt(
|
||||
else
|
||||
full_app_name;
|
||||
|
||||
if (windowsCreateProcess(app_name_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_ptr, lpStartupInfo, lpProcessInformation)) |_| {
|
||||
if (windowsCreateProcess(app_name_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_ptr, flags, lpStartupInfo, lpProcessInformation)) |_| {
|
||||
return;
|
||||
} else |err| switch (err) {
|
||||
error.FileNotFound => continue,
|
||||
@ -1247,6 +1258,7 @@ fn windowsCreateProcess(
|
||||
cmd_line: [*:0]u16,
|
||||
envp_ptr: ?[*]u16,
|
||||
cwd_ptr: ?[*:0]u16,
|
||||
flags: windows.CreateProcessFlags,
|
||||
lpStartupInfo: *windows.STARTUPINFOW,
|
||||
lpProcessInformation: *windows.PROCESS_INFORMATION,
|
||||
) !void {
|
||||
@ -1273,7 +1285,7 @@ fn windowsCreateProcess(
|
||||
null,
|
||||
null,
|
||||
windows.TRUE,
|
||||
windows.CREATE_UNICODE_ENVIRONMENT,
|
||||
flags,
|
||||
@as(?*anyopaque, @ptrCast(envp_ptr)),
|
||||
cwd_ptr,
|
||||
lpStartupInfo,
|
||||
|
||||
@ -138,7 +138,7 @@ fn spawnVerify(verify_path: [:0]const u16, cmd_line: [:0]const u16) !windows.DWO
|
||||
null,
|
||||
null,
|
||||
windows.TRUE,
|
||||
0,
|
||||
.{},
|
||||
null,
|
||||
null,
|
||||
&startup_info,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user