C
C#13mo ago
Frodolon

❔ Using STARTUPINFOEXW on PInvoke.CreateProcess - how to move from ref / out to pointer?

I'm using CsWin32 but I'm having trouble calling PInvoke.CreateProcess using a STARTUPINFOEXW instead of a STARTUPINFOW at argument 9 (in info). Looking at https://github.com/microsoft/CsWin32/issues/917 it says to instead of doing
PInvoke.CreateProcess(null, ref cmdLine, null, null, false, PROCESS_CREATION_FLAGS.EXTENDED_STARTUPINFO_PRESENT, null, null, in info, out var processInformation);
PInvoke.CreateProcess(null, ref cmdLine, null, null, false, PROCESS_CREATION_FLAGS.EXTENDED_STARTUPINFO_PRESENT, null, null, in info, out var processInformation);
I should use the variant using pointers... but I can't seem to figure out how to correctly refer to my Span<char> cmdLine = stackalloc char[execPath.Length]; and my STARTUPINFOEXW info = new STARTUPINFOEXW() using pointers or replacing out var with pointers
9 Replies
Chiyoko_S
Chiyoko_S13mo ago
span - you can just take the pointer by doing Unsafe.AsPointer(ref MemoryMarshal.AsRef(cmdLine)) ...or just do char* cmdLine = stackalloc char[...] out T name is just glorified T* so just do &info
Frodolon
Frodolon13mo ago
This is the signature of the pointer variant btw
Frodolon
Frodolon13mo ago
Ok, I managed to get a char* through fixed (char* cmdLine = execPath) { /* code */ }
ero
ero13mo ago
or just do char* cmdLine = stackalloc char[...]
Frodolon
Frodolon13mo ago
I already had another string Really, the main problem is Visual Studio displaying the error messages for the version using refs etc. making the error messages utterly useless This feels like it should work:
string execPath = "notepad.exe\0";
nuint* size = default;
PInvoke.InitializeProcThreadAttributeList(default, 1, 0, size);
STARTUPINFOEXW info = new STARTUPINFOEXW();
info.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)Windows.Win32.PInvoke.LocalAlloc(0, (nuint)size).Value;
fixed (char* cmdLine = execPath)
{
PROCESS_INFORMATION* procInfoPtr = default;
PInvoke.CreateProcess(null, cmdLine, null, null, false, PROCESS_CREATION_FLAGS.EXTENDED_STARTUPINFO_PRESENT, null, null, &info, procInfoPtr);
}
string execPath = "notepad.exe\0";
nuint* size = default;
PInvoke.InitializeProcThreadAttributeList(default, 1, 0, size);
STARTUPINFOEXW info = new STARTUPINFOEXW();
info.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)Windows.Win32.PInvoke.LocalAlloc(0, (nuint)size).Value;
fixed (char* cmdLine = execPath)
{
PROCESS_INFORMATION* procInfoPtr = default;
PInvoke.CreateProcess(null, cmdLine, null, null, false, PROCESS_CREATION_FLAGS.EXTENDED_STARTUPINFO_PRESENT, null, null, &info, procInfoPtr);
}
It still complains about the CreateProcess arguments though (Can't convert STARTUPINFOEXW to STARTUPINFOW etc.) Ah, got it working: PInvoke.CreateProcess(null, cmdLine, null, null, false, PROCESS_CREATION_FLAGS.EXTENDED_STARTUPINFO_PRESENT, null, null, (STARTUPINFOW*)&info, procInfoPtr);
ero
ero13mo ago
good luck with that nuint* size = default; lol
Frodolon
Frodolon13mo ago
Already fixed that :P Still doesn't work but runs Hmm, CreateProcess gives error 87 - The Parameter is Incorrect - the reason I'm even trying to do all this is that I'm trying to reimplement https://scorpiosoftware.net/2019/01/15/fun-with-appcontainers/ in C# to play around with AppContainers...
Frodolon
Frodolon13mo ago
Gist
The Parameter is incorrect?
The Parameter is incorrect? GitHub Gist: instantly share code, notes, and snippets.
Accord
Accord13mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.