Skip to content

Commit 58ad24b

Browse files
authored
Files.Launcher: Code cleanup (#1367)
Use Vanara instead of DLLImport
1 parent dfed34e commit 58ad24b

File tree

2 files changed

+75
-64
lines changed

2 files changed

+75
-64
lines changed

Files.Launcher/Program.cs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,21 @@
1515
using Windows.ApplicationModel.AppService;
1616
using Windows.Foundation.Collections;
1717
using Windows.Storage;
18-
using static Vanara.PInvoke.Shell32;
18+
using Vanara.PInvoke;
19+
using NLog;
1920

2021
namespace FilesFullTrust
2122
{
2223
internal class Program
2324
{
24-
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
25+
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
2526

2627
[STAThread]
2728
private static void Main(string[] args)
2829
{
2930
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
30-
NLog.LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NLog.config"));
31-
NLog.LogManager.Configuration.Variables["LogPath"] = storageFolder.Path;
31+
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NLog.config"));
32+
LogManager.Configuration.Variables["LogPath"] = storageFolder.Path;
3233

3334
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
3435

@@ -41,12 +42,15 @@ private static void Main(string[] args)
4142
// Only one instance of the fulltrust process allowed
4243
// This happens if multiple instances of the UWP app are launched
4344
using var mutex = new Mutex(true, "FilesUwpFullTrust", out bool isNew);
44-
if (!isNew) return;
45+
if (!isNew)
46+
{
47+
return;
48+
}
4549

4650
try
4751
{
4852
// Create shell COM object and get recycle bin folder
49-
recycler = new ShellFolder(KNOWNFOLDERID.FOLDERID_RecycleBinFolder);
53+
recycler = new ShellFolder(Shell32.KNOWNFOLDERID.FOLDERID_RecycleBinFolder);
5054
ApplicationData.Current.LocalSettings.Values["RecycleBin_Title"] = recycler.Name;
5155

5256
// Create filesystem watcher to monitor recycle bin folder(s)
@@ -98,7 +102,7 @@ private static void UnhandledExceptionTrapper(object sender, UnhandledExceptionE
98102

99103
private static async void Watcher_Changed(object sender, FileSystemEventArgs e)
100104
{
101-
Debug.WriteLine("Reycle bin event: {0}, {1}", e.ChangeType, e.FullPath);
105+
Debug.WriteLine($"Reycle bin event: {e.ChangeType}, {e.FullPath}");
102106
if (connection != null)
103107
{
104108
// Send message to UWP app to refresh items
@@ -262,15 +266,15 @@ private static async Task parseRecycleBinAction(AppServiceRequestReceivedEventAr
262266
{
263267
case "Empty":
264268
// Shell function to empty recyclebin
265-
SHEmptyRecycleBin(IntPtr.Zero, null, SHERB.SHERB_NOCONFIRMATION | SHERB.SHERB_NOPROGRESSUI);
269+
Shell32.SHEmptyRecycleBin(IntPtr.Zero, null, Shell32.SHERB.SHERB_NOCONFIRMATION | Shell32.SHERB.SHERB_NOPROGRESSUI);
266270
break;
267271

268272
case "Query":
269273
var responseQuery = new ValueSet();
270-
SHQUERYRBINFO queryBinInfo = new SHQUERYRBINFO();
274+
Shell32.SHQUERYRBINFO queryBinInfo = new Shell32.SHQUERYRBINFO();
271275
queryBinInfo.cbSize = (uint)Marshal.SizeOf(queryBinInfo);
272-
var res = SHQueryRecycleBin(null, ref queryBinInfo);
273-
if (res == Vanara.PInvoke.HRESULT.S_OK)
276+
var res = Shell32.SHQueryRecycleBin(null, ref queryBinInfo);
277+
if (res == HRESULT.S_OK)
274278
{
275279
var numItems = queryBinInfo.i64NumItems;
276280
var binSize = queryBinInfo.i64Size;
@@ -298,13 +302,13 @@ private static async Task parseRecycleBinAction(AppServiceRequestReceivedEventAr
298302
continue;
299303
}
300304
folderItem.Properties.TryGetValue<System.Runtime.InteropServices.ComTypes.FILETIME?>(
301-
Vanara.PInvoke.Ole32.PROPERTYKEY.System.DateCreated, out var fileTime);
305+
Ole32.PROPERTYKEY.System.DateCreated, out var fileTime);
302306
var recycleDate = fileTime?.ToDateTime().ToLocalTime() ?? DateTime.Now; // This is LocalTime
303307
string fileSize = folderItem.Properties.TryGetValue<ulong?>(
304-
Vanara.PInvoke.Ole32.PROPERTYKEY.System.Size, out var fileSizeBytes) ?
305-
folderItem.Properties.GetPropertyString(Vanara.PInvoke.Ole32.PROPERTYKEY.System.Size) : null;
308+
Ole32.PROPERTYKEY.System.Size, out var fileSizeBytes) ?
309+
folderItem.Properties.GetPropertyString(Ole32.PROPERTYKEY.System.Size) : null;
306310
folderItem.Properties.TryGetValue<string>(
307-
Vanara.PInvoke.Ole32.PROPERTYKEY.System.ItemTypeText, out var fileType);
311+
Ole32.PROPERTYKEY.System.ItemTypeText, out var fileType);
308312
folderContentsList.Add(new ShellFileItem(isFolder, recyclePath, fileName, filePath, recycleDate, fileSize, fileSizeBytes ?? 0, fileType));
309313
}
310314
catch (FileNotFoundException)
@@ -398,32 +402,42 @@ await Win32API.StartSTATask(() =>
398402
}
399403
else
400404
{
401-
var groups = split.GroupBy(x => new {
405+
var groups = split.GroupBy(x => new
406+
{
402407
Dir = Path.GetDirectoryName(x),
403408
Prog = Win32API.GetFileAssociation(x).Result ?? Path.GetExtension(x)
404409
});
405410
foreach (var group in groups)
406411
{
407-
if (!group.Any()) continue;
412+
if (!group.Any())
413+
{
414+
continue;
415+
}
416+
408417
var files = group.Select(x => new ShellItem(x));
409418
using var sf = files.First().Parent;
410-
Vanara.PInvoke.Shell32.IContextMenu menu = null;
419+
Shell32.IContextMenu menu = null;
411420
try
412421
{
413-
menu = sf.GetChildrenUIObjects<Vanara.PInvoke.Shell32.IContextMenu>(null, files.ToArray());
414-
menu.QueryContextMenu(Vanara.PInvoke.HMENU.NULL, 0, 0, 0, Vanara.PInvoke.Shell32.CMF.CMF_DEFAULTONLY);
415-
var pici = new Vanara.PInvoke.Shell32.CMINVOKECOMMANDINFOEX();
416-
pici.lpVerb = Vanara.PInvoke.Shell32.CMDSTR_OPEN;
417-
pici.nShow = Vanara.PInvoke.ShowWindowCommand.SW_SHOW;
422+
menu = sf.GetChildrenUIObjects<Shell32.IContextMenu>(null, files.ToArray());
423+
menu.QueryContextMenu(HMENU.NULL, 0, 0, 0, Shell32.CMF.CMF_DEFAULTONLY);
424+
var pici = new Shell32.CMINVOKECOMMANDINFOEX();
425+
pici.lpVerb = Shell32.CMDSTR_OPEN;
426+
pici.nShow = ShowWindowCommand.SW_SHOW;
418427
pici.cbSize = (uint)Marshal.SizeOf(pici);
419428
menu.InvokeCommand(pici);
420429
}
421430
finally
422431
{
423432
foreach (var elem in files)
433+
{
424434
elem.Dispose();
435+
}
436+
425437
if (menu != null)
438+
{
426439
Marshal.ReleaseComObject(menu);
440+
}
427441
}
428442
}
429443
}
@@ -483,7 +497,7 @@ private static string GetMtpPath(string executable)
483497
{
484498
if (executable.StartsWith("\\\\?\\"))
485499
{
486-
using var computer = new ShellFolder(Vanara.PInvoke.Shell32.KNOWNFOLDERID.FOLDERID_ComputerFolder);
500+
using var computer = new ShellFolder(Shell32.KNOWNFOLDERID.FOLDERID_ComputerFolder);
487501
using var device = computer.FirstOrDefault(i => executable.Replace("\\\\?\\", "").StartsWith(i.Name));
488502
var deviceId = device?.ParsingName;
489503
var itemPath = Regex.Replace(executable, @"^\\\\\?\\[^\\]*\\?", "");

Files.Launcher/Win32API.cs

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
using System.Threading;
99
using System.Threading.Tasks;
1010
using Vanara.Windows.Shell;
11+
using Vanara.PInvoke;
12+
using Windows.System;
13+
using System.IO;
1114

1215
namespace FilesFullTrust
1316
{
@@ -32,18 +35,23 @@ public static Task<T> StartSTATask<T>(Func<T> func)
3235
return tcs.Task;
3336
}
3437

35-
[DllImport("shell32.dll", CharSet = CharSet.Ansi)]
36-
public static extern IntPtr FindExecutable(string lpFile, string lpDirectory, [Out] StringBuilder lpResult);
37-
3838
public static async Task<string> GetFileAssociation(string filename)
3939
{
4040
// Find UWP apps
41-
var uwp_apps = await Windows.System.Launcher.FindFileHandlersAsync(System.IO.Path.GetExtension(filename));
42-
if (uwp_apps.Any()) return uwp_apps.First().PackageFamilyName;
41+
var uwp_apps = await Launcher.FindFileHandlersAsync(Path.GetExtension(filename));
42+
if (uwp_apps.Any())
43+
{
44+
return uwp_apps.First().PackageFamilyName;
45+
}
46+
4347
// Find desktop apps
4448
var lpResult = new StringBuilder();
45-
var hResult = FindExecutable(filename, null, lpResult);
46-
if (hResult.ToInt64() > 32) return lpResult.ToString();
49+
var hResult = Shell32.FindExecutable(filename, null, lpResult);
50+
if (hResult.ToInt64() > 32)
51+
{
52+
return lpResult.ToString();
53+
}
54+
4755
return null;
4856
}
4957

@@ -53,28 +61,28 @@ public enum PropertyReturnType
5361
DISPLAYVALUE
5462
}
5563

56-
public static List<(Vanara.PInvoke.Ole32.PROPERTYKEY propertyKey, PropertyReturnType returnType)> RecyledFileProperties =
57-
new List<(Vanara.PInvoke.Ole32.PROPERTYKEY propertyKey, PropertyReturnType returnType)>
64+
public static List<(Ole32.PROPERTYKEY propertyKey, PropertyReturnType returnType)> RecyledFileProperties =
65+
new List<(Ole32.PROPERTYKEY propertyKey, PropertyReturnType returnType)>
5866
{
59-
(Vanara.PInvoke.Ole32.PROPERTYKEY.System.Size, PropertyReturnType.RAWVALUE),
60-
(Vanara.PInvoke.Ole32.PROPERTYKEY.System.Size, PropertyReturnType.DISPLAYVALUE),
61-
(Vanara.PInvoke.Ole32.PROPERTYKEY.System.ItemTypeText, PropertyReturnType.RAWVALUE),
67+
(Ole32.PROPERTYKEY.System.Size, PropertyReturnType.RAWVALUE),
68+
(Ole32.PROPERTYKEY.System.Size, PropertyReturnType.DISPLAYVALUE),
69+
(Ole32.PROPERTYKEY.System.ItemTypeText, PropertyReturnType.RAWVALUE),
6270
(PropertyStore.GetPropertyKeyFromName("System.Recycle.DateDeleted"), PropertyReturnType.RAWVALUE)
6371
};
6472

6573
// A faster method of getting file shell properties (currently non used)
66-
public static IList<object> GetFileProperties(ShellItem folderItem, List<(Vanara.PInvoke.Ole32.PROPERTYKEY propertyKey, PropertyReturnType returnType)> properties)
74+
public static IList<object> GetFileProperties(ShellItem folderItem, List<(Ole32.PROPERTYKEY propertyKey, PropertyReturnType returnType)> properties)
6775
{
6876
var propValueList = new List<object>(properties.Count);
69-
var flags = Vanara.PInvoke.PropSys.GETPROPERTYSTOREFLAGS.GPS_DEFAULT | Vanara.PInvoke.PropSys.GETPROPERTYSTOREFLAGS.GPS_FASTPROPERTIESONLY;
77+
var flags = PropSys.GETPROPERTYSTOREFLAGS.GPS_DEFAULT | PropSys.GETPROPERTYSTOREFLAGS.GPS_FASTPROPERTIESONLY;
7078

71-
Vanara.PInvoke.PropSys.IPropertyStore pStore = null;
79+
PropSys.IPropertyStore pStore = null;
7280
try
7381
{
74-
pStore = ((Vanara.PInvoke.Shell32.IShellItem2)folderItem.IShellItem).GetPropertyStoreForKeys(properties.Select(p => p.propertyKey).ToArray(), (uint)properties.Count, flags, typeof(Vanara.PInvoke.PropSys.IPropertyStore).GUID);
82+
pStore = ((Shell32.IShellItem2)folderItem.IShellItem).GetPropertyStoreForKeys(properties.Select(p => p.propertyKey).ToArray(), (uint)properties.Count, flags, typeof(PropSys.IPropertyStore).GUID);
7583
foreach (var prop in properties)
7684
{
77-
using var propVariant = new Vanara.PInvoke.Ole32.PROPVARIANT();
85+
using var propVariant = new Ole32.PROPVARIANT();
7886
pStore.GetValue(prop.propertyKey, propVariant);
7987
if (prop.returnType == PropertyReturnType.RAWVALUE)
8088
{
@@ -83,7 +91,7 @@ public static IList<object> GetFileProperties(ShellItem folderItem, List<(Vanara
8391
else if (prop.returnType == PropertyReturnType.DISPLAYVALUE)
8492
{
8593
using var pDesc = PropertyDescription.Create(prop.propertyKey);
86-
var pValue = pDesc?.FormatForDisplay(propVariant, Vanara.PInvoke.PropSys.PROPDESC_FORMAT_FLAGS.PDFF_DEFAULT);
94+
var pValue = pDesc?.FormatForDisplay(propVariant, PropSys.PROPDESC_FORMAT_FLAGS.PDFF_DEFAULT);
8795
propValueList.Add(pValue);
8896
}
8997
}
@@ -96,39 +104,28 @@ public static IList<object> GetFileProperties(ShellItem folderItem, List<(Vanara
96104
return propValueList;
97105
}
98106

99-
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
100-
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
101-
102-
[DllImport("user32.dll", CharSet = CharSet.Auto)]
103-
private static extern int LoadString(IntPtr hInstance, int ID, StringBuilder lpBuffer, int nBufferMax);
104-
105-
[DllImport("kernel32.dll", SetLastError = true)]
106-
[return: MarshalAs(UnmanagedType.Bool)]
107-
private static extern bool FreeLibrary(IntPtr hModule);
108-
109107
public static string ExtractStringFromDLL(string file, int number)
110108
{
111-
IntPtr lib = LoadLibrary(file);
109+
var lib = Kernel32.LoadLibrary(file);
112110
StringBuilder result = new StringBuilder(2048);
113-
LoadString(lib, number, result, result.Capacity);
114-
FreeLibrary(lib);
111+
User32.LoadString(lib, number, result, result.Capacity);
112+
Kernel32.FreeLibrary(lib);
115113
return result.ToString();
116114
}
117115

118-
[DllImport("shell32.dll", SetLastError = true)]
119-
public static extern IntPtr CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs);
120-
121-
[DllImport("kernel32.dll")]
122-
public static extern IntPtr LocalFree(IntPtr hMem);
123-
124116
public static string[] CommandLineToArgs(string commandLine)
125117
{
126-
if (String.IsNullOrEmpty(commandLine))
118+
if (string.IsNullOrEmpty(commandLine))
119+
{
127120
return Array.Empty<string>();
121+
}
128122

129-
var argv = CommandLineToArgvW(commandLine, out int argc);
123+
var argv = Shell32.CommandLineToArgvW(commandLine, out int argc);
130124
if (argv == IntPtr.Zero)
131-
throw new System.ComponentModel.Win32Exception();
125+
{
126+
throw new Win32Exception();
127+
}
128+
132129
try
133130
{
134131
var args = new string[argc];

0 commit comments

Comments
 (0)