chore: use CsWin32 source generator instead of random pinvoke library (#10361)

* chore: use CsWin32 source generator instead of random pinvoke library

* fix: use local D3D12CreateDevice definition
This commit is contained in:
dantmnf
2024-08-25 19:46:32 +08:00
committed by GitHub
parent bdfc1f139c
commit e227d71813
6 changed files with 162 additions and 72 deletions

View File

@@ -55,5 +55,10 @@ namespace MaaWpfGui.Extensions
{
return dt is { Month: 4, Day: 1 };
}
public static DateTime ToDateTime(this System.Runtime.InteropServices.ComTypes.FILETIME filetime)
{
return DateTime.FromFileTime(((long)filetime.dwHighDateTime << 32) | (uint)filetime.dwLowDateTime);
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Win32.Foundation;
namespace MaaWpfGui.Extensions
{
internal static class Win32Extension
{
public static long AsLong(this LUID luid)
{
return ((long)luid.HighPart << 32) | luid.LowPart;
}
}
}

View File

@@ -19,11 +19,17 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using DirectN;
using MaaWpfGui.Constants;
using MaaWpfGui.Extensions;
using Microsoft.Win32;
using Vanara.Extensions;
using Vanara.PInvoke;
using Windows.Win32;
using Windows.Win32.Devices.DeviceAndDriverInstallation;
using Windows.Win32.Devices.Display;
using Windows.Win32.Devices.Properties;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Direct3D;
using Windows.Win32.Graphics.Direct3D12;
using Windows.Win32.Graphics.Dxgi;
namespace MaaWpfGui.Helper
{
@@ -120,8 +126,8 @@ namespace MaaWpfGui.Helper
}
}
var hr = DXGIFunctions.CreateDXGIFactory2(0, typeof(IDXGIFactory4).GUID, out var comobj);
if (!hr.IsSuccess)
var hr = PInvoke.CreateDXGIFactory2(0, typeof(IDXGIFactory4).GUID, out var comobj);
if (hr.Failed)
{
return null;
}
@@ -147,7 +153,7 @@ namespace MaaWpfGui.Helper
{
IDXGIAdapter1 adapter;
var hr = factory.EnumAdapters1(i, out adapter);
if (hr == HRESULTS.DXGI_ERROR_NOT_FOUND)
if (hr == HRESULT.DXGI_ERROR_NOT_FOUND)
{
break;
}
@@ -156,8 +162,8 @@ namespace MaaWpfGui.Helper
i++;
var desc = adapter.GetDesc1();
var instance_path = GetAdapterInstancePath((ulong)desc.AdapterLuid.Value);
var driverInfo = GetGpuDriverInformation(desc.Description, instance_path);
var instance_path = GetAdapterInstancePath(desc.AdapterLuid);
var driverInfo = GetGpuDriverInformation(desc.Description.ToString(), instance_path);
if (!CheckGpu(adapter, ref desc, instance_path, driverInfo, out var deprecated))
{
@@ -200,27 +206,40 @@ namespace MaaWpfGui.Helper
private static bool CheckD3D12Support(IDXGIAdapter1 adapter, bool requireFL12 = false)
{
// using the same feature level as onnxruntime does
var hr = D3D12Functions.D3D12CheckDeviceCreate<ID3D12Device>(adapter, requireFL12 ? D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_12_0 : D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0);
var hr = D3D12CreateDevice(adapter, requireFL12 ? D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_12_0 : D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0, typeof(ID3D12Device).GUID, 0);
return hr == HRESULTS.S_FALSE;
return hr == HRESULT.S_FALSE;
[DllImport("d3d12.dll", ExactSpelling = true)]
static extern HRESULT D3D12CreateDevice([MarshalAs(UnmanagedType.IUnknown)] object pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel, in Guid riid, nint ppDevice);
}
private static unsafe string? GetAdapterInstancePath(ulong luid)
private static unsafe string? GetAdapterInstancePath(LUID luid)
{
try
{
var adpname = User32.DisplayConfigGetDeviceInfo<Gdi32.DISPLAYCONFIG_ADAPTER_NAME>(luid, 0, Gdi32.DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME);
var req = new DISPLAYCONFIG_ADAPTER_NAME
{
header = new DISPLAYCONFIG_DEVICE_INFO_HEADER
{
size = (uint)sizeof(DISPLAYCONFIG_ADAPTER_NAME),
adapterId = luid,
id = 0,
type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME,
},
};
var adpname = PInvoke.DisplayConfigGetDeviceInfo(ref req.header);
var interface_path = adpname.adapterDevicePath;
var interface_path = req.adapterDevicePath.ToString();
uint size = 0;
var err = CfgMgr32.CM_Get_Device_Interface_Property(interface_path, SetupAPI.DEVPKEY_Device_InstanceId, out var type, IntPtr.Zero, ref size, 0);
var err = PInvoke.CM_Get_Device_Interface_Property(interface_path, PInvoke.DEVPKEY_Device_InstanceId, out var type, null, ref size, 0);
if (err != CfgMgr32.CONFIGRET.CR_BUFFER_SMALL)
if (err != CONFIGRET.CR_BUFFER_SMALL)
{
return null;
}
if (type != SetupAPI.DEVPROPTYPE.DEVPROP_TYPE_STRING)
if (type != DEVPROPTYPE.DEVPROP_TYPE_STRING)
{
return null;
}
@@ -230,8 +249,8 @@ namespace MaaWpfGui.Helper
fixed (byte* ptr = buf)
{
err = CfgMgr32.CM_Get_Device_Interface_Property(interface_path, SetupAPI.DEVPKEY_Device_InstanceId, out _, (nint)ptr, ref size, 0);
if (err != CfgMgr32.CONFIGRET.CR_SUCCESS)
err = PInvoke.CM_Get_Device_Interface_Property(interface_path, PInvoke.DEVPKEY_Device_InstanceId, out _, ptr, ref size, 0);
if (err != CONFIGRET.CR_SUCCESS)
{
return null;
}
@@ -286,29 +305,34 @@ namespace MaaWpfGui.Helper
return new(description, null, null);
}
var err = CfgMgr32.CM_Locate_DevNode(out var devinst, instance_path, CfgMgr32.CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_NORMAL);
uint devinst;
if (err != CfgMgr32.CONFIGRET.CR_SUCCESS)
fixed (char* ptr = instance_path)
{
return new(description, null, null);
var err2 = PInvoke.CM_Locate_DevNode(out devinst, ptr, CM_LOCATE_DEVNODE_FLAGS.CM_LOCATE_DEVNODE_NORMAL);
if (err2 != CONFIGRET.CR_SUCCESS)
{
return new(description, null, null);
}
}
System.Runtime.InteropServices.ComTypes.FILETIME ft;
uint size = (uint)sizeof(System.Runtime.InteropServices.ComTypes.FILETIME);
err = CfgMgr32.CM_Get_DevNode_Property(devinst, SetupAPI.DEVPKEY_Device_DriverDate, out _, (nint)(&ft), ref size, 0);
var err = PInvoke.CM_Get_DevNode_Property(devinst, PInvoke.DEVPKEY_Device_DriverDate, out _, (byte*)(&ft), ref size, 0);
if (err != CfgMgr32.CONFIGRET.CR_SUCCESS)
if (err != CONFIGRET.CR_SUCCESS)
{
return new(description, null, null);
}
var driverDate = ft.ToDateTime(DateTimeKind.Utc).Date;
var driverDate = ft.ToDateTime().Date;
size = 0;
err = CfgMgr32.CM_Get_DevNode_Property(devinst, SetupAPI.DEVPKEY_Device_DriverVersion, out _, 0, ref size, 0);
err = PInvoke.CM_Get_DevNode_Property(devinst, PInvoke.DEVPKEY_Device_DriverVersion, out _, null, ref size, 0);
if (err != CfgMgr32.CONFIGRET.CR_BUFFER_SMALL)
if (err != CONFIGRET.CR_BUFFER_SMALL)
{
return new(description, null, driverDate);
}
@@ -317,7 +341,7 @@ namespace MaaWpfGui.Helper
string? driverVersion = null;
fixed (byte* ptr = buf)
{
err = CfgMgr32.CM_Get_DevNode_Property(devinst, SetupAPI.DEVPKEY_Device_DriverVersion, out _, (nint)ptr, ref size, 0);
err = PInvoke.CM_Get_DevNode_Property(devinst, PInvoke.DEVPKEY_Device_DriverVersion, out _, ptr, ref size, 0);
driverVersion = Marshal.PtrToStringUni((nint)ptr);
}
@@ -327,7 +351,7 @@ namespace MaaWpfGui.Helper
private static bool CheckGpu(IDXGIAdapter1 adapter, ref DXGI_ADAPTER_DESC1 desc, string? instance_path, GpuDriverInformation driverInfo, out bool deprecated)
{
deprecated = false;
if ((desc.Flags & (uint)DXGI_ADAPTER_FLAG.DXGI_ADAPTER_FLAG_SOFTWARE) != 0)
if (((uint)desc.Flags & (uint)DXGI_ADAPTER_FLAG.DXGI_ADAPTER_FLAG_SOFTWARE) != 0)
{
// skip software device
return false;
@@ -511,7 +535,7 @@ namespace MaaWpfGui.Helper
public bool ShowIndex { get; set; }
public SpecificGpuOption(uint index, DXGI_ADAPTER_DESC1 description, string instance_path, GpuDriverInformation info)
internal SpecificGpuOption(uint index, DXGI_ADAPTER_DESC1 description, string instance_path, GpuDriverInformation info)
{
_index = index;
_description = description;
@@ -527,7 +551,7 @@ namespace MaaWpfGui.Helper
{
if (obj is SpecificGpuOption x)
{
return x._description.AdapterLuid.Value == _description.AdapterLuid.Value;
return x._description.AdapterLuid.AsLong() == _description.AdapterLuid.AsLong();
}
return false;
@@ -535,7 +559,7 @@ namespace MaaWpfGui.Helper
public override int GetHashCode() => (typeof(SpecificGpuOption), _description, _index, _instance_path).GetHashCode();
public override string ToString() => ShowIndex ? _description + $" (GPU {_index})" : _description.Description;
public override string ToString() => ShowIndex ? _description + $" (GPU {_index})" : _description.Description.ToString();
}
}
}

View File

@@ -15,11 +15,15 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows;
using HandyControl.Data;
using Vanara.PInvoke;
using Windows.Win32;
using Windows.Win32.UI.Controls;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.WindowsAndMessaging;
[assembly: SecurityCritical]
[assembly: SecurityTreatAsSafe]
@@ -157,7 +161,25 @@ namespace MaaWpfGui.Helper
}
}
public static MessageBoxResult ShowNative(
private unsafe readonly ref struct DisposablePin<T>
where T : unmanaged
{
private readonly GCHandle _handle;
public DisposablePin(object obj)
{
_handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
}
public T* AddrOfPinnedObject => (T*)_handle.AddrOfPinnedObject();
public void Dispose()
{
_handle.Free();
}
}
public static unsafe MessageBoxResult ShowNative(
WindowHandle ownerWindow,
string messageBoxText,
string mainInstruction = "",
@@ -171,41 +193,45 @@ namespace MaaWpfGui.Helper
string yes = "",
string no = "")
{
var config = new ComCtl32.TASKDIALOGCONFIG()
using var contentPin = new DisposablePin<char>(messageBoxText);
using var instructionPin = new DisposablePin<char>(mainInstruction);
using var titlePin = new DisposablePin<char>(windowTitle);
var config = new TASKDIALOGCONFIG()
{
Content = messageBoxText,
MainInstruction = mainInstruction,
WindowTitle = windowTitle,
hwndParent = ownerWindow.Handle,
pszContent = contentPin.AddrOfPinnedObject,
pszMainInstruction = instructionPin.AddrOfPinnedObject,
pszWindowTitle = titlePin.AddrOfPinnedObject,
hwndParent = (Windows.Win32.Foundation.HWND)ownerWindow.Handle,
nDefaultButton = (int)defaultButton,
dwFlags = ComCtl32.TASKDIALOG_FLAGS.TDF_POSITION_RELATIVE_TO_WINDOW | ComCtl32.TASKDIALOG_FLAGS.TDF_SIZE_TO_CONTENT,
dwFlags = TASKDIALOG_FLAGS.TDF_POSITION_RELATIVE_TO_WINDOW | TASKDIALOG_FLAGS.TDF_SIZE_TO_CONTENT,
};
if (alwaysAllowCancel)
{
config.dwFlags |= ComCtl32.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
config.dwFlags |= TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
}
switch (icon)
{
case MessageBoxImage.Information:
// case MessageBoxImage.Asterisk:
config.mainIcon = (IntPtr)ComCtl32.TaskDialogIcon.TD_INFORMATION_ICON;
config.Anonymous1.pszMainIcon = PInvoke.TD_INFORMATION_ICON;
break;
case MessageBoxImage.Hand:
// case MessageBoxImage.Stop:
// case MessageBoxImage.Error
config.mainIcon = (IntPtr)ComCtl32.TaskDialogIcon.TD_ERROR_ICON;
config.Anonymous1.pszMainIcon = PInvoke.TD_ERROR_ICON;
break;
case MessageBoxImage.Exclamation:
// case MessageBoxImage.Warning:
config.mainIcon = (IntPtr)ComCtl32.TaskDialogIcon.TD_WARNING_ICON;
config.Anonymous1.pszMainIcon = PInvoke.TD_WARNING_ICON;
break;
case MessageBoxImage.Question:
var iconInfo = new Shell32.SHSTOCKICONINFO { cbSize = (uint)Marshal.SizeOf<Shell32.SHSTOCKICONINFO>() };
Shell32.SHGetStockIconInfo(Shell32.SHSTOCKICONID.SIID_HELP, Shell32.SHGSI.SHGSI_ICON, ref iconInfo).ThrowIfFailed();
config.mainIcon = iconInfo.hIcon.DangerousGetHandle();
config.dwFlags |= ComCtl32.TASKDIALOG_FLAGS.TDF_USE_HICON_MAIN;
var iconInfo = new SHSTOCKICONINFO { cbSize = (uint)Marshal.SizeOf<SHSTOCKICONINFO>() };
PInvoke.SHGetStockIconInfo(SHSTOCKICONID.SIID_HELP, SHGSI_FLAGS.SHGSI_ICON, ref iconInfo).ThrowOnFailure();
config.Anonymous1.hMainIcon = iconInfo.hIcon;
config.dwFlags |= TASKDIALOG_FLAGS.TDF_USE_HICON_MAIN;
break;
case MessageBoxImage.None:
break;
@@ -214,7 +240,7 @@ namespace MaaWpfGui.Helper
}
bool hasOk = false, hasCancel = false, hasYes = false, hasNo = false;
var customButtons = new List<ComCtl32.TASKDIALOG_BUTTON>();
var customButtons = new List<TASKDIALOG_BUTTON>();
var gcHandles = new List<GCHandle>();
switch (buttons)
{
@@ -242,13 +268,13 @@ namespace MaaWpfGui.Helper
{
if (string.IsNullOrEmpty(ok))
{
config.dwCommonButtons |= ComCtl32.TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_OK_BUTTON;
config.dwCommonButtons |= TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_OK_BUTTON;
}
else
{
var gch = GCHandle.Alloc(ok, GCHandleType.Pinned);
gcHandles.Add(gch);
customButtons.Add(new ComCtl32.TASKDIALOG_BUTTON { nButtonID = (int)User32.MB_RESULT.IDOK, pszButtonText = gch.AddrOfPinnedObject() });
customButtons.Add(new TASKDIALOG_BUTTON { nButtonID = (int)MessageBoxResult.OK, pszButtonText = (char*)gch.AddrOfPinnedObject() });
}
}
@@ -256,13 +282,13 @@ namespace MaaWpfGui.Helper
{
if (string.IsNullOrEmpty(cancel))
{
config.dwCommonButtons |= ComCtl32.TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_CANCEL_BUTTON;
config.dwCommonButtons |= TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_CANCEL_BUTTON;
}
else
{
var gch = GCHandle.Alloc(cancel, GCHandleType.Pinned);
gcHandles.Add(gch);
customButtons.Add(new ComCtl32.TASKDIALOG_BUTTON { nButtonID = (int)User32.MB_RESULT.IDCANCEL, pszButtonText = gch.AddrOfPinnedObject() });
customButtons.Add(new TASKDIALOG_BUTTON { nButtonID = (int)MessageBoxResult.Cancel, pszButtonText = (char*)gch.AddrOfPinnedObject() });
}
}
@@ -270,13 +296,13 @@ namespace MaaWpfGui.Helper
{
if (string.IsNullOrEmpty(yes))
{
config.dwCommonButtons |= ComCtl32.TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_YES_BUTTON;
config.dwCommonButtons |= TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_YES_BUTTON;
}
else
{
var gch = GCHandle.Alloc(yes, GCHandleType.Pinned);
gcHandles.Add(gch);
customButtons.Add(new ComCtl32.TASKDIALOG_BUTTON { nButtonID = (int)User32.MB_RESULT.IDYES, pszButtonText = gch.AddrOfPinnedObject() });
customButtons.Add(new TASKDIALOG_BUTTON { nButtonID = (int)MessageBoxResult.Yes, pszButtonText = (char*)gch.AddrOfPinnedObject() });
}
}
@@ -284,13 +310,13 @@ namespace MaaWpfGui.Helper
{
if (string.IsNullOrEmpty(no))
{
config.dwCommonButtons |= ComCtl32.TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_NO_BUTTON;
config.dwCommonButtons |= TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_NO_BUTTON;
}
else
{
var gch = GCHandle.Alloc(no, GCHandleType.Pinned);
gcHandles.Add(gch);
customButtons.Add(new ComCtl32.TASKDIALOG_BUTTON { nButtonID = (int)User32.MB_RESULT.IDNO, pszButtonText = gch.AddrOfPinnedObject() });
customButtons.Add(new TASKDIALOG_BUTTON { nButtonID = (int)MessageBoxResult.No, pszButtonText = (char*)gch.AddrOfPinnedObject() });
}
}
@@ -299,26 +325,19 @@ namespace MaaWpfGui.Helper
var array = customButtons.ToArray();
var gch = GCHandle.Alloc(array, GCHandleType.Pinned);
gcHandles.Add(gch);
config.pButtons = gch.AddrOfPinnedObject();
config.pButtons = (TASKDIALOG_BUTTON*)gch.AddrOfPinnedObject();
config.cButtons = (uint)customButtons.Count;
}
ComCtl32.TaskDialogIndirect(config, out var button, out _, out _).ThrowIfFailed();
int button = 0;
PInvoke.TaskDialogIndirect(config, &button, null, null).ThrowOnFailure();
foreach (var h in gcHandles)
{
h.Free();
}
return button switch
{
(int)User32.MB_RESULT.IDOK => MessageBoxResult.OK,
(int)User32.MB_RESULT.IDYES => MessageBoxResult.Yes,
(int)User32.MB_RESULT.IDNO => MessageBoxResult.No,
(int)User32.MB_RESULT.IDCANCEL => MessageBoxResult.Cancel,
0 => MessageBoxResult.None,
_ => (MessageBoxResult)button,
};
return (MessageBoxResult)button;
}
}
}

View File

@@ -90,7 +90,6 @@
<!-- Nuget Packages -->
<ItemGroup>
<PackageReference Include="CalcBinding" Version="2.5.2" />
<PackageReference Include="DirectNCore" Version="1.16.1" />
<PackageReference Include="FluentEmail.Liquid" Version="3.0.2" />
<PackageReference Include="FluentEmail.MailKit" Version="3.0.2" />
<PackageReference Include="Fody" Version="6.8.0">
@@ -106,6 +105,10 @@
<PackageReference Include="MdXaml.Html" Version="1.22.0" />
<PackageReference Include="MdXaml.Plugins" Version="1.22.0" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Notification.Wpf" Version="7.0.0.2" />
<PackageReference Include="ObservableCollections" Version="1.1.3" />
@@ -121,10 +124,6 @@
</PackageReference>
<PackageReference Include="Stylet" Version="1.3.6" />
<PackageReference Include="System.Management" Version="8.0.0" />
<PackageReference Include="Vanara.PInvoke.ComCtl32" Version="3.4.17" />
<PackageReference Include="Vanara.PInvoke.Shared" Version="3.4.17" />
<PackageReference Include="Vanara.PInvoke.Shell32" Version="3.4.16" />
<PackageReference Include="Vanara.PInvoke.CfgMgr32" Version="3.4.16" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>

View File

@@ -0,0 +1,26 @@
// GpuOption
CreateDXGIFactory2
IDXGIFactory4
DXGI_ERROR_NOT_FOUND
IDXGIAdapter1
D3D12CreateDevice
ID3D12Device
S_FALSE
DisplayConfigGetDeviceInfo
DISPLAYCONFIG_ADAPTER_NAME
CM_Get_Device_Interface_Property
CM_Get_DevNode_Property
CM_Locate_DevNode
CONFIGRET
CM_LOCATE_DEVNODE_FLAGS
DEVPKEY_Device_InstanceId
DEVPKEY_Device_DriverDate
DEVPKEY_Device_DriverVersion
// MessageBoxHelper
TaskDialogIndirect
TD_INFORMATION_ICON
TD_ERROR_ICON
TD_WARNING_ICON
TD_INFORMATION_ICON
SHGetStockIconInfo