Skip to content
This repository was archived by the owner on Jun 23, 2021. It is now read-only.

Commit 37369f0

Browse files
author
Allen Byron Penner
committed
Win Explorer Content Menu Integration
1 parent aabda47 commit 37369f0

9 files changed

Lines changed: 302 additions & 6188 deletions

CommonApplicationData.cs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
//Author: DaveyM69
2+
//Date: 22 May 2010
3+
//Link: http://www.codeproject.com/Tips/61987/Allow-write-modify-access-to-CommonApplicationData
4+
5+
using System;
6+
using System.IO;
7+
using System.Security.AccessControl;
8+
using System.Security.Principal;
9+
10+
namespace FileHasher
11+
{
12+
class CommonApplicationData
13+
{
14+
15+
private string applicationFolder;
16+
private string companyFolder;
17+
private static readonly string directory =
18+
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
19+
20+
/// <summary>
21+
/// Creates a new instance of this class creating the specified company and application folders
22+
/// if they don't already exist and optionally allows write/modify to all users.
23+
/// </summary>
24+
/// <param name="companyFolder">The name of the company's folder (normally the company name).</param>
25+
/// <param name="applicationFolder">The name of the application's folder (normally the application name).</param>
26+
/// <remarks>If the application folder already exists then permissions if requested are NOT altered.</remarks>
27+
public CommonApplicationData(string companyFolder, string applicationFolder)
28+
: this(companyFolder, applicationFolder, false)
29+
{ }
30+
/// <summary>
31+
/// Creates a new instance of this class creating the specified company and application folders
32+
/// if they don't already exist and optionally allows write/modify to all users.
33+
/// </summary>
34+
/// <param name="companyFolder">The name of the company's folder (normally the company name).</param>
35+
/// <param name="applicationFolder">The name of the application's folder (normally the application name).</param>
36+
/// <param name="allUsers">true to allow write/modify to all users; otherwise, false.</param>
37+
/// <remarks>If the application folder already exists then permissions if requested are NOT altered.</remarks>
38+
public CommonApplicationData(string companyFolder, string applicationFolder, bool allUsers)
39+
{
40+
this.applicationFolder = applicationFolder;
41+
this.companyFolder = companyFolder;
42+
CreateFolders(allUsers);
43+
}
44+
45+
/// <summary>
46+
/// Gets the path of the application's data folder.
47+
/// </summary>
48+
public string ApplicationFolderPath
49+
{
50+
get { return Path.Combine(CompanyFolderPath, applicationFolder); }
51+
}
52+
/// <summary>
53+
/// Gets the path of the company's data folder.
54+
/// </summary>
55+
public string CompanyFolderPath
56+
{
57+
get { return Path.Combine(directory, companyFolder); }
58+
}
59+
60+
private void CreateFolders(bool allUsers)
61+
{
62+
DirectoryInfo directoryInfo;
63+
DirectorySecurity directorySecurity;
64+
AccessRule rule;
65+
SecurityIdentifier securityIdentifier = new SecurityIdentifier
66+
(WellKnownSidType.BuiltinUsersSid, null);
67+
if (!Directory.Exists(CompanyFolderPath))
68+
{
69+
directoryInfo = Directory.CreateDirectory(CompanyFolderPath);
70+
bool modified;
71+
directorySecurity = directoryInfo.GetAccessControl();
72+
rule = new FileSystemAccessRule(
73+
securityIdentifier,
74+
FileSystemRights.Write |
75+
FileSystemRights.ReadAndExecute |
76+
FileSystemRights.Modify,
77+
AccessControlType.Allow);
78+
directorySecurity.ModifyAccessRule(AccessControlModification.Add, rule, out modified);
79+
directoryInfo.SetAccessControl(directorySecurity);
80+
}
81+
if (!Directory.Exists(ApplicationFolderPath))
82+
{
83+
directoryInfo = Directory.CreateDirectory(ApplicationFolderPath);
84+
if (allUsers)
85+
{
86+
bool modified;
87+
directorySecurity = directoryInfo.GetAccessControl();
88+
rule = new FileSystemAccessRule(
89+
securityIdentifier,
90+
FileSystemRights.Write |
91+
FileSystemRights.ReadAndExecute |
92+
FileSystemRights.Modify,
93+
InheritanceFlags.ContainerInherit |
94+
InheritanceFlags.ObjectInherit,
95+
PropagationFlags.InheritOnly,
96+
AccessControlType.Allow);
97+
directorySecurity.ModifyAccessRule(AccessControlModification.Add, rule, out modified);
98+
directoryInfo.SetAccessControl(directorySecurity);
99+
}
100+
}
101+
}
102+
/// <summary>
103+
/// Returns the path of the application's data folder.
104+
/// </summary>
105+
/// <returns>The path of the application's data folder.</returns>
106+
public override string ToString()
107+
{
108+
return ApplicationFolderPath;
109+
}
110+
111+
}
112+
}

FileHasher.csproj

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,14 @@
8787
<Reference Include="System.Windows.Forms" />
8888
</ItemGroup>
8989
<ItemGroup>
90+
<Compile Include="CommonApplicationData.cs" />
9091
<Compile Include="Form1.cs">
9192
<SubType>Form</SubType>
9293
</Compile>
9394
<Compile Include="Form1.Designer.cs">
9495
<DependentUpon>Form1.cs</DependentUpon>
9596
</Compile>
97+
<Compile Include="GlobalSettings.cs" />
9698
<Compile Include="Program.cs" />
9799
<Compile Include="Properties\AssemblyInfo.cs" />
98100
<EmbeddedResource Include="Form1.resx">
@@ -108,18 +110,10 @@
108110
<DependentUpon>Resources.resx</DependentUpon>
109111
<DesignTime>True</DesignTime>
110112
</Compile>
113+
<None Include="app.config" />
111114
<None Include="filehasher.pfx" />
112115
<None Include="FileHasher_TemporaryKey.pfx" />
113116
<None Include="Properties\app.manifest" />
114-
<None Include="Properties\Settings.settings">
115-
<Generator>SettingsSingleFileGenerator</Generator>
116-
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
117-
</None>
118-
<Compile Include="Properties\Settings.Designer.cs">
119-
<AutoGen>True</AutoGen>
120-
<DependentUpon>Settings.settings</DependentUpon>
121-
<DesignTimeSharedInput>True</DesignTimeSharedInput>
122-
</Compile>
123117
</ItemGroup>
124118
<ItemGroup>
125119
<None Include="Resources\filehasher.png" />

Form1.Designer.cs

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Form1.cs

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
1-
using System;
1+
using Microsoft.Win32;
2+
using System;
23
using System.ComponentModel;
4+
using System.Diagnostics;
35
using System.IO;
46
using System.Security.Cryptography;
7+
using System.Security.Principal;
58
using System.Windows.Forms;
69

710
namespace FileHasher
811
{
912
public partial class Form1 : Form
1013
{
14+
public string arg;
1115
public int HashType = 0;
1216
public Form1()
1317
{
1418
InitializeComponent();
1519
}
1620

21+
public Form1(string argument)
22+
{
23+
arg = argument;
24+
InitializeComponent();
25+
}
26+
1727
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
1828
{
1929
if (string.IsNullOrEmpty((string)e.Argument))
@@ -124,6 +134,14 @@ private void Form1_Load(object sender, EventArgs e)
124134
saveFileDialog1.Title = Properties.Resources.SaveDialogTitle;
125135

126136
openFileDialog1.FileName = "";
137+
138+
enableCMenuCheckBox.Checked = GlobalSettings.WinContextMenuEnabled;
139+
140+
if (!string.IsNullOrEmpty(arg))
141+
{
142+
filenameTextBox.Text = arg;
143+
computeButton_Click(sender, e);
144+
}
127145
}
128146

129147
private void copyButton_Click(object sender, EventArgs e)
@@ -177,5 +195,97 @@ private void compareTextBox_TextChanged(object sender, EventArgs e)
177195
compareTextBox.BackColor = System.Drawing.Color.LightCoral;
178196

179197
}
198+
199+
private void enableCMenuCheckBox_CheckedChanged(object sender, EventArgs e)
200+
{
201+
if (!IsAdmin())
202+
{
203+
RestartElevated(arg);
204+
return;
205+
}
206+
207+
if (enableCMenuCheckBox.Checked)
208+
{
209+
RegistryKey regmenu = null;
210+
RegistryKey regcmd = null;
211+
try
212+
{
213+
regmenu = Registry.ClassesRoot.CreateSubKey("*\\shell\\Checksum");
214+
if (regmenu != null)
215+
regmenu.SetValue("", "Checksum");
216+
regcmd = Registry.ClassesRoot.CreateSubKey("*\\shell\\Checksum\\command");
217+
if (regcmd != null)
218+
regcmd.SetValue("", Application.ExecutablePath + " %1");
219+
220+
GlobalSettings.WinContextMenuEnabled = true;
221+
}
222+
catch (Exception ex)
223+
{
224+
MessageBox.Show(this, ex.ToString());
225+
}
226+
finally
227+
{
228+
if (regmenu != null)
229+
regmenu.Close();
230+
if (regcmd != null)
231+
regcmd.Close();
232+
}
233+
234+
}
235+
else
236+
{
237+
try
238+
{
239+
RegistryKey reg = Registry.ClassesRoot.OpenSubKey("*\\shell\\Checksum\\command");
240+
if (reg != null)
241+
{
242+
reg.Close();
243+
Registry.ClassesRoot.DeleteSubKey("*\\shell\\Checksum\\command");
244+
}
245+
reg = Registry.ClassesRoot.OpenSubKey("*\\shell\\Checksum");
246+
if (reg != null)
247+
{
248+
reg.Close();
249+
Registry.ClassesRoot.DeleteSubKey("*\\shell\\Checksum");
250+
}
251+
252+
GlobalSettings.WinContextMenuEnabled = false;
253+
}
254+
catch (Exception ex)
255+
{
256+
MessageBox.Show(this, ex.ToString());
257+
}
258+
}
259+
260+
Application.DoEvents();
261+
enableCMenuCheckBox.Checked = GlobalSettings.WinContextMenuEnabled;
262+
}
263+
264+
static internal bool IsAdmin()
265+
{
266+
WindowsIdentity id = WindowsIdentity.GetCurrent();
267+
WindowsPrincipal p = new WindowsPrincipal(id);
268+
return p.IsInRole(WindowsBuiltInRole.Administrator);
269+
}
270+
271+
internal static void RestartElevated(string arg)
272+
{
273+
ProcessStartInfo startInfo = new ProcessStartInfo();
274+
startInfo.UseShellExecute = true;
275+
startInfo.WorkingDirectory = Environment.CurrentDirectory;
276+
startInfo.FileName = Application.ExecutablePath;
277+
startInfo.Arguments = arg;
278+
startInfo.Verb = "runas";
279+
try
280+
{
281+
Process p = Process.Start(startInfo);
282+
}
283+
catch (System.ComponentModel.Win32Exception ex)
284+
{
285+
return;
286+
}
287+
288+
Application.Exit();
289+
}
180290
}
181291
}

0 commit comments

Comments
 (0)