Closed Nuklon closed 1 year ago
CsWin32 defaults to non-preserve sig for COM methods. A failing HRESULT will result in a thrown COMException
with a property retaining the original error code.
If you prefer to check a return value instead, see https://github.com/microsoft/CsWin32#customizing-generated-code for the preserveSig setting where in your NativeMethods.json file you can set specific methods or COM interfaces to use preserveSig instead.
Thanks, that seems to work. Now to find out how to create an instance of IGroupPolicyObject ☀️
Thanks, that seems to work. Now to find out how to create an instance of IGroupPolicyObject ☀️
Ah, that doesn't work right now due to allowMarshaling being set to false.
Why are you setting allowMarshaling to false? (there are legit reasons, but preservesig isn't one of them). I don't know why preserveSig false would prevent you from getting an instance of that interface. I don't know how to get an instance of that interface anyway (win32 is a big API and I certainly don't know all of it), but generally allowMarshaling:false shouldn't make anything impossible -- though maybe less convenient.
Because of this: https://github.com/microsoft/CsWin32/issues/992 With allowMarshaling on false you cannot cast it to another type. I'll give it a think on how do get around it.
With allowMarshaling on false you cannot cast it to another type.
Can you elaborate on this? I'm not aware of such a limitation, although the syntax may be slightly different.
Continuing with IGroupPolicyObject.
[ComImport, Guid("EA502722-A23D-11d1-A7D3-0000F87571E3")]
public class GroupPolicyObject
{
}
IGroupPolicyObject a = (IGroupPolicyObject)new GroupPolicyObject();
This would be the normal route. That works if you have allowMarshaling set to true (the default). But when you set it to false, you cannot cast it anymore as IGroupPolicyObject is not an interface. You can create a new instance of IGroupPolicyObject as it's a struct, but that created type doesn't do anything. It probably needs some kind of activation but I don't know what to activate.
It's probably because lpVtbl is 0, but I don't have any idea on how to set this. On .NET Framework PopulateVTable isn't available, and on .NET Core you cannot assign that to an isntance. But perhaps there's another way I don't know about.
when marshaling is disabled, an interface is still generated. So the following code compiles (when combined with CsWin32 generated IGroupPolicyObject
:
unsafe
{
object a = new GroupPolicyObject();
IGroupPolicyObject.Interface? i = (IGroupPolicyObject.Interface)a;
Console.WriteLine(a);
}
[ComImport, Guid("EA502722-A23D-11d1-A7D3-0000F87571E3")]
public class GroupPolicyObject
{
}
That said, it doesn't run properly. The cast to the interface fails. My best guess is that the GroupPolicyObject
class you declared is perhaps decorated with the wrong GUID so it's creating an object that doesn't implement the interface based on a matching GUID.
Hmm, I missed that one, thanks! It's the right GUID, but you need to annotate "main" with [STAThread], then you cast it correctly.
Actual behavior
For example, OpenLocalMachineGPO returns void, but this should return one of the COM error codes defined in the Platform SDK header file WinError.h. It's correct in metadata.
Expected behavior
Generate correctly.
Repro steps
NativeMethods.txt
content:Context
LangVersion
(if explicitly set by project): latest