mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Use PInvoke to improve code quality
This commit is contained in:
parent
41c5b36fba
commit
086aeab6c0
3 changed files with 50 additions and 61 deletions
|
|
@ -57,3 +57,7 @@ LOCALE_TRANSIENT_KEYBOARD1
|
|||
LOCALE_TRANSIENT_KEYBOARD2
|
||||
LOCALE_TRANSIENT_KEYBOARD3
|
||||
LOCALE_TRANSIENT_KEYBOARD4
|
||||
|
||||
SHParseDisplayName
|
||||
SHOpenFolderAndSelectItems
|
||||
CoTaskMemFree
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
|
@ -17,6 +18,7 @@ using Windows.Win32;
|
|||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.Graphics.Dwm;
|
||||
using Windows.Win32.UI.Input.KeyboardAndMouse;
|
||||
using Windows.Win32.UI.Shell.Common;
|
||||
using Windows.Win32.UI.WindowsAndMessaging;
|
||||
using Point = System.Windows.Point;
|
||||
using SystemFonts = System.Windows.SystemFonts;
|
||||
|
|
@ -753,5 +755,34 @@ namespace Flow.Launcher.Infrastructure
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Explorer
|
||||
|
||||
public static unsafe void OpenFolderAndSelectFile(string filePath)
|
||||
{
|
||||
ITEMIDLIST* pidlFolder = null;
|
||||
ITEMIDLIST* pidlFile = null;
|
||||
|
||||
var folderPath = Path.GetDirectoryName(filePath);
|
||||
|
||||
try
|
||||
{
|
||||
var hrFolder = PInvoke.SHParseDisplayName(folderPath, null, out pidlFolder, 0, null);
|
||||
if (hrFolder.Failed) throw new COMException("Failed to parse folder path", hrFolder);
|
||||
|
||||
var hrFile = PInvoke.SHParseDisplayName(filePath, null, out pidlFile, 0, null);
|
||||
if (hrFile.Failed) throw new COMException("Failed to parse file path", hrFile);
|
||||
|
||||
var hrSelect = PInvoke.SHOpenFolderAndSelectItems(pidlFolder, 1, &pidlFile, 0);
|
||||
if (hrSelect.Failed) throw new COMException("Failed to open folder and select item", hrSelect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pidlFile != null) PInvoke.CoTaskMemFree(pidlFile);
|
||||
if (pidlFolder != null) PInvoke.CoTaskMemFree(pidlFolder);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Flow.Launcher.Core;
|
||||
|
|
@ -320,88 +318,44 @@ namespace Flow.Launcher
|
|||
|
||||
((PluginJsonStorage<T>)_pluginJsonStorages[type]).Save();
|
||||
}
|
||||
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern int SHParseDisplayName(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string name,
|
||||
IntPtr bindingContext,
|
||||
out IntPtr pidl,
|
||||
uint sfgaoIn,
|
||||
out uint psfgaoOut
|
||||
);
|
||||
|
||||
[DllImport("shell32.dll")]
|
||||
private static extern int SHOpenFolderAndSelectItems(
|
||||
IntPtr pidlFolder,
|
||||
uint cidl,
|
||||
[MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
|
||||
uint dwFlags
|
||||
);
|
||||
|
||||
[DllImport("ole32.dll")]
|
||||
private static extern void CoTaskMemFree(IntPtr pv);
|
||||
|
||||
private void OpenFolderAndSelectItem(string filePath)
|
||||
{
|
||||
IntPtr pidlFolder = IntPtr.Zero;
|
||||
IntPtr pidlFile = IntPtr.Zero;
|
||||
uint attr;
|
||||
|
||||
string folderPath = Path.GetDirectoryName(filePath);
|
||||
|
||||
try
|
||||
{
|
||||
SHParseDisplayName(folderPath, IntPtr.Zero, out pidlFolder, 0, out attr);
|
||||
SHParseDisplayName(filePath, IntPtr.Zero, out pidlFile, 0, out attr);
|
||||
|
||||
if (pidlFolder != IntPtr.Zero && pidlFile != IntPtr.Zero)
|
||||
{
|
||||
SHOpenFolderAndSelectItems(pidlFolder, 1, new[] { pidlFile }, 0);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pidlFile != IntPtr.Zero)
|
||||
CoTaskMemFree(pidlFile);
|
||||
if (pidlFolder != IntPtr.Zero)
|
||||
CoTaskMemFree(pidlFolder);
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenDirectory(string directoryPath, string fileNameOrFilePath = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string targetPath = fileNameOrFilePath is null
|
||||
var explorerInfo = _settings.CustomExplorer;
|
||||
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
|
||||
var targetPath = fileNameOrFilePath is null
|
||||
? directoryPath
|
||||
: Path.IsPathRooted(fileNameOrFilePath)
|
||||
? fileNameOrFilePath
|
||||
: Path.Combine(directoryPath, fileNameOrFilePath);
|
||||
|
||||
var explorerInfo = _settings.CustomExplorer;
|
||||
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
|
||||
|
||||
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
|
||||
{
|
||||
// Windows File Manager
|
||||
if (fileNameOrFilePath is null)
|
||||
{
|
||||
// 폴더만 열기
|
||||
Process.Start(new ProcessStartInfo
|
||||
// Only Open the directory
|
||||
using var explorer = new Process();
|
||||
explorer.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = directoryPath,
|
||||
UseShellExecute = true
|
||||
})?.Dispose();
|
||||
};
|
||||
explorer.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
// SHOpenFolderAndSelectItems 방식
|
||||
OpenFolderAndSelectItem(targetPath);
|
||||
// Open the directory and select the file
|
||||
Win32Helper.OpenFolderAndSelectFile(targetPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 커스텀 파일 관리자
|
||||
var shellProcess = new ProcessStartInfo
|
||||
// Custom File Manager
|
||||
using var explorer = new Process();
|
||||
explorer.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = explorerInfo.Path.Replace("%d", directoryPath),
|
||||
UseShellExecute = true,
|
||||
|
|
@ -411,7 +365,7 @@ namespace Flow.Launcher
|
|||
.Replace("%d", directoryPath)
|
||||
.Replace("%f", targetPath)
|
||||
};
|
||||
Process.Start(shellProcess)?.Dispose();
|
||||
explorer.Start();
|
||||
}
|
||||
}
|
||||
catch (Win32Exception ex) when (ex.NativeErrorCode == 2)
|
||||
|
|
|
|||
Loading…
Reference in a new issue