Skip to content

IShellDispatch2.ShellExecute causes NotSupportedException: BSTR cannot be marshalled to a Variant #862

@jnm2

Description

@jnm2

System.NotSupportedException: 'Type 'Windows.Win32.Foundation.BSTR' cannot be marshalled to a Variant. Type library is not registered.'

https://learn.microsoft.com/en-us/windows/win32/shell/ishelldispatch2-shellexecute

Repro steps

  1. NativeMethods.txt content:
ShellWindows
CSIDL_DESKTOP
IServiceProvider
ShellWindowTypeConstants
ShellWindowFindWindowOptions
IShellBrowser
SID_STopLevelBrowser
_SVGIO
IDispatch
IShellFolderViewDual
IShellDispatch2
SHOW_WINDOW_CMD
  1. NativeMethods.json content (if present):
  1. Any of your own code that should be shared?
using System;
using Windows.Win32.UI.Shell;
using Windows.Win32;
using System.Runtime.InteropServices;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;

internal static class ProcessUtils
{
    public static void StartProcessWithoutElevation(string fileName, string workingDirectory)
    {
        var shellWindows = (IShellWindows)new ShellWindows();

        var serviceProvider = (IServiceProvider)shellWindows.FindWindowSW(
            PInvoke.CSIDL_DESKTOP,
            pvarLocRoot: null,
            ShellWindowTypeConstants.SWC_DESKTOP,
            phwnd: out _,
            ShellWindowFindWindowOptions.SWFO_NEEDDISPATCH);

        var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke.SID_STopLevelBrowser, typeof(IShellBrowser).GUID);

        shellBrowser.QueryActiveShellView(out var shellView);

        shellView.GetItemObject((uint)_SVGIO.SVGIO_BACKGROUND, typeof(IDispatch).GUID, out var folderViewAsObject);

        var folderView = (IShellFolderViewDual)folderViewAsObject;
        var shellDispatch = (IShellDispatch2)folderView.Application;

        var fileNameAsBstr = (BSTR)Marshal.StringToBSTR(fileName);
        try
        {
            shellDispatch.ShellExecute(File: fileNameAsBstr, vArgs: null, vDir: workingDirectory, vOperation: "", SHOW_WINDOW_CMD.SW_NORMAL);
        }
        finally
        {
            Marshal.FreeBSTR(fileNameAsBstr);
        }
    }

    // Workaround for https://github.com/microsoft/CsWin32/issues/860
    [Guid("85CB6900-4D95-11CF-960C-0080C7F4EE85"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch), ComImport]
    private interface IShellWindows
    {
        [return: MarshalAs(UnmanagedType.IDispatch)]
        object FindWindowSW([MarshalAs(UnmanagedType.Struct)] in object pvarLoc, [MarshalAs(UnmanagedType.Struct)] in object? pvarLocRoot, ShellWindowTypeConstants swClass, out int phwnd, ShellWindowFindWindowOptions swfwOptions);
    }

    [Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComImport]
    private interface IServiceProvider
    {
        [return: MarshalAs(UnmanagedType.Interface)]
        object QueryService(in Guid guidService, in Guid riid);
    }

    // Workaround for https://github.com/microsoft/CsWin32/issues/861
    [ComImport, Guid("00020400-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    private interface IDispatch
    {
    }
}

Context

  • CsWin32 version: 0.2.188-beta
  • Win32Metadata version (if explicitly set by project):
  • Target Framework: net6.0-windows8
  • LangVersion (if explicitly set by project): latest

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions