rawfilewizard

git clone https://git.clttr.info/rawfilewizard.git
Log (Feed) | Files | Refs (Tags) | README | LICENSE

commit de4d06c64b47df77b232e0e5a5054b18e5c8ec33
parent 994b3549a765edae6c6e7b49270085528d5b9a77
Author: rwa <apollo@rw-net.de>
Date:   Sat, 27 Oct 2018 21:15:14 +0200

implements #14

add posibility to register to tool for Windows Explorer folder context menu

Diffstat:
MJpegDivider/JpegDivider.csproj | 1+
MJpegDivider/JpegDivider.csproj.user | 5++++-
MJpegDivider/Program.cs | 121++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
MJpegDivider/Properties/AssemblyInfo.cs | 4++--
AJpegDivider/UacHelper.cs | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 234 insertions(+), 13 deletions(-)

diff --git a/JpegDivider/JpegDivider.csproj b/JpegDivider/JpegDivider.csproj @@ -44,6 +44,7 @@ <ItemGroup> <Compile Include="Program.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="UacHelper.cs" /> </ItemGroup> <ItemGroup> <None Include="App.config" /> diff --git a/JpegDivider/JpegDivider.csproj.user b/JpegDivider/JpegDivider.csproj.user @@ -1,7 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'"> - <StartArguments>/%3f</StartArguments> + <StartArguments>register</StartArguments> <StartWorkingDirectory>C:\Users\winuser\Pictures</StartWorkingDirectory> </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'"> + <StartArguments>register</StartArguments> + </PropertyGroup> </Project> \ No newline at end of file diff --git a/JpegDivider/Program.cs b/JpegDivider/Program.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Win32; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -15,10 +16,19 @@ namespace JpegDivider Console.WriteLine("Leave args blank or give exactly one dir!"); } - if (args[0].Equals("help") || args[0].Equals("/h") || args[0].Equals("/?")) + switch (args[0].ToLower()) { - showHelp(); - return; + case "help": + ShowHelp(); + return; + case "register": + RegisterShellExt(); + return; + case "deregister": + DeregisterShellExt(); + return; + default: + break; } string dir; @@ -31,8 +41,14 @@ namespace JpegDivider dir = Directory.GetCurrentDirectory(); } - Console.WriteLine($"working dir: {dir}"); + Divide(dir); + Console.ReadKey(); + } + + private static void Divide(string dir) + { + Console.WriteLine($"working directory: {dir}"); // create string sepDir = Path.Combine(dir, "JPEG"); if (!Directory.Exists(sepDir)) @@ -60,11 +76,76 @@ namespace JpegDivider } Console.WriteLine("Finished."); + } - Console.ReadKey(); + private static void DeregisterShellExt() + { + if (!UacCheck) { return; } + + string MenuName = "Folder\\shell\\JpegDivider"; + string Command = "Folder\\shell\\JpegDivider\\command"; + + try + { + RegistryKey reg = Registry.ClassesRoot.OpenSubKey(Command); + if (reg != null) + { + reg.Close(); + Registry.ClassesRoot.DeleteSubKey(Command); + } + reg = Registry.ClassesRoot.OpenSubKey(MenuName); + if (reg != null) + { + reg.Close(); + Registry.ClassesRoot.DeleteSubKey(MenuName); + } + } + catch (Exception ex) + { + Console.WriteLine($"Failed to remove application from Windows Explorer context menu:{Environment.NewLine}{ex.Message}"); + } } - private static void showHelp() + private static void RegisterShellExt() + { + if (!UacCheck) { return; } + + string MenuName = "Folder\\shell\\JpegDivider"; + string Command = "Folder\\shell\\JpegDivider\\command"; + + RegistryKey regmenu = null; + RegistryKey regcmd = null; + try + { + regmenu = Registry.ClassesRoot.CreateSubKey(MenuName); + if (regmenu != null) + { + regmenu.SetValue("", "JpegDivider"); + } + regcmd = Registry.ClassesRoot.CreateSubKey(Command); + if (regcmd != null) + { + regcmd.SetValue("", $"\"{Assembly.GetEntryAssembly().Location}\" \"%L\""); + } + } + catch (Exception ex) + { + Console.WriteLine($"Failed to register application to Windows Explorer context menu:{Environment.NewLine}{ex.Message}"); + } + finally + { + if (regmenu != null) + { + regmenu.Close(); + } + if (regcmd != null) + { + regcmd.Close(); + } + } + } + + private static void ShowHelp() { Console.WriteLine($"{Assembly.GetExecutingAssembly().GetName().Name} - Version {Assembly.GetExecutingAssembly().GetName().Version}"); Console.WriteLine("published under BSD 3 - Clause License"); @@ -72,11 +153,30 @@ namespace JpegDivider Console.WriteLine("https://gitlab.com/guzzisti1/rawfilewizard"); Console.WriteLine(""); Console.WriteLine("divide jpegs from raw files by moving them to subfolder JPEG"); + Console.WriteLine("the subfolder is created if not existing"); Console.WriteLine(""); - Console.WriteLine("Commandline:"); + Console.WriteLine("commandline:"); Console.WriteLine("jpegdivider.exe - move jpegs from current working dir to subfolder"); Console.WriteLine("jpgedivider.exe <path_to_folder> - move jpegs from specified folder to subfolder"); - Console.WriteLine("jpgedivider.exe /h|/?|help - show this help"); + Console.WriteLine("jpegdivider.exe register - register the program to folder context menu, run JpegDivider on a selected folder from Windows Explorer"); + Console.WriteLine("jpegdivider.exe deregister - remove the programm from folder context menu"); + Console.WriteLine("jpgedivider.exe help - show this help"); + } + + private static bool UacCheck + { + get + { + if (UacHelper.IsProcessElevated) + { + return true; + } + else + { + Console.WriteLine("Need to run as administrator / with elevated UAC rights!"); + return false; + } + } } } -} +} +\ No newline at end of file diff --git a/JpegDivider/Properties/AssemblyInfo.cs b/JpegDivider/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // 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")] +[assembly: AssemblyVersion("1.1.0.0")] +[assembly: AssemblyFileVersion("1.1.0.0")] diff --git a/JpegDivider/UacHelper.cs b/JpegDivider/UacHelper.cs @@ -0,0 +1,115 @@ +using Microsoft.Win32; +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Security.Principal; + +namespace JpegDivider +{ + public static class UacHelper + { + private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; + private const string uacRegistryValue = "EnableLUA"; + + private static uint STANDARD_RIGHTS_READ = 0x00020000; + private static uint TOKEN_QUERY = 0x0008; + private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); + + [DllImport("advapi32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); + + [DllImport("advapi32.dll", SetLastError = true)] + public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength); + + public enum TOKEN_INFORMATION_CLASS + { + TokenUser = 1, + TokenGroups, + TokenPrivileges, + TokenOwner, + TokenPrimaryGroup, + TokenDefaultDacl, + TokenSource, + TokenType, + TokenImpersonationLevel, + TokenStatistics, + TokenRestrictedSids, + TokenSessionId, + TokenGroupsAndPrivileges, + TokenSessionReference, + TokenSandBoxInert, + TokenAuditPolicy, + TokenOrigin, + TokenElevationType, + TokenLinkedToken, + TokenElevation, + TokenHasRestrictions, + TokenAccessInformation, + TokenVirtualizationAllowed, + TokenVirtualizationEnabled, + TokenIntegrityLevel, + TokenUIAccess, + TokenMandatoryPolicy, + TokenLogonSid, + MaxTokenInfoClass + } + + public enum TOKEN_ELEVATION_TYPE + { + TokenElevationTypeDefault = 1, + TokenElevationTypeFull, + TokenElevationTypeLimited + } + + public static bool IsUacEnabled + { + get + { + RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false); + bool result = uacKey.GetValue(uacRegistryValue).Equals(1); + return result; + } + } + + public static bool IsProcessElevated + { + get + { + if (IsUacEnabled) + { + IntPtr tokenHandle; + if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle)) + { + throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error()); + } + + TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; + + int elevationResultSize = Marshal.SizeOf((int)elevationResult); + uint returnedSize = 0; + IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize); + + bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint)elevationResultSize, out returnedSize); + if (success) + { + elevationResult = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(elevationTypePtr); + bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull; + return isProcessAdmin; + } + else + { + throw new ApplicationException("Unable to determine the current elevation."); + } + } + else + { + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new WindowsPrincipal(identity); + bool result = principal.IsInRole(WindowsBuiltInRole.Administrator); + return result; + } + } + } + } +} +\ No newline at end of file