I am porting this implementation (starting a process as desktop user) from [DllImport] to [LibraryImport] (.NET 8). Visual Studio Roslyn has changed the method 'AdjustTokenPrivileges' to
[LibraryImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool AdjustTokenPrivileges(IntPtr htok, [MarshalAs(UnmanagedType.Bool)] bool disall, ref TOKEN_PRIVILEGES newst, int len, IntPtr prev, IntPtr relen);
and I get this error: SYSLIB1051: The type 'MyMethods.TOKEN_PRIVILEGES' is not supported by source-generated P/Invokes. The generated source will not handle marshalling of parameter 'newst'.
And the next method 'CreateProcessWithTokenW' is changed to
[LibraryImport("advapi32", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool CreateProcessWithTokenW(IntPtr hToken, int dwLogonFlags, string lpApplicationName, string lpCommandLine, int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
where the error is: SYSLIB1051: The type 'MyMethods.STARTUPINFO' is not supported by source-generated P/Invokes. The generated source will not handle marshalling of parameter 'lpStartupInfo'.
I tried to change Int32 to int and UInt32 to uint and changed string to unsafe char* as proposed here. I also tried to implement the answer from CaiB but I couldn't get through it.
Well, I don't know what crazy mind has imagined the new soure generation for p/invoke, but it's far from being simple. It's much more powerful than the previous one and let you finely tune things, but there are obvious and simple things that it cannot do alone, and it's generally not 100% compatible, work has to be done. You can add to that the far-from-being-complete documentation.
Ok, so there's the concept of blittable types (a type that is the same at binary level, whatever piece of code, managed or unmanaged, accesses it). It's not new at all but it seems the list of what's blittable has been restricted. Apparently, an array of blittable types, of constant size is not considered as blittable itself anymore...
So, when a type is not blittable, you must marshal the type by yourself, as stated here: https://github.com/dotnet/runtime/issues/75376
Enough ranting, here is a sample for a marshaller for
TOKEN_PRIVILEGES:Some useful documentation: User Defined Type Marshalling for Source-Generated Interop and Tutorial: Use custom marshallers in source-generated P/Invokes
And you can call it like that:
For the second one, just remove
[In], for some reasons, the generator chokes on it:I've put a full source copy here: https://gist.github.com/smourier/70cc9208b47534ba475279a4554180ce
Now, it's interesting to look at the generated code:
As you can see, in the end, it's just calling the method using the
DllImportway with the unmanaged struct. So in this case, I don't think it's useful to useLibraryImportat all.PS: in this very special case, since it's an array of 1 element, you could just declare this: