mirror of
				https://github.com/nsnail/dot.git
				synced 2025-11-04 11:00:49 +08:00 
			
		
		
		
	feat: ✨ windows右键菜单打开Git仓库网址 (#30)
This commit is contained in:
		@@ -6,6 +6,8 @@ IP工具
 | 
				
			|||||||
Json工具
 | 
					Json工具
 | 
				
			||||||
Json文本转义成字符串
 | 
					Json文本转义成字符串
 | 
				
			||||||
NTP_标准时钟
 | 
					NTP_标准时钟
 | 
				
			||||||
 | 
					Windows右键菜单已卸载
 | 
				
			||||||
 | 
					Windows右键菜单已添加
 | 
				
			||||||
下载分块数
 | 
					下载分块数
 | 
				
			||||||
下载完成
 | 
					下载完成
 | 
				
			||||||
仓库
 | 
					仓库
 | 
				
			||||||
@@ -16,6 +18,7 @@ NTP_标准时钟
 | 
				
			|||||||
剩余时间
 | 
					剩余时间
 | 
				
			||||||
剪贴板未包含正确的Json字符串
 | 
					剪贴板未包含正确的Json字符串
 | 
				
			||||||
单击鼠标左键复制颜色和坐标到剪贴板
 | 
					单击鼠标左键复制颜色和坐标到剪贴板
 | 
				
			||||||
 | 
					卸载Windows右键菜单
 | 
				
			||||||
压缩Json文本
 | 
					压缩Json文本
 | 
				
			||||||
只读模式_不会真实修改文件
 | 
					只读模式_不会真实修改文件
 | 
				
			||||||
同步本机时间
 | 
					同步本机时间
 | 
				
			||||||
@@ -28,6 +31,7 @@ NTP_标准时钟
 | 
				
			|||||||
屏幕坐标颜色选取工具
 | 
					屏幕坐标颜色选取工具
 | 
				
			||||||
已复制到剪贴板
 | 
					已复制到剪贴板
 | 
				
			||||||
总进度
 | 
					总进度
 | 
				
			||||||
 | 
					打开Git仓库网址
 | 
				
			||||||
执行命令后保留会话
 | 
					执行命令后保留会话
 | 
				
			||||||
指定的路径不存在
 | 
					指定的路径不存在
 | 
				
			||||||
按下Esc隐藏译文
 | 
					按下Esc隐藏译文
 | 
				
			||||||
@@ -44,9 +48,10 @@ NTP_标准时钟
 | 
				
			|||||||
本机时钟
 | 
					本机时钟
 | 
				
			||||||
本机时钟偏移平均值
 | 
					本机时钟偏移平均值
 | 
				
			||||||
本机时间已同步
 | 
					本机时间已同步
 | 
				
			||||||
查找此目录下所有Git仓库目录
 | 
					 | 
				
			||||||
查找文件
 | 
					查找文件
 | 
				
			||||||
 | 
					查找此目录下所有Git仓库目录
 | 
				
			||||||
格式化Json文本
 | 
					格式化Json文本
 | 
				
			||||||
 | 
					添加Windows右键菜单
 | 
				
			||||||
目录检索深度
 | 
					目录检索深度
 | 
				
			||||||
移除文件尾部换行和空格
 | 
					移除文件尾部换行和空格
 | 
				
			||||||
移除文件的UTF8_BOM
 | 
					移除文件的UTF8_BOM
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,60 +0,0 @@
 | 
				
			|||||||
using System.Diagnostics;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Dot;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ReSharper disable once UnusedType.Global
 | 
					 | 
				
			||||||
// ReSharper disable once UnusedMember.Global
 | 
					 | 
				
			||||||
internal static class CsxEditor
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    private static readonly string[] _imageExts = { "*.jpg", "*.jpeg" };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // ReSharper disable once UnusedMember.Local
 | 
					 | 
				
			||||||
    #pragma warning disable S1144, RCS1213, IDE0051
 | 
					 | 
				
			||||||
    private static void Run()
 | 
					 | 
				
			||||||
        #pragma warning restore IDE0051, RCS1213, S1144
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
            for %%i in (*.png) do pngquant %%i --force --output %%i --skip-if-larger
 | 
					 | 
				
			||||||
            for %%i in (*.jpg) do jpegtran -copy none -optimize -perfect %%i %%i
 | 
					 | 
				
			||||||
         *
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var files = Directory.EnumerateFiles(".", "*.png"
 | 
					 | 
				
			||||||
                                           , new EnumerationOptions {
 | 
					 | 
				
			||||||
                                                                        RecurseSubdirectories = true
 | 
					 | 
				
			||||||
                                                                      , AttributesToSkip = FileAttributes.ReparsePoint
 | 
					 | 
				
			||||||
                                                                      , IgnoreInaccessible = true
 | 
					 | 
				
			||||||
                                                                    })
 | 
					 | 
				
			||||||
                             .ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        _ = Parallel.ForEach(files, file => {
 | 
					 | 
				
			||||||
            var startInfo = new ProcessStartInfo {
 | 
					 | 
				
			||||||
                                                     FileName = "pngquant"
 | 
					 | 
				
			||||||
                                                   , Arguments
 | 
					 | 
				
			||||||
                                                         = $"\"{file}\" --force --output \"{file}\" --skip-if-larger"
 | 
					 | 
				
			||||||
                                                 };
 | 
					 | 
				
			||||||
            using var p = Process.Start(startInfo);
 | 
					 | 
				
			||||||
            p!.WaitForExit();
 | 
					 | 
				
			||||||
            Console.WriteLine(p.ExitCode);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        files = _imageExts.SelectMany(x => Directory.EnumerateFiles(
 | 
					 | 
				
			||||||
                                          ".", x
 | 
					 | 
				
			||||||
                                        , new EnumerationOptions {
 | 
					 | 
				
			||||||
                                                                     RecurseSubdirectories = true
 | 
					 | 
				
			||||||
                                                                   , AttributesToSkip      = FileAttributes.ReparsePoint
 | 
					 | 
				
			||||||
                                                                   , IgnoreInaccessible    = true
 | 
					 | 
				
			||||||
                                                                 }))
 | 
					 | 
				
			||||||
                          .ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        _ = Parallel.ForEach(files, file => {
 | 
					 | 
				
			||||||
            var startInfo = new ProcessStartInfo {
 | 
					 | 
				
			||||||
                                                     FileName  = "jpegtran"
 | 
					 | 
				
			||||||
                                                   , Arguments = $"-copy none -optimize -perfect \"{file}\" \"{file}\""
 | 
					 | 
				
			||||||
                                                 };
 | 
					 | 
				
			||||||
            using var p = Process.Start(startInfo);
 | 
					 | 
				
			||||||
            p!.WaitForExit();
 | 
					 | 
				
			||||||
            Console.WriteLine(p.ExitCode);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -3,6 +3,9 @@
 | 
				
			|||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Diagnostics;
 | 
					using System.Diagnostics;
 | 
				
			||||||
using NSExt.Extensions;
 | 
					using NSExt.Extensions;
 | 
				
			||||||
 | 
					#if NET8_0_WINDOWS
 | 
				
			||||||
 | 
					using Microsoft.Win32;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Dot.Git;
 | 
					namespace Dot.Git;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -10,12 +13,31 @@ namespace Dot.Git;
 | 
				
			|||||||
[Localization(typeof(Ln))]
 | 
					[Localization(typeof(Ln))]
 | 
				
			||||||
internal sealed class Main : ToolBase<Option>
 | 
					internal sealed class Main : ToolBase<Option>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    #if NET8_0_WINDOWS
 | 
				
			||||||
 | 
					    private static readonly Regex _regex = new("url = (http.*)");
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
    private Encoding                                               _gitOutputEnc; // git command rsp 编码
 | 
					    private Encoding                                               _gitOutputEnc; // git command rsp 编码
 | 
				
			||||||
    private ConcurrentDictionary<string, StringBuilder>            _repoRsp;      // 仓库信息容器
 | 
					    private ConcurrentDictionary<string, StringBuilder>            _repoRsp;      // 仓库信息容器
 | 
				
			||||||
    private ConcurrentDictionary<string, TaskStatusColumn.Statues> _repoStatus;
 | 
					    private ConcurrentDictionary<string, TaskStatusColumn.Statues> _repoStatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected override Task CoreAsync()
 | 
					    protected override Task CoreAsync()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        #if NET8_0_WINDOWS
 | 
				
			||||||
 | 
					        #pragma warning disable IDE0046
 | 
				
			||||||
 | 
					        if (Opt.InstallRightClickMenu) {
 | 
				
			||||||
 | 
					            #pragma warning restore IDE0046
 | 
				
			||||||
 | 
					            return InstallRightClickMenuAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (Opt.UninstallRightClickMenu) {
 | 
				
			||||||
 | 
					            return UninstallRightClickMenuAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (Opt.OpenGitUrl) {
 | 
				
			||||||
 | 
					            return OpenGitUrlAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return !Directory.Exists(Opt.Path)
 | 
					        return !Directory.Exists(Opt.Path)
 | 
				
			||||||
            ? throw new ArgumentException($"{Ln.指定的路径不存在}: {Opt.Path}", "PATH")
 | 
					            ? throw new ArgumentException($"{Ln.指定的路径不存在}: {Opt.Path}", "PATH")
 | 
				
			||||||
            : CoreInternalAsync();
 | 
					            : CoreInternalAsync();
 | 
				
			||||||
@@ -125,4 +147,36 @@ internal sealed class Main : ToolBase<Option>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        payload.Value.StopTask();
 | 
					        payload.Value.StopTask();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #if NET8_0_WINDOWS
 | 
				
			||||||
 | 
					    #pragma warning disable SA1204
 | 
				
			||||||
 | 
					    private static Task InstallRightClickMenuAsync()
 | 
				
			||||||
 | 
					        #pragma warning restore SA1204
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Registry.SetValue(@"HKEY_CLASSES_ROOT\Directory\shell\OpenGitUrl\command", string.Empty
 | 
				
			||||||
 | 
					                        , @$"""{Environment.ProcessPath}"" git -o ""%1""");
 | 
				
			||||||
 | 
					        Console.WriteLine(Ln.Windows右键菜单已添加);
 | 
				
			||||||
 | 
					        return Task.CompletedTask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static Task UninstallRightClickMenuAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Registry.ClassesRoot.OpenSubKey(@"Directory\shell", true)?.DeleteSubKeyTree("OpenGitUrl", false);
 | 
				
			||||||
 | 
					        Console.WriteLine(Ln.Windows右键菜单已卸载);
 | 
				
			||||||
 | 
					        return Task.CompletedTask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Task OpenGitUrlAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var file = @$"{Opt.Path}\.git\config";
 | 
				
			||||||
 | 
					        if (File.Exists(file)) {
 | 
				
			||||||
 | 
					            var content = File.ReadAllText(file);
 | 
				
			||||||
 | 
					            Console.WriteLine(content);
 | 
				
			||||||
 | 
					            var url = _regex.Match(content).Groups[1].Value;
 | 
				
			||||||
 | 
					            _ = Process.Start("explorer.exe", url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Task.CompletedTask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -28,4 +28,24 @@ internal sealed class Option : OptionBase
 | 
				
			|||||||
    [Localization(typeof(Ln))]
 | 
					    [Localization(typeof(Ln))]
 | 
				
			||||||
    [DefaultValue(".")]
 | 
					    [DefaultValue(".")]
 | 
				
			||||||
    public string Path { get; set; }
 | 
					    public string Path { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #if NET8_0_WINDOWS
 | 
				
			||||||
 | 
					    [CommandOption("-i|--install-right-click-menu")]
 | 
				
			||||||
 | 
					    [Description(nameof(Ln.添加Windows右键菜单))]
 | 
				
			||||||
 | 
					    [Localization(typeof(Ln))]
 | 
				
			||||||
 | 
					    [DefaultValue(false)]
 | 
				
			||||||
 | 
					    public bool InstallRightClickMenu { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CommandOption("-u|--uninstall-right-click-menu")]
 | 
				
			||||||
 | 
					    [Description(nameof(Ln.卸载Windows右键菜单))]
 | 
				
			||||||
 | 
					    [Localization(typeof(Ln))]
 | 
				
			||||||
 | 
					    [DefaultValue(false)]
 | 
				
			||||||
 | 
					    public bool UninstallRightClickMenu { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CommandOption("-o|--open-git-url")]
 | 
				
			||||||
 | 
					    [Description(nameof(Ln.打开Git仓库网址))]
 | 
				
			||||||
 | 
					    [Localization(typeof(Ln))]
 | 
				
			||||||
 | 
					    [DefaultValue(false)]
 | 
				
			||||||
 | 
					    public bool OpenGitUrl { get; set; }
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user