jborean
jborean
CC#
Created by jborean on 11/20/2024 in #help
Using stackalloc span in if statement
ah ok, that makes more sense as I was wracking my brain to figure out how it could have escaped it. Putting scope ... entry did the trick though so thank you very much
5 replies
CC#
Created by jborean on 11/20/2024 in #help
Using stackalloc span in if statement
Thanks I appreciate, I'll have to read through that post as I don't understand how it could be used outside of its valid context but maybe that's just my misunderstanding of spans really
5 replies
CC#
Created by jborean on 4/28/2024 in #help
AssemblyLoadContext LoadfromAssemblyPath vs LoadFromNativeImagePath
Thanks, appreciate the explanation!
8 replies
CC#
Created by jborean on 4/28/2024 in #help
AssemblyLoadContext LoadfromAssemblyPath vs LoadFromNativeImagePath
Ah ok, explains why pwzNIPath was never actually used there. So there were cases where you could have had 2 files for an assembly to load?
8 replies
CC#
Created by jborean on 4/28/2024 in #help
AssemblyLoadContext LoadfromAssemblyPath vs LoadFromNativeImagePath
I can see both end up calling AssemblyNative_LoadFromPath where the assemblyPath arg is the pwzILPath and nativeImagePath is pwzNIPath but it seems like the latter is not used at all in that situation?
8 replies
CC#
Created by jborean on 4/8/2024 in #help
sans-io pattern in .NET library
That's my apprehension with Pipelines is that it's not a simple thing to work with but the alternative of just accepting a byte array and emitting one seems wasteful from a memory/copy perspective
6 replies
CC#
Created by jborean on 4/8/2024 in #help
sans-io pattern in .NET library
Yea I have one currently for LDAP in .NET but it's somewhat tied to a PowerShell module. I'm contemplating splitting it out into a dedicated nuget package but this is the part I'm trying to figure out a good pattern for. It currently uses System.IO.Pipelines but I'm not sure if there's potentially a better alternative out there
6 replies
CC#
Created by jborean on 3/26/2024 in #help
Invoke method with [Optional] with default value through Reflection
6 replies
CC#
Created by jborean on 3/26/2024 in #help
Invoke method with [Optional] with default value through Reflection
It does work for TestMethod1 and TestMethod3 though
6 replies
CC#
Created by jborean on 3/26/2024 in #help
Invoke method with [Optional] with default value through Reflection
I realised I never shared the error when trying to use Invoke(null, new[] { Type.Missing }); for TestMethod2, it is
Object of type 'System.Reflection.Missing' cannot be converted to type 'System.Int32'.
Object of type 'System.Reflection.Missing' cannot be converted to type 'System.Int32'.
6 replies
CC#
Created by jborean on 3/26/2024 in #help
Invoke method with [Optional] with default value through Reflection
Hmm no that won't work as the DefaultValue is Type.Missing when no explicit default value is set
Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;

public class MyClass
{
public static int TestMethod1(int value = 1) => value;
public static int TestMethod2([Optional] int value) => value;
public static int TestMethod3([Optional, DefaultParameterValue(1)] int value) => value;
}
'@

[MyClass].GetMethod('TestMethod1').GetParameters()

ParameterType : System.Int32
Name : value
HasDefaultValue : True
DefaultValue : 1
RawDefaultValue : 1
MetadataToken : 134217729
Attributes : Optional, HasDefault
Member : Int32 TestMethod1(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}

[MyClass].GetMethod('TestMethod2').GetParameters()

ParameterType : System.Int32
Name : value
HasDefaultValue : False
DefaultValue : System.Reflection.Missing
RawDefaultValue : System.Reflection.Missing
MetadataToken : 134217730
Attributes : Optional
Member : Int32 TestMethod2(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}

[MyClass].GetMethod('TestMethod3').GetParameters()

ParameterType : System.Int32
Name : value
HasDefaultValue : True
DefaultValue : 1
RawDefaultValue : 1
MetadataToken : 134217731
Attributes : Optional, HasDefault
Member : Int32 TestMethod3(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}
Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;

public class MyClass
{
public static int TestMethod1(int value = 1) => value;
public static int TestMethod2([Optional] int value) => value;
public static int TestMethod3([Optional, DefaultParameterValue(1)] int value) => value;
}
'@

[MyClass].GetMethod('TestMethod1').GetParameters()

ParameterType : System.Int32
Name : value
HasDefaultValue : True
DefaultValue : 1
RawDefaultValue : 1
MetadataToken : 134217729
Attributes : Optional, HasDefault
Member : Int32 TestMethod1(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}

[MyClass].GetMethod('TestMethod2').GetParameters()

ParameterType : System.Int32
Name : value
HasDefaultValue : False
DefaultValue : System.Reflection.Missing
RawDefaultValue : System.Reflection.Missing
MetadataToken : 134217730
Attributes : Optional
Member : Int32 TestMethod2(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}

[MyClass].GetMethod('TestMethod3').GetParameters()

ParameterType : System.Int32
Name : value
HasDefaultValue : True
DefaultValue : 1
RawDefaultValue : 1
MetadataToken : 134217731
Attributes : Optional, HasDefault
Member : Int32 TestMethod3(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}
6 replies
CC#
Created by jborean on 3/26/2024 in #help
Invoke method with [Optional] with default value through Reflection
I'm assuming I'll have to get the ParameterInfo for the argument, check if IsOptional and use DefaultValue to get the default value to pass in rather than Type.Missing
6 replies
CC#
Created by jborean on 3/1/2024 in #help
✅ COM + NativeAOT Help
As sorry I wasn’t aware that was a thing here 🙂
32 replies
CC#
Created by jborean on 3/1/2024 in #help
✅ COM + NativeAOT Help
Thanks for the advice!
32 replies
CC#
Created by jborean on 3/1/2024 in #help
✅ COM + NativeAOT Help
Do I need to keep the WTSPlugin instance alive as a static field or can it be dropped after providing the pointer to it?
32 replies
CC#
Created by jborean on 3/1/2024 in #help
✅ COM + NativeAOT Help
but as you said if it works it works
32 replies
CC#
Created by jborean on 3/1/2024 in #help
✅ COM + NativeAOT Help
I'm assuming I messed up my ppObjArray signature and setting that value somehow
32 replies
CC#
Created by jborean on 3/1/2024 in #help
✅ COM + NativeAOT Help
you're telling me 🙂
32 replies
CC#
Created by jborean on 3/1/2024 in #help
✅ COM + NativeAOT Help
Used ConvertToUnmanaged and played around with the ppObjArray signature
32 replies
CC#
Created by jborean on 3/1/2024 in #help
✅ COM + NativeAOT Help
[UnmanagedCallersOnly(EntryPoint = "VirtualChannelGetInstance", CallConvs = [typeof(CallConvStdcall)])]
private unsafe static int VirtualChannelGetInstance(
Guid* refiid,
int* pNumObjs,
void** ppObjArray
)
{
using StreamWriter writer = new(@"C:\temp\ProcessVirtualChannel\VirtualChannelGetInstance-log.txt", true);
string now = DateTime.Now.ToString("[HH:mm:ss.fff]");
writer.WriteLine($"{now} - VirtualChannelGetInstance - {*pNumObjs}");

if (*refiid != typeof(IWTSPlugin).GUID)
{
return unchecked((int)0x80004002); // E_NOINTERFACE
}

*pNumObjs = 1;
if (ppObjArray != null)
{
void* unmanagedPtr = ComInterfaceMarshaller<IWTSPlugin>.ConvertToUnmanaged(_plugin);
*ppObjArray = unmanagedPtr;

now = DateTime.Now.ToString("[HH:mm:ss.fff]");
writer.WriteLine($"{now} - Created pointer - {*pNumObjs}");
}
else
{
now = DateTime.Now.ToString("[HH:mm:ss.fff]");
writer.WriteLine($"{now} - setting pNumObjs");
}

return 0;
}
[UnmanagedCallersOnly(EntryPoint = "VirtualChannelGetInstance", CallConvs = [typeof(CallConvStdcall)])]
private unsafe static int VirtualChannelGetInstance(
Guid* refiid,
int* pNumObjs,
void** ppObjArray
)
{
using StreamWriter writer = new(@"C:\temp\ProcessVirtualChannel\VirtualChannelGetInstance-log.txt", true);
string now = DateTime.Now.ToString("[HH:mm:ss.fff]");
writer.WriteLine($"{now} - VirtualChannelGetInstance - {*pNumObjs}");

if (*refiid != typeof(IWTSPlugin).GUID)
{
return unchecked((int)0x80004002); // E_NOINTERFACE
}

*pNumObjs = 1;
if (ppObjArray != null)
{
void* unmanagedPtr = ComInterfaceMarshaller<IWTSPlugin>.ConvertToUnmanaged(_plugin);
*ppObjArray = unmanagedPtr;

now = DateTime.Now.ToString("[HH:mm:ss.fff]");
writer.WriteLine($"{now} - Created pointer - {*pNumObjs}");
}
else
{
now = DateTime.Now.ToString("[HH:mm:ss.fff]");
writer.WriteLine($"{now} - setting pNumObjs");
}

return 0;
}
32 replies