Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of LibraryImport (.NET 7) #114

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"sdk": {
"allowPrerelease": false,
"version": "6.0.100",
"allowPrerelease": true,
"version": "7.0.*",
"rollForward": "latestFeature"
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

<PropertyGroup>
<TargetFrameworks>net6.0-windows;net5.0-windows;netcoreapp3.1;net462</TargetFrameworks>
<TargetFrameworks>net7.0-windows;net6.0-windows;net462</TargetFrameworks>
<OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
Expand All @@ -23,6 +23,8 @@

<PropertyGroup>
<DisableImplicitFrameworkReferences Condition=" '$(TargetFramework)' == 'net462' ">true</DisableImplicitFrameworkReferences>
<AssemblyVersion>1.0.0.22259</AssemblyVersion>
<FileVersion>1.0.0.22259</FileVersion>
</PropertyGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net462' ">
Expand Down
126 changes: 96 additions & 30 deletions src/Ookii.Dialogs.Wpf/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

namespace Ookii.Dialogs.Wpf
{
static class NativeMethods
static partial class NativeMethods
{
public const int ErrorFileNotFound = 2;

Expand All @@ -45,7 +45,19 @@ public static bool IsWindowsXPOrLater
}

#region LoadLibrary
#if NET7_0_OR_GREATER
[LibraryImport("kernel32", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
public static partial SafeModuleHandle LoadLibraryEx(
string lpFileName,
IntPtr hFile,
LoadLibraryExFlags dwFlags
);

[LibraryImport("kernel32", SetLastError = true),
ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool FreeLibrary(IntPtr hModule);
#else
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern Ookii.Dialogs.Wpf.SafeModuleHandle LoadLibraryEx(
string lpFileName,
Expand All @@ -57,7 +69,7 @@ LoadLibraryExFlags dwFlags
ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FreeLibrary(IntPtr hModule);

#endif
[Flags]
public enum LoadLibraryExFlags : uint
{
Expand All @@ -71,6 +83,23 @@ public enum LoadLibraryExFlags : uint

#region Task Dialogs

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist"), DllImport("comctl32.dll", PreserveSig = false)]
public static extern void TaskDialogIndirect([In] ref TASKDIALOGCONFIG pTaskConfig, out int pnButton, out int pnRadioButton, [MarshalAs(UnmanagedType.Bool)] out bool pfVerificationFlagChecked);

#if NET7_0_OR_GREATER
[LibraryImport("user32.dll")]
public static partial IntPtr GetActiveWindow();

[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool EnableWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool bEnable);

[LibraryImport("user32.dll")]
public static partial int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

[LibraryImport("kernel32.dll")]
public static partial int GetCurrentThreadId();
#else
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetActiveWindow();

Expand All @@ -82,9 +111,7 @@ public enum LoadLibraryExFlags : uint

[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int GetCurrentThreadId();

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist"), DllImport("comctl32.dll", PreserveSig = false)]
public static extern void TaskDialogIndirect([In] ref TASKDIALOGCONFIG pTaskConfig, out int pnButton, out int pnRadioButton, [MarshalAs(UnmanagedType.Bool)] out bool pfVerificationFlagChecked);
#endif


public delegate uint TaskDialogCallback(IntPtr hwnd, uint uNotification, IntPtr wParam, IntPtr lParam, IntPtr dwRefData);
Expand Down Expand Up @@ -218,15 +245,29 @@ public struct TASKDIALOGCONFIG
public uint cxWidth;
}

//This DllImport doesn't work with LibraryImport. Unless it's re-worked a bit, skip suggestions for it.
[DllImport("user32.dll", CharSet = CharSet.Auto)]
#pragma warning disable SYSLIB1054 // Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time
public static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
#pragma warning restore SYSLIB1054 // Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time

#endregion

#region Activation Context

[DllImport("Kernel32.dll", SetLastError = true)]
public extern static ActivationContextSafeHandle CreateActCtx(ref ACTCTX actctx);
#if NET7_0_OR_GREATER
[LibraryImport("kernel32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static partial void ReleaseActCtx(IntPtr hActCtx);
[LibraryImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool ActivateActCtx(ActivationContextSafeHandle hActCtx, out IntPtr lpCookie);
[LibraryImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool DeactivateActCtx(uint dwFlags, IntPtr lpCookie);
#else

[DllImport("kernel32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public extern static void ReleaseActCtx(IntPtr hActCtx);
[DllImport("Kernel32.dll", SetLastError = true)]
Expand All @@ -235,6 +276,7 @@ public struct TASKDIALOGCONFIG
[DllImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public extern static bool DeactivateActCtx(uint dwFlags, IntPtr lpCookie);
#endif

public const int ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004;

Expand All @@ -251,9 +293,9 @@ public struct ACTCTX
}


#endregion
#endregion

#region File Operations Definitions
#region File Operations Definitions

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
internal struct COMDLG_FILTERSPEC
Expand Down Expand Up @@ -336,9 +378,9 @@ internal enum CDCONTROLSTATE
CDCS_VISIBLE = 0x00000002
}

#endregion
#endregion

#region KnownFolder Definitions
#region KnownFolder Definitions

internal enum FFFP_MODE
{
Expand Down Expand Up @@ -399,9 +441,9 @@ internal struct PROPERTYKEY
internal uint pid;
}

#endregion
#endregion

#region Shell Parsing Names
#region Shell Parsing Names

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
public static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppv);
Expand All @@ -416,9 +458,9 @@ public static Interop.IShellItem CreateItemFromParsingName(string path)
return (Interop.IShellItem)item;
}

#endregion
#endregion

#region String Resources
#region String Resources

[Flags()]
public enum FormatMessageFlags
Expand All @@ -439,9 +481,9 @@ public static extern uint FormatMessage([MarshalAs(UnmanagedType.U4)] FormatMess
uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer,
uint nSize, string[] Arguments);

#endregion
#endregion

#region Credentials
#region Credentials

internal const int CREDUI_MAX_USERNAME_LENGTH = 256 + 1 + 256;
internal const int CREDUI_MAX_PASSWORD_LENGTH = 256;
Expand Down Expand Up @@ -545,17 +587,6 @@ public static extern CredUIReturnCodes CredUIPromptForWindowsCredentials(
[MarshalAs(UnmanagedType.Bool)]ref bool pfSave,
CredUIWinFlags dwFlags);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "CredReadW", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
extern static internal bool CredRead(string TargetName, CredTypes Type, int Flags, out IntPtr Credential);

[DllImport("advapi32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
extern static internal void CredFree(IntPtr Buffer);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "CredDeleteW", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
extern static internal bool CredDelete(string TargetName, CredTypes Type, int Flags);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "CredWriteW", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
extern static internal bool CredWrite(ref CREDENTIAL Credential, int Flags);
Expand All @@ -568,6 +599,31 @@ public static extern CredUIReturnCodes CredUIPromptForWindowsCredentials(
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CredUnPackAuthenticationBuffer(uint dwFlags, IntPtr pAuthBuffer, uint cbAuthBuffer, StringBuilder pszUserName, ref uint pcchMaxUserName, StringBuilder pszDomainName, ref uint pcchMaxDomainName, StringBuilder pszPassword, ref uint pcchMaxPassword);

#if NET7_0_OR_GREATER
[LibraryImport("advapi32.dll", EntryPoint = "CredReadW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool CredRead(string TargetName, CredTypes Type, int Flags, out IntPtr Credential);

[LibraryImport("advapi32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal static partial void CredFree(IntPtr Buffer);

[LibraryImport("advapi32.dll", EntryPoint = "CredDeleteW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool CredDelete(string TargetName, CredTypes Type, int Flags);

#else
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "CredReadW", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
extern static internal bool CredRead(string TargetName, CredTypes Type, int Flags, out IntPtr Credential);

[DllImport("advapi32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
extern static internal void CredFree(IntPtr Buffer);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "CredDeleteW", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
extern static internal bool CredDelete(string TargetName, CredTypes Type, int Flags);
#endif

// Disable the "Internal field is never assigned to" warning.
#pragma warning disable 649
// This type does not own the IntPtr native resource; when CredRead is used, CredFree must be called on the
Expand Down Expand Up @@ -598,9 +654,9 @@ public struct CREDENTIAL
}
#pragma warning restore 649

#endregion
#endregion

#region Downlevel folder browser dialog
#region Downlevel folder browser dialog

public enum FolderBrowserDialogMessage
{
Expand Down Expand Up @@ -650,17 +706,27 @@ public struct BROWSEINFO

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SHBrowseForFolder(ref BROWSEINFO lpbi);
[DllImport("shell32.dll", SetLastError = true)]
public static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, Environment.SpecialFolder nFolder, ref IntPtr ppidl);
[DllImport("shell32.dll", PreserveSig = false)]
public static extern IMalloc SHGetMalloc();
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SHGetPathFromIDList(IntPtr pidl, StringBuilder pszPath);
#if NET7_0_OR_GREATER
[LibraryImport("shell32.dll", SetLastError = true)]
public static partial int SHGetSpecialFolderLocation(IntPtr hwndOwner, Environment.SpecialFolder nFolder, ref IntPtr ppidl);

[LibraryImport("user32.dll", StringMarshalling = StringMarshalling.Utf16)]
public static partial IntPtr SendMessage(IntPtr hWnd, FolderBrowserDialogMessage msg, IntPtr wParam, string lParam);
[LibraryImport("user32.dll")]
public static partial IntPtr SendMessage(IntPtr hWnd, FolderBrowserDialogMessage msg, IntPtr wParam, IntPtr lParam);
#else
[DllImport("shell32.dll", SetLastError = true)]
public static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, Environment.SpecialFolder nFolder, ref IntPtr ppidl);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(IntPtr hWnd, FolderBrowserDialogMessage msg, IntPtr wParam, string lParam);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, FolderBrowserDialogMessage msg, IntPtr wParam, IntPtr lParam);
#endif


#endregion
Expand Down
8 changes: 5 additions & 3 deletions src/Ookii.Dialogs.Wpf/Ookii.Dialogs.Wpf.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0-windows;net5.0-windows;netcoreapp3.1;net462</TargetFrameworks>
<TargetFrameworks>net7.0-windows;net6.0-windows;net462</TargetFrameworks>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<RootNamespace>Ookii.Dialogs.Wpf</RootNamespace>

<AssemblyName>Ookii.Dialogs.Wpf</AssemblyName>
<AssemblyVersion>3.0.0.0</AssemblyVersion>
<AssemblyVersion>3.0.0.22259</AssemblyVersion>
<GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>true</GenerateAssemblyFileVersionAttribute>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down Expand Up @@ -63,6 +63,8 @@

<PropertyGroup>
<DisableImplicitFrameworkReferences Condition=" '$(TargetFramework)' == 'net462' ">true</DisableImplicitFrameworkReferences>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<FileVersion>0.0.1.22259</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/Ookii.Dialogs/Ookii.Dialogs.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0-windows;net5.0-windows;netcoreapp3.1;net462</TargetFrameworks>
<TargetFrameworks>net7.0-windows;net6.0-windows;net462</TargetFrameworks>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>

Expand Down