├── .gitattributes ├── .gitignore ├── Compiled └── CygwinContextMenu.exe ├── CygwinContextMenu.csproj ├── CygwinContextMenu.sln ├── FileShellExtension.cs ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── README.markdown └── app.manifest /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /Compiled/CygwinContextMenu.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Genbox/CygwinContextMenu/474ca362bcbad5d63a0d968513b4d1d28622ee4b/Compiled/CygwinContextMenu.exe -------------------------------------------------------------------------------- /CygwinContextMenu.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {1175DA05-939E-497F-958F-C0BA7F94313F} 9 | WinExe 10 | Properties 11 | CygwinContextMenu 12 | CygwinContextMenu 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | app.manifest 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | copy "$(TargetPath)" "$(ProjectDir)Compiled\" 58 | 59 | 66 | -------------------------------------------------------------------------------- /CygwinContextMenu.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CygwinContextMenu", "CygwinContextMenu.csproj", "{1175DA05-939E-497F-958F-C0BA7F94313F}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {1175DA05-939E-497F-958F-C0BA7F94313F}.Debug|x86.ActiveCfg = Debug|x86 13 | {1175DA05-939E-497F-958F-C0BA7F94313F}.Debug|x86.Build.0 = Debug|x86 14 | {1175DA05-939E-497F-958F-C0BA7F94313F}.Release|x86.ActiveCfg = Release|x86 15 | {1175DA05-939E-497F-958F-C0BA7F94313F}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /FileShellExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using Microsoft.Win32; 4 | 5 | namespace CygwinContextMenu 6 | { 7 | //Sample code from Ralph Arvesen (www.vertigo.com / www.lostsprings.com) 8 | //Source: http://www.codeproject.com/Articles/15171/Simple-shell-context-menu 9 | 10 | /// 11 | /// Register and unregister simple shell context menus. 12 | /// 13 | public static class FileShellExtension 14 | { 15 | public static bool IsRegistered(string fileType, string shellKeyName, bool userOnly) 16 | { 17 | string regPath = string.Format(@"Software\Classes\{0}\shell\{1}", fileType, shellKeyName); 18 | 19 | RegistryKey hive = userOnly ? Registry.CurrentUser : Registry.LocalMachine; 20 | 21 | using (RegistryKey key = hive.OpenSubKey(regPath)) 22 | { 23 | return key != null; 24 | } 25 | } 26 | 27 | /// 28 | /// Register a simple shell context menu. 29 | /// 30 | /// The file type to register. 31 | /// Name that appears in the registry. 32 | /// Text that appears in the context menu. 33 | /// Command line that is executed. 34 | /// True means it will only show when CTRL key is down. 35 | public static void Register(string fileType, string shellKeyName, string menuText, string menuCommand, bool userOnly, bool makeExtended = false) 36 | { 37 | Debug.Assert(!string.IsNullOrEmpty(fileType) && !string.IsNullOrEmpty(shellKeyName) && !string.IsNullOrEmpty(menuText) && !string.IsNullOrEmpty(menuCommand)); 38 | 39 | // create full path to registry location 40 | string regPath = string.Format(@"Software\Classes\{0}\shell\{1}", fileType, shellKeyName); 41 | 42 | RegistryKey hive = userOnly ? Registry.CurrentUser : Registry.LocalMachine; 43 | 44 | // add context menu to the registry 45 | using (RegistryKey key = hive.CreateSubKey(regPath)) 46 | { 47 | if (key != null) 48 | key.SetValue(null, menuText); 49 | else 50 | throw new Exception("Failed to create " + regPath); 51 | 52 | if (makeExtended) 53 | { 54 | if (key != null) key.SetValue("Extended", string.Empty); 55 | } 56 | } 57 | 58 | // add command that is invoked to the registry 59 | using (RegistryKey key = hive.CreateSubKey(string.Format(@"{0}\command", regPath))) 60 | { 61 | if (key != null) 62 | key.SetValue(null, menuCommand); 63 | else 64 | throw new Exception("Failed to create " + menuCommand); 65 | } 66 | } 67 | 68 | /// 69 | /// Unregister a simple shell context menu. 70 | /// 71 | /// The file type to unregister. 72 | /// Name that was registered in the registry. 73 | public static void Unregister(string fileType, string shellKeyName, bool userOnly) 74 | { 75 | Debug.Assert(!string.IsNullOrEmpty(fileType) && 76 | !string.IsNullOrEmpty(shellKeyName)); 77 | 78 | // full path to the registry location 79 | string regPath = string.Format(@"Software\Classes\{0}\shell\{1}", fileType, shellKeyName); 80 | 81 | RegistryKey hive = userOnly ? Registry.CurrentUser : Registry.LocalMachine; 82 | 83 | // remove context menu from the registry 84 | hive.DeleteSubKeyTree(regPath, false); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Windows.Forms; 4 | using Microsoft.Win32; 5 | 6 | [assembly: CLSCompliant(true)] 7 | namespace CygwinContextMenu 8 | { 9 | static class Program 10 | { 11 | // file type to register 12 | const string FileType = @"Directory\Background"; 13 | 14 | // context menu name in the registry 15 | const string KeyName = "opencygwin"; 16 | 17 | // context menu text 18 | const string MenuText = "Open cygwin window here"; 19 | 20 | [STAThread] 21 | static void Main(string[] args) 22 | { 23 | DialogResult result = MessageBox.Show("You want the installer to run for all users?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question); 24 | bool allUsers = result == DialogResult.Yes; 25 | 26 | try 27 | { 28 | bool isRegistered = FileShellExtension.IsRegistered(FileType, KeyName, !allUsers); 29 | 30 | if (isRegistered) 31 | { 32 | // unregister the context menu 33 | FileShellExtension.Unregister(FileType, KeyName, !allUsers); 34 | 35 | MessageBox.Show(string.Format("The '{0}' shell extension was unregistered.", MenuText), MenuText, MessageBoxButtons.OK, MessageBoxIcon.Information); 36 | } 37 | else 38 | { 39 | //Find the location of cygwin. 40 | string cygwinPath = @"C:\cygwin"; 41 | string cygwinPath64 = @"C:\cygwin64"; 42 | 43 | using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)) 44 | { 45 | using (RegistryKey subKey = baseKey.OpenSubKey(@"SOFTWARE\Cygwin\setup\")) 46 | { 47 | if (subKey != null) 48 | cygwinPath = subKey.GetValue("rootdir").ToString(); 49 | } 50 | } 51 | 52 | using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)) 53 | { 54 | using (RegistryKey subKey = baseKey.OpenSubKey(@"SOFTWARE\Cygwin\setup\")) 55 | { 56 | if (subKey != null) 57 | cygwinPath64 = subKey.GetValue("rootdir").ToString(); 58 | } 59 | } 60 | 61 | string cygwinTTY = Path.Combine(cygwinPath, @"bin\mintty.exe"); 62 | string cygwinTTY64 = Path.Combine(cygwinPath64, @"bin\mintty.exe"); 63 | 64 | if (!File.Exists(cygwinTTY) && !File.Exists(cygwinTTY64)) 65 | { 66 | MessageBox.Show("Cygwin is not installed. Please install Cygwin.", "Cygwin not found", MessageBoxButtons.OK, MessageBoxIcon.Error); 67 | return; 68 | } 69 | 70 | //see http://code.google.com/p/mintty/wiki/Tips#Starting_mintty_from_a_batch_file 71 | string menuCommand = File.Exists(cygwinTTY64) ? "\"" + cygwinTTY64 + "\" /bin/env CHERE_INVOKING=1 /bin/bash -l" : "\"" + cygwinTTY + "\" /bin/env CHERE_INVOKING=1 /bin/bash -l"; 72 | 73 | // register the context menu 74 | FileShellExtension.Register(FileType, KeyName, MenuText, menuCommand, !allUsers); 75 | 76 | MessageBox.Show(string.Format("The '{0}' shell extension was registered for " + (allUsers ? "all users." : "only you."), MenuText), MenuText, MessageBoxButtons.OK, MessageBoxIcon.Information); 77 | } 78 | } 79 | catch (Exception ex) 80 | { 81 | MessageBox.Show(ex.Message, "Exception caught", MessageBoxButtons.OK, MessageBoxIcon.Error); 82 | } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("CygwinContextMenu")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("CygwinContextMenu")] 12 | [assembly: AssemblyCopyright("Copyright Ian Qvist © 2013")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("d23a0df3-2158-45d4-a03f-4cb6ee81700f")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.1.0")] 35 | [assembly: AssemblyFileVersion("1.0.1.0")] 36 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Cygwin Context Menu - Shift right click in a folder to open Cygwin. 2 | 3 | ### How to use it 4 | 1. Download the application: https://github.com/Genbox/CygwinContextMenu/raw/master/Compiled/CygwinContextMenu.exe 5 | 2. Open it. 6 | 3. The context menu is now registered. 7 | 4. Hold shift and right click in a folder and choose 'Open Cygwin window here' 8 | 9 | ### I want to compile it myself 10 | 1. Compile the project by pressing CTRL + F5 in Visual Studio. 11 | 2. Doubleclick the 'CygwinContextMenu.exe' in the build folder 12 | 3. The context menu is now registered. 13 | 4. Hold shift and right click in a folder and choose 'Open Cygwin window here' 14 | 15 | ### Notes 16 | * Open the CygwinContextMenu.exe application again to unregister it. 17 | * Once registered, you no longer need to keep CygwinContextMenu.exe around. 18 | 19 | Cygwin manual tells us we can use the 'chere' application to register the a context menu in explorer. 20 | See http://code.google.com/p/mintty/wiki/Tips#Starting_mintty_from_a_batch_file 21 | 22 | The changes between using 'chere' and this application are very subtle: 23 | * It only works inside folders, and not on folders. This reduces clutter in the menu. 24 | * It uses shift right click, just like the normal 'Open command window here' 25 | * It is named 'Open Cygwin window here' instead of 'Open bash shell' -------------------------------------------------------------------------------- /app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 59 | 60 | 61 | 75 | 76 | 77 | --------------------------------------------------------------------------------