RSCG – Com

RSCG – Com    

name Com
nuget https://www.nuget.org/packages/System.Runtime.InteropServices/
link https://learn.microsoft.com/en-us/dotnet/standard/native-interop/comwrappers-source-generation
author Microsoft

Generating Com Declarations

 

This is how you can use Com .

The code that you start with is

  <Project Sdk="Microsoft.NET.Sdk">    <PropertyGroup>     <OutputType>Exe</OutputType>     <TargetFramework>net8.0</TargetFramework>     <ImplicitUsings>enable</ImplicitUsings>     <Nullable>enable</Nullable> 	  <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <!--
<PackageReference Include="System.Runtime.InteropServices" />
-->   </PropertyGroup> 	<PropertyGroup> 		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> 		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> 	</PropertyGroup> </Project>   

The code that you will use is

  using test;  IShellExecute shellExecute = new ShellExecuteClass();  // Open a file using the default associated program IntPtr result = shellExecute.ShellExecute(     IntPtr.Zero, // HWND (handle to parent window)     "open",      // Operation to perform     "notepad.exe", // File to open (replace with your file or URL)     "",           // Parameters     "",           // Working directory     1            // Show command (SW_SHOWNORMAL) );  Console.WriteLine($"ShellExecute Result: {result}");   
  using System; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling;  namespace test;  // Import the ShellExecute function from Shell32.dll using ComImport [ComImport] [Guid("00000000-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IUnknown {     void QueryInterface(ref Guid riid, out IntPtr ppvObject);     void AddRef();     void Release(); }  //[ComImport] [GeneratedComInterface(StringMarshalling = StringMarshalling.Utf8)] [Guid("000214F9-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public partial interface IShellExecute {     IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd); }   // Replace this with your actual ShellExecute COM class public class ShellExecuteClass : IShellExecute {     public IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd)     {         // Implement the ShellExecute functionality         return NativeMethods.ShellExecute(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);     } }  // NativeMethods class to import necessary functions from Shell32.dll static class NativeMethods {     [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]     public static extern IntPtr ShellExecute(         IntPtr hwnd,         string lpOperation,         string lpFile,         string lpParameters,         string lpDirectory,         int nShowCmd     ); }   

  The code that is generated is

 // <auto-generated /> #pragma warning disable CS0612, CS0618 file unsafe class InterfaceInformation : global::System.Runtime.InteropServices.Marshalling.IIUnknownInterfaceType {     public static global::System.Guid Iid { get; } = new(new global::System.ReadOnlySpan<byte>(new byte[] { 249, 20, 2, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 70 }));      private static void** _vtable;     public static void** ManagedVirtualMethodTable => _vtable != null ? _vtable : (_vtable = InterfaceImplementation.CreateManagedVirtualFunctionTable()); }  [global::System.Runtime.InteropServices.DynamicInterfaceCastableImplementationAttribute] file unsafe partial interface InterfaceImplementation : global::test.IShellExecute {     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.ComInterfaceGenerator", "8.0.9.3103")]     [global::System.Runtime.CompilerServices.SkipLocalsInitAttribute]     nint global::test.IShellExecute.ShellExecute(nint hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd)     {         var(__this, __vtable_native) = ((global::System.Runtime.InteropServices.Marshalling.IUnmanagedVirtualMethodTableProvider)this).GetVirtualMethodTableInfoForKey(typeof(global::test.IShellExecute));         byte* __lpOperation_native = default;         byte* __lpFile_native = default;         byte* __lpParameters_native = default;         byte* __lpDirectory_native = default;         nint __retVal = default;         int __invokeRetVal = default;         // Setup - Perform required setup.         scoped global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __lpDirectory_native__marshaller = new();         scoped global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __lpParameters_native__marshaller = new();         scoped global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __lpFile_native__marshaller = new();         scoped global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __lpOperation_native__marshaller = new();         try         {             // Marshal - Convert managed data to native data.             __lpDirectory_native__marshaller.FromManaged(lpDirectory, stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize]);             __lpParameters_native__marshaller.FromManaged(lpParameters, stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize]);             __lpFile_native__marshaller.FromManaged(lpFile, stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize]);             __lpOperation_native__marshaller.FromManaged(lpOperation, stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize]);             {                 // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.                 __lpDirectory_native = __lpDirectory_native__marshaller.ToUnmanaged();                 __lpParameters_native = __lpParameters_native__marshaller.ToUnmanaged();                 __lpFile_native = __lpFile_native__marshaller.ToUnmanaged();                 __lpOperation_native = __lpOperation_native__marshaller.ToUnmanaged();                 __invokeRetVal = ((delegate* unmanaged[MemberFunction]<void*, nint, byte*, byte*, byte*, byte*, int, nint*, int> )__vtable_native[3])(__this, hwnd, __lpOperation_native, __lpFile_native, __lpParameters_native, __lpDirectory_native, nShowCmd, &__retVal);             }              // NotifyForSuccessfulInvoke - Keep alive any managed objects that need to stay alive across the call.             global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(__invokeRetVal);             global::System.GC.KeepAlive(this);         }         finally         {             // CleanupCallerAllocated - Perform cleanup of caller allocated resources.             __lpDirectory_native__marshaller.Free();             __lpParameters_native__marshaller.Free();             __lpFile_native__marshaller.Free();             __lpOperation_native__marshaller.Free();         }          return __retVal;     } }  file unsafe partial interface InterfaceImplementation {     [global::System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute(CallConvs = new[] { typeof(global::System.Runtime.CompilerServices.CallConvMemberFunction) })]     internal static int ABI_ShellExecute(global::System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch* __this_native, nint hwnd, byte* __lpOperation_native, byte* __lpFile_native, byte* __lpParameters_native, byte* __lpDirectory_native, int nShowCmd, nint* __invokeRetValUnmanaged__param)     {         global::test.IShellExecute @this = default;         string lpOperation = default;         string lpFile = default;         string lpParameters = default;         string lpDirectory = default;         ref nint __invokeRetValUnmanaged = ref *__invokeRetValUnmanaged__param;         nint __invokeRetVal = default;         int __retVal = default;         try         {             // Unmarshal - Convert native data to managed data.             lpDirectory = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__lpDirectory_native);             lpParameters = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__lpParameters_native);             lpFile = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__lpFile_native);             lpOperation = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__lpOperation_native);             @this = global::System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch.GetInstance<global::test.IShellExecute>(__this_native);             __invokeRetVal = @this.ShellExecute(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);             // NotifyForSuccessfulInvoke - Keep alive any managed objects that need to stay alive across the call.             __retVal = 0; // S_OK             // Marshal - Convert managed data to native data.             __invokeRetValUnmanaged = __invokeRetVal;         }         catch (global::System.Exception __exception)         {             __retVal = global::System.Runtime.InteropServices.Marshalling.ExceptionAsHResultMarshaller<int>.ConvertToUnmanaged(__exception);         }          return __retVal;     } }  file unsafe partial interface InterfaceImplementation {     internal static void** CreateManagedVirtualFunctionTable()     {         void** vtable = (void**)global::System.Runtime.CompilerServices.RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(global::test.IShellExecute), sizeof(void*) * 4);         {             nint v0, v1, v2;             global::System.Runtime.InteropServices.ComWrappers.GetIUnknownImpl(out v0, out v1, out v2);             vtable[0] = (void*)v0;             vtable[1] = (void*)v1;             vtable[2] = (void*)v2;         }          {             vtable[3] = (void*)(delegate* unmanaged[MemberFunction]<global::System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch*, nint, byte*, byte*, byte*, byte*, int, nint*, int> )&ABI_ShellExecute;         }          return vtable;     } }  namespace test {     [global::System.Runtime.InteropServices.Marshalling.IUnknownDerivedAttribute<InterfaceInformation, InterfaceImplementation>]     public partial interface IShellExecute     {     } }  namespace test {     public partial interface IShellExecute     {     } } 

Code and pdf at https://ignatandrei.github.io/RSCG_Examples/v2/docs/Com