diff --git a/NativeFileDialogSharp.sln b/NativeFileDialogSharp.sln
index 89a69db..c95c259 100644
--- a/NativeFileDialogSharp.sln
+++ b/NativeFileDialogSharp.sln
@@ -1,22 +1,51 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeFileDialogSharp", "NativeFileDialogSharp\NativeFileDialogSharp.csproj", "{4127F279-9FD5-4C37-B904-242C124C1A07}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeFileDialogSharpSandbox", "NativeFileDialogSharpSandbox\NativeFileDialogSharpSandbox.csproj", "{427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {4127F279-9FD5-4C37-B904-242C124C1A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4127F279-9FD5-4C37-B904-242C124C1A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4127F279-9FD5-4C37-B904-242C124C1A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4127F279-9FD5-4C37-B904-242C124C1A07}.Release|Any CPU.Build.0 = Release|Any CPU
- {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31919.166
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeFileDialogSharp", "NativeFileDialogSharp\NativeFileDialogSharp.csproj", "{4127F279-9FD5-4C37-B904-242C124C1A07}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeFileDialogSharpSandbox", "NativeFileDialogSharpSandbox\NativeFileDialogSharpSandbox.csproj", "{427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeFileDialogSharpSandboxNetFramework", "NativeFileDialogSharpSandboxNetFramework\NativeFileDialogSharpSandboxNetFramework.csproj", "{0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4127F279-9FD5-4C37-B904-242C124C1A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4127F279-9FD5-4C37-B904-242C124C1A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4127F279-9FD5-4C37-B904-242C124C1A07}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4127F279-9FD5-4C37-B904-242C124C1A07}.Debug|x64.Build.0 = Debug|Any CPU
+ {4127F279-9FD5-4C37-B904-242C124C1A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4127F279-9FD5-4C37-B904-242C124C1A07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4127F279-9FD5-4C37-B904-242C124C1A07}.Release|x64.ActiveCfg = Release|Any CPU
+ {4127F279-9FD5-4C37-B904-242C124C1A07}.Release|x64.Build.0 = Release|Any CPU
+ {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Debug|x64.Build.0 = Debug|Any CPU
+ {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Release|x64.ActiveCfg = Release|Any CPU
+ {427E5F76-8418-4EA3-9AA3-C1DBFDE0478F}.Release|x64.Build.0 = Release|Any CPU
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}.Debug|x64.ActiveCfg = Debug|x64
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}.Debug|x64.Build.0 = Debug|x64
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}.Release|x64.ActiveCfg = Release|x64
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {124CB415-A372-4268-9C13-330A0F1093C2}
+ EndGlobalSection
+EndGlobal
diff --git a/NativeFileDialogSharp/Native/NativeFunctions.cs b/NativeFileDialogSharp/Native/NativeFunctions.cs
index e332cdc..9b702ea 100644
--- a/NativeFileDialogSharp/Native/NativeFunctions.cs
+++ b/NativeFileDialogSharp/Native/NativeFunctions.cs
@@ -1,56 +1,97 @@
using System;
using System.Runtime.InteropServices;
-namespace NativeFileDialogSharp.Native;
-
-public struct nfdpathset_t
+namespace NativeFileDialogSharp.Native
{
- public IntPtr buf;
- public IntPtr indices;
- public UIntPtr count;
-}
+ public struct nfdpathset_t
+ {
+ public IntPtr buf;
+ public IntPtr indices;
+ public UIntPtr count;
+ }
-public enum nfdresult_t
-{
- NFD_ERROR,
- NFD_OKAY,
- NFD_CANCEL
-}
+ public enum nfdresult_t
+ {
+ NFD_ERROR,
+ NFD_OKAY,
+ NFD_CANCEL
+ }
-public static class NativeFunctions
-{
- public const string LibraryName = "nfd";
+ public static class NativeFunctions
+ {
+ public const string LibraryName = "nfd";
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe nfdresult_t NFD_OpenDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe nfdresult_t NFD_OpenDialogMultiple(byte* filterList, byte* defaultPath,
+ nfdpathset_t* outPaths);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe nfdresult_t NFD_SaveDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe nfdresult_t NFD_PickFolder(byte* defaultPath, out IntPtr outPath);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe byte* NFD_GetError();
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe UIntPtr NFD_PathSet_GetCount(nfdpathset_t* pathSet);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe byte* NFD_PathSet_GetPath(nfdpathset_t* pathSet, UIntPtr index);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe void NFD_PathSet_Free(nfdpathset_t* pathSet);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe void NFD_Dummy();
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe IntPtr NFD_Malloc(UIntPtr bytes);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe void NFD_Free(IntPtr ptr);
+ }
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe nfdresult_t NFD_OpenDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe nfdresult_t NFD_OpenDialogMultiple(byte* filterList, byte* defaultPath, nfdpathset_t* outPaths);
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe nfdresult_t NFD_SaveDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe nfdresult_t NFD_PickFolder(byte* defaultPath, out IntPtr outPath);
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe byte* NFD_GetError();
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe UIntPtr NFD_PathSet_GetCount(nfdpathset_t* pathSet);
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe byte* NFD_PathSet_GetPath(nfdpathset_t* pathSet, UIntPtr index);
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe void NFD_PathSet_Free(nfdpathset_t* pathSet);
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe void NFD_Dummy();
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe IntPtr NFD_Malloc(UIntPtr bytes);
-
- [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
- public static extern unsafe void NFD_Free(IntPtr ptr);
+ public static class NativeFunctions32
+ {
+ public const string LibraryName = "nfd_x86";
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe nfdresult_t NFD_OpenDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe nfdresult_t NFD_OpenDialogMultiple(byte* filterList, byte* defaultPath,
+ nfdpathset_t* outPaths);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe nfdresult_t NFD_SaveDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe nfdresult_t NFD_PickFolder(byte* defaultPath, out IntPtr outPath);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe byte* NFD_GetError();
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe UIntPtr NFD_PathSet_GetCount(nfdpathset_t* pathSet);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe byte* NFD_PathSet_GetPath(nfdpathset_t* pathSet, UIntPtr index);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe void NFD_PathSet_Free(nfdpathset_t* pathSet);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe void NFD_Dummy();
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe IntPtr NFD_Malloc(UIntPtr bytes);
+
+ [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+ public static extern unsafe void NFD_Free(IntPtr ptr);
+ }
}
\ No newline at end of file
diff --git a/NativeFileDialogSharp/NativeFileDialogSharp.csproj b/NativeFileDialogSharp/NativeFileDialogSharp.csproj
index 1628e6a..87a0602 100644
--- a/NativeFileDialogSharp/NativeFileDialogSharp.csproj
+++ b/NativeFileDialogSharp/NativeFileDialogSharp.csproj
@@ -1,9 +1,8 @@
- 10
- 0.2.5
- net6.0
+ 7.3
+ 0.5.0
disable
true
Zlib
@@ -11,6 +10,7 @@
https://github.com/milleniumbug/NativeFileDialogSharp
https://github.com/milleniumbug/NativeFileDialogSharp
Cross-platform native file dialog controls for Windows, Linux and macOS
+ netstandard2.0
diff --git a/NativeFileDialogSharp/NativeWrappers.cs b/NativeFileDialogSharp/NativeWrappers.cs
index a6ee17e..42e02f0 100644
--- a/NativeFileDialogSharp/NativeWrappers.cs
+++ b/NativeFileDialogSharp/NativeWrappers.cs
@@ -1,156 +1,168 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Text;
using NativeFileDialogSharp.Native;
-namespace NativeFileDialogSharp;
-
-public static class Dialog
+namespace NativeFileDialogSharp
{
- private static byte[] ToUtf8(string s)
+ public static class Dialog
{
- var byteCount = Encoding.UTF8.GetByteCount(s);
- var bytes = new byte[byteCount + 1];
- Encoding.UTF8.GetBytes(s.AsSpan(), bytes.AsSpan());
- return bytes;
- }
+ private static readonly Encoder utf8encoder = Encoding.UTF8.GetEncoder();
- private static unsafe Span MakeSpanFromNullTerminatedString(byte* nullTerminatedString)
- {
- int count = 0;
- var ptr = nullTerminatedString;
- while (*ptr != 0)
+ private static unsafe byte[] ToUtf8(string s)
{
- ptr++;
- count++;
+ var byteCount = Encoding.UTF8.GetByteCount(s);
+ var bytes = new byte[byteCount + 1];
+ fixed (byte* o = bytes)
+ fixed (char* input = s)
+ {
+ utf8encoder.Convert(input, s.Length, o, bytes.Length, true, out _, out var _,
+ out var completed);
+ Debug.Assert(completed);
+ }
+
+ return bytes;
}
- return new Span(nullTerminatedString, count);
- }
-
- private static string FromUtf8(ReadOnlySpan input)
- {
- return Encoding.UTF8.GetString(input);
- }
-
- public static unsafe DialogResult FileOpen(string filterList = null, string defaultPath = null)
- {
- fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
- fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
+ private static unsafe int GetNullTerminatedStringLength(byte* nullTerminatedString)
{
- string path = null;
- string errorMessage = null;
- var result = NativeFunctions.NFD_OpenDialog(filterListNts, defaultPathNts, out IntPtr outPathIntPtr);
- if (result == nfdresult_t.NFD_ERROR)
+ int count = 0;
+ var ptr = nullTerminatedString;
+ while (*ptr != 0)
{
- errorMessage = FromUtf8(MakeSpanFromNullTerminatedString(NativeFunctions.NFD_GetError()));
- }
- else if (result == nfdresult_t.NFD_OKAY)
- {
- var outPathNts = (byte*)outPathIntPtr.ToPointer();
- path = FromUtf8(MakeSpanFromNullTerminatedString(outPathNts));
- NativeFunctions.NFD_Free(outPathIntPtr);
+ ptr++;
+ count++;
}
- return new DialogResult(result, path, null, errorMessage);
+ return count;
}
- }
-
- public static unsafe DialogResult FileSave(string filterList = null, string defaultPath = null)
- {
- fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
- fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
- {
- string path = null;
- string errorMessage = null;
- var result = NativeFunctions.NFD_SaveDialog(filterListNts, defaultPathNts, out IntPtr outPathIntPtr);
- if (result == nfdresult_t.NFD_ERROR)
- {
- errorMessage = FromUtf8(MakeSpanFromNullTerminatedString(NativeFunctions.NFD_GetError()));
- }
- else if (result == nfdresult_t.NFD_OKAY)
- {
- var outPathNts = (byte*)outPathIntPtr.ToPointer();
- path = FromUtf8(MakeSpanFromNullTerminatedString(outPathNts));
- NativeFunctions.NFD_Free(outPathIntPtr);
- }
- return new DialogResult(result, path, null, errorMessage);
- }
- }
-
- public static unsafe DialogResult FolderPicker(string defaultPath = null)
- {
- fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
+ private static unsafe string FromUtf8(byte* nullTerminatedString)
{
- string path = null;
- string errorMessage = null;
- var result = NativeFunctions.NFD_PickFolder(defaultPathNts, out IntPtr outPathIntPtr);
- if (result == nfdresult_t.NFD_ERROR)
- {
- errorMessage = FromUtf8(MakeSpanFromNullTerminatedString(NativeFunctions.NFD_GetError()));
- }
- else if (result == nfdresult_t.NFD_OKAY)
- {
- var outPathNts = (byte*)outPathIntPtr.ToPointer();
- path = FromUtf8(MakeSpanFromNullTerminatedString(outPathNts));
- NativeFunctions.NFD_Free(outPathIntPtr);
- }
+ return Encoding.UTF8.GetString(nullTerminatedString, GetNullTerminatedStringLength(nullTerminatedString));
+ }
- return new DialogResult(result, path, null, errorMessage);
- }
- }
-
- public static unsafe DialogResult FileOpenMultiple(string filterList = null, string defaultPath = null)
- {
- fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
- fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
+ public static unsafe DialogResult FileOpen(string filterList = null, string defaultPath = null)
{
- List paths = null;
- string errorMessage = null;
- nfdpathset_t pathSet;
- var result = NativeFunctions.NFD_OpenDialogMultiple(filterListNts, defaultPathNts, &pathSet);
- if (result == nfdresult_t.NFD_ERROR)
+ fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
+ fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
{
- errorMessage = FromUtf8(MakeSpanFromNullTerminatedString(NativeFunctions.NFD_GetError()));
- }
- else if (result == nfdresult_t.NFD_OKAY)
- {
- var pathCount = (int)NativeFunctions.NFD_PathSet_GetCount(&pathSet).ToUInt32();
- paths = new List(pathCount);
- for (int i = 0; i < pathCount; i++)
+ string path = null;
+ string errorMessage = null;
+ var result = NativeFunctions.NFD_OpenDialog(filterListNts, defaultPathNts, out IntPtr outPathIntPtr);
+ if (result == nfdresult_t.NFD_ERROR)
{
- paths.Add(FromUtf8(MakeSpanFromNullTerminatedString(NativeFunctions.NFD_PathSet_GetPath(&pathSet, new UIntPtr((uint)i)))));
+ errorMessage = FromUtf8(NativeFunctions.NFD_GetError());
+ }
+ else if (result == nfdresult_t.NFD_OKAY)
+ {
+ var outPathNts = (byte*)outPathIntPtr.ToPointer();
+ path = FromUtf8(outPathNts);
+ NativeFunctions.NFD_Free(outPathIntPtr);
}
- NativeFunctions.NFD_PathSet_Free(&pathSet);
- }
- return new DialogResult(result, null, paths, errorMessage);
+ return new DialogResult(result, path, null, errorMessage);
+ }
+ }
+
+ public static unsafe DialogResult FileSave(string filterList = null, string defaultPath = null)
+ {
+ fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
+ fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
+ {
+ string path = null;
+ string errorMessage = null;
+ var result = NativeFunctions.NFD_SaveDialog(filterListNts, defaultPathNts, out IntPtr outPathIntPtr);
+ if (result == nfdresult_t.NFD_ERROR)
+ {
+ errorMessage = FromUtf8(NativeFunctions.NFD_GetError());
+ }
+ else if (result == nfdresult_t.NFD_OKAY)
+ {
+ var outPathNts = (byte*)outPathIntPtr.ToPointer();
+ path = FromUtf8(outPathNts);
+ NativeFunctions.NFD_Free(outPathIntPtr);
+ }
+
+ return new DialogResult(result, path, null, errorMessage);
+ }
+ }
+
+ public static unsafe DialogResult FolderPicker(string defaultPath = null)
+ {
+ fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
+ {
+ string path = null;
+ string errorMessage = null;
+ var result = NativeFunctions.NFD_PickFolder(defaultPathNts, out IntPtr outPathIntPtr);
+ if (result == nfdresult_t.NFD_ERROR)
+ {
+ errorMessage = FromUtf8(NativeFunctions.NFD_GetError());
+ }
+ else if (result == nfdresult_t.NFD_OKAY)
+ {
+ var outPathNts = (byte*)outPathIntPtr.ToPointer();
+ path = FromUtf8(outPathNts);
+ NativeFunctions.NFD_Free(outPathIntPtr);
+ }
+
+ return new DialogResult(result, path, null, errorMessage);
+ }
+ }
+
+ public static unsafe DialogResult FileOpenMultiple(string filterList = null, string defaultPath = null)
+ {
+ fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
+ fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
+ {
+ List paths = null;
+ string errorMessage = null;
+ nfdpathset_t pathSet;
+ var result = NativeFunctions.NFD_OpenDialogMultiple(filterListNts, defaultPathNts, &pathSet);
+ if (result == nfdresult_t.NFD_ERROR)
+ {
+ errorMessage = FromUtf8(NativeFunctions.NFD_GetError());
+ }
+ else if (result == nfdresult_t.NFD_OKAY)
+ {
+ var pathCount = (int)NativeFunctions.NFD_PathSet_GetCount(&pathSet).ToUInt32();
+ paths = new List(pathCount);
+ for (int i = 0; i < pathCount; i++)
+ {
+ paths.Add(FromUtf8(NativeFunctions.NFD_PathSet_GetPath(&pathSet, new UIntPtr((uint)i))));
+ }
+
+ NativeFunctions.NFD_PathSet_Free(&pathSet);
+ }
+
+ return new DialogResult(result, null, paths, errorMessage);
+ }
}
}
-}
-public class DialogResult
-{
- private readonly nfdresult_t result;
-
- public string Path { get; }
-
- public IReadOnlyList Paths { get; }
-
- public bool IsError => result == nfdresult_t.NFD_ERROR;
-
- public string ErrorMessage { get; }
-
- public bool IsCancelled => result == nfdresult_t.NFD_CANCEL;
-
- public bool IsOk => result == nfdresult_t.NFD_OKAY;
-
- internal DialogResult(nfdresult_t result, string path, IReadOnlyList paths, string errorMessage)
+ public class DialogResult
{
- this.result = result;
- Path = path;
- Paths = paths;
- ErrorMessage = errorMessage;
+ private readonly nfdresult_t result;
+
+ public string Path { get; }
+
+ public IReadOnlyList Paths { get; }
+
+ public bool IsError => result == nfdresult_t.NFD_ERROR;
+
+ public string ErrorMessage { get; }
+
+ public bool IsCancelled => result == nfdresult_t.NFD_CANCEL;
+
+ public bool IsOk => result == nfdresult_t.NFD_OKAY;
+
+ internal DialogResult(nfdresult_t result, string path, IReadOnlyList paths, string errorMessage)
+ {
+ this.result = result;
+ Path = path;
+ Paths = paths;
+ ErrorMessage = errorMessage;
+ }
}
}
\ No newline at end of file
diff --git a/NativeFileDialogSharpSandbox/NativeFileDialogSharpSandbox.csproj b/NativeFileDialogSharpSandbox/NativeFileDialogSharpSandbox.csproj
index e9f7684..5f3b95e 100644
--- a/NativeFileDialogSharpSandbox/NativeFileDialogSharpSandbox.csproj
+++ b/NativeFileDialogSharpSandbox/NativeFileDialogSharpSandbox.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/NativeFileDialogSharpSandbox/Program.cs b/NativeFileDialogSharpSandbox/Program.cs
index abd3bed..f0a57a1 100644
--- a/NativeFileDialogSharpSandbox/Program.cs
+++ b/NativeFileDialogSharpSandbox/Program.cs
@@ -1,14 +1,26 @@
-// See https://aka.ms/new-console-template for more information
-
-using System;
-using NativeFileDialogSharp;
-using NativeFileDialogSharp.Native;
-
-var result = Dialog.FileOpenMultiple();
-
-Console.WriteLine($"Path: {result.Path}, IsError {result.IsError}, IsOk {result.IsOk}, IsCancelled {result.IsCancelled}, ErrorMessage {result.ErrorMessage}");
-if (result.Paths != null)
-{
- Console.WriteLine("Paths");
- Console.WriteLine(string.Join("\n", result.Paths));
-}
\ No newline at end of file
+using NativeFileDialogSharp;
+using System;
+
+namespace NativeFileDialogSharpSandbox
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ PrintResult(Dialog.FileOpenMultiple("pdf", null));
+ PrintResult(Dialog.FileOpen(null));
+ PrintResult(Dialog.FileSave(null));
+ PrintResult(Dialog.FolderPicker(null));
+ }
+
+ static void PrintResult(DialogResult result)
+ {
+ Console.WriteLine($"Path: {result.Path}, IsError {result.IsError}, IsOk {result.IsOk}, IsCancelled {result.IsCancelled}, ErrorMessage {result.ErrorMessage}");
+ if (result.Paths != null)
+ {
+ Console.WriteLine("Paths");
+ Console.WriteLine(string.Join("\n", result.Paths));
+ }
+ }
+ }
+}
diff --git a/NativeFileDialogSharpSandboxNetFramework/App.config b/NativeFileDialogSharpSandboxNetFramework/App.config
new file mode 100644
index 0000000..e89424b
--- /dev/null
+++ b/NativeFileDialogSharpSandboxNetFramework/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/NativeFileDialogSharpSandboxNetFramework/NativeFileDialogSharpSandboxNetFramework.csproj b/NativeFileDialogSharpSandboxNetFramework/NativeFileDialogSharpSandboxNetFramework.csproj
new file mode 100644
index 0000000..9629bee
--- /dev/null
+++ b/NativeFileDialogSharpSandboxNetFramework/NativeFileDialogSharpSandboxNetFramework.csproj
@@ -0,0 +1,78 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {0FD91168-D8F5-4776-8D91-CB9B9C55AA1B}
+ Exe
+ NativeFileDialogSharpSandboxNetFramework
+ NativeFileDialogSharpSandboxNetFramework
+ v4.6.2
+ 512
+ true
+ true
+
+
+
+ x86
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ 7.3
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ 7.3
+ prompt
+ true
+
+
+
+ ..\packages\NativeFileDialogSharp.0.4.4\lib\net461\NativeFileDialogSharp.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NativeFileDialogSharpSandboxNetFramework/Program.cs b/NativeFileDialogSharpSandboxNetFramework/Program.cs
new file mode 100644
index 0000000..485a57f
--- /dev/null
+++ b/NativeFileDialogSharpSandboxNetFramework/Program.cs
@@ -0,0 +1,26 @@
+using NativeFileDialogSharp;
+using System;
+
+namespace NativeFileDialogSharpSandboxNetFramework
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ PrintResult(Dialog.FileOpenMultiple("pdf", null));
+ PrintResult(Dialog.FileOpen(null));
+ PrintResult(Dialog.FileSave(null));
+ PrintResult(Dialog.FolderPicker(null));
+ }
+
+ static void PrintResult(DialogResult result)
+ {
+ Console.WriteLine($"Path: {result.Path}, IsError {result.IsError}, IsOk {result.IsOk}, IsCancelled {result.IsCancelled}, ErrorMessage {result.ErrorMessage}");
+ if (result.Paths != null)
+ {
+ Console.WriteLine("Paths");
+ Console.WriteLine(string.Join("\n", result.Paths));
+ }
+ }
+ }
+}
diff --git a/NativeFileDialogSharpSandboxNetFramework/Properties/AssemblyInfo.cs b/NativeFileDialogSharpSandboxNetFramework/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ffd8a87
--- /dev/null
+++ b/NativeFileDialogSharpSandboxNetFramework/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("NativeFileDialogSharpSandboxNetFramework")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("NativeFileDialogSharpSandboxNetFramework")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("0fd91168-d8f5-4776-8d91-cb9b9c55aa1b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/NativeFileDialogSharpSandboxNetFramework/packages.config b/NativeFileDialogSharpSandboxNetFramework/packages.config
new file mode 100644
index 0000000..7826378
--- /dev/null
+++ b/NativeFileDialogSharpSandboxNetFramework/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file