mirror of
https://github.com/nsnail/dot.git
synced 2025-04-14 09:32:49 +08:00
parent
e9d755e7a6
commit
d6fd2b0f9a
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
build
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
packages
|
||||||
|
Migrations
|
||||||
|
_gsdata_
|
||||||
|
_ReSharper*
|
||||||
|
TestResults
|
||||||
|
app_data
|
||||||
|
nuget.config
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.log
|
||||||
|
*.pubxml
|
||||||
|
*.publish.xml
|
||||||
|
.svn
|
||||||
|
.vs
|
||||||
|
*.dbmdl
|
||||||
|
*.jfm
|
||||||
|
*.exe
|
||||||
|
.idea
|
||||||
|
node_modules
|
||||||
|
dist
|
4
.tgitconfig
Normal file
4
.tgitconfig
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[hook "startcommit"]
|
||||||
|
cmdline = code-format.cmd
|
||||||
|
wait = true
|
||||||
|
show = true
|
7
Directory.Build.props
Normal file
7
Directory.Build.props
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<BaseOutputPath>../build/temp/bin</BaseOutputPath>
|
||||||
|
<BaseIntermediateOutputPath>../build/temp/obj</BaseIntermediateOutputPath>
|
||||||
|
<MSBuildProjectExtensionsPath>../build/temp/obj</MSBuildProjectExtensionsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
3
build.ps1
Normal file
3
build.ps1
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dotnet build
|
||||||
|
dotnet publish -c Release -r win-x64 --sc -p:PublishSingleFile=true -o ./build/win-x64
|
||||||
|
rm -r ./build/temp
|
3
code-format.cmd
Normal file
3
code-format.cmd
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dot trim-utf8-bom
|
||||||
|
dot remove-whitespace
|
||||||
|
dot convert-lf
|
22
dot.sln
Normal file
22
dot.sln
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31903.59
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dot", "src\dot.csproj", "{E7608D54-4A3B-4B4B-ADA0-7852987CA21F}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E7608D54-4A3B-4B4B-ADA0-7852987CA21F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E7608D54-4A3B-4B4B-ADA0-7852987CA21F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E7608D54-4A3B-4B4B-ADA0-7852987CA21F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E7608D54-4A3B-4B4B-ADA0-7852987CA21F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
45
dot.sln.DotSettings
Normal file
45
dot.sln.DotSettings
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?>
|
||||||
|
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
|
||||||
|
<TypePattern>
|
||||||
|
<Entry>
|
||||||
|
<Entry.SortBy>
|
||||||
|
<Kind>
|
||||||
|
<Kind.Order>
|
||||||
|
<DeclarationKind>Interface</DeclarationKind>
|
||||||
|
<DeclarationKind>Class</DeclarationKind>
|
||||||
|
<DeclarationKind>Enum</DeclarationKind>
|
||||||
|
<DeclarationKind>Struct</DeclarationKind>
|
||||||
|
<DeclarationKind>Delegate</DeclarationKind>
|
||||||
|
<DeclarationKind>Event</DeclarationKind>
|
||||||
|
<DeclarationKind>Constant</DeclarationKind>
|
||||||
|
<DeclarationKind>Field</DeclarationKind>
|
||||||
|
<DeclarationKind>Property</DeclarationKind>
|
||||||
|
<DeclarationKind>Constructor</DeclarationKind>
|
||||||
|
<DeclarationKind>Destructor</DeclarationKind>
|
||||||
|
<DeclarationKind>Indexer</DeclarationKind>
|
||||||
|
<DeclarationKind>Method</DeclarationKind>
|
||||||
|
</Kind.Order>
|
||||||
|
</Kind>
|
||||||
|
<Access>
|
||||||
|
<Access.Order>
|
||||||
|
<AccessModifier>Private</AccessModifier>
|
||||||
|
<AccessModifier>PrivateProtected</AccessModifier>
|
||||||
|
<AccessModifier>Protected</AccessModifier>
|
||||||
|
<AccessModifier>ProtectedInternal</AccessModifier>
|
||||||
|
<AccessModifier>Internal</AccessModifier>
|
||||||
|
<AccessModifier>Public</AccessModifier>
|
||||||
|
</Access.Order>
|
||||||
|
</Access>
|
||||||
|
<Name />
|
||||||
|
</Entry.SortBy>
|
||||||
|
</Entry>
|
||||||
|
</TypePattern>
|
||||||
|
</Patterns></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue"><Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" /></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||||
|
<s:Boolean x:Key="/Default/ReSpeller/ReSpellerEnabled/@EntryValue">False</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TooWideLocalVariableScope/@EntryIndexedValue">HINT</s:String>
|
||||||
|
</wpf:ResourceDictionary>
|
1
git-clean.ps1
Normal file
1
git-clean.ps1
Normal file
@ -0,0 +1 @@
|
|||||||
|
git reset --hard | git clean -d -fx .
|
41
src/.editorconfig
Normal file
41
src/.editorconfig
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
tab_width = 4
|
||||||
|
|
||||||
|
|
||||||
|
# ReSharper properties
|
||||||
|
resharper_align_linq_query = true
|
||||||
|
resharper_align_multiline_argument = true
|
||||||
|
resharper_align_multiline_array_and_object_initializer = true
|
||||||
|
resharper_align_multiline_binary_patterns = true
|
||||||
|
resharper_align_multiline_calls_chain = true
|
||||||
|
resharper_align_multiline_extends_list = true
|
||||||
|
resharper_align_multiline_parameter = true
|
||||||
|
resharper_align_multiline_property_pattern = true
|
||||||
|
resharper_align_multiline_switch_expression = true
|
||||||
|
resharper_align_multiple_declaration = true
|
||||||
|
resharper_align_multline_type_parameter_constrains = true
|
||||||
|
resharper_align_multline_type_parameter_list = true
|
||||||
|
resharper_align_tuple_components = true
|
||||||
|
resharper_allow_comment_after_lbrace = true
|
||||||
|
resharper_csharp_empty_block_style = together_same_line
|
||||||
|
resharper_csharp_outdent_commas = true
|
||||||
|
resharper_csharp_stick_comment = false
|
||||||
|
resharper_csharp_wrap_before_comma = true
|
||||||
|
resharper_indent_nested_foreach_stmt = true
|
||||||
|
resharper_indent_nested_for_stmt = true
|
||||||
|
resharper_indent_nested_while_stmt = true
|
||||||
|
resharper_indent_preprocessor_if = usual_indent
|
||||||
|
resharper_indent_preprocessor_other = usual_indent
|
||||||
|
resharper_int_align = true
|
||||||
|
resharper_keep_existing_arrangement = false
|
||||||
|
resharper_place_linq_into_on_new_line = false
|
||||||
|
resharper_place_simple_switch_expression_on_single_line = true
|
||||||
|
resharper_wrap_before_eq = true
|
||||||
|
resharper_wrap_chained_method_calls = chop_if_long
|
||||||
|
resharper_wrap_switch_expression = chop_if_long
|
||||||
|
|
||||||
|
# Microsoft .NET properties
|
||||||
|
csharp_indent_braces = false
|
||||||
|
csharp_new_line_before_open_brace = local_functions, methods, types
|
113
src/Convert2Lf/Main.cs
Normal file
113
src/Convert2Lf/Main.cs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Dot.Convert2Lf;
|
||||||
|
|
||||||
|
public sealed class Main : Tool<Option>, IDisposable
|
||||||
|
{
|
||||||
|
private int _breakCnt;
|
||||||
|
private bool _disposed;
|
||||||
|
private static readonly object _lockObj = new();
|
||||||
|
private int _procedCnt;
|
||||||
|
private int _replaceCnt;
|
||||||
|
private ChildProgressBar _step2Bar;
|
||||||
|
private int _totalCnt;
|
||||||
|
public Main(Option opt) : base(opt) { }
|
||||||
|
|
||||||
|
|
||||||
|
~Main()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (_disposed) return;
|
||||||
|
if (disposing) _step2Bar?.Dispose();
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FileHandle(string file)
|
||||||
|
{
|
||||||
|
_step2Bar.Tick();
|
||||||
|
ShowMessage(1, 0, 0);
|
||||||
|
|
||||||
|
var tmpFile = $"{file}.tmp";
|
||||||
|
var isReplaced = false;
|
||||||
|
var isBin = false;
|
||||||
|
int data;
|
||||||
|
|
||||||
|
using (var fsr = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
|
||||||
|
using var fsw = new FileStream(tmpFile, FileMode.OpenOrCreate, FileAccess.Write);
|
||||||
|
|
||||||
|
while ((data = fsr.ReadByte()) != -1) {
|
||||||
|
switch (data) {
|
||||||
|
case 0x0d when fsr.ReadByte() == 0x0a: // crlf windows
|
||||||
|
fsw.WriteByte(0x0a);
|
||||||
|
isReplaced = true;
|
||||||
|
continue;
|
||||||
|
case 0x0d: //cr macos
|
||||||
|
fsw.WriteByte(0x0a);
|
||||||
|
fsr.Seek(-1, SeekOrigin.Current);
|
||||||
|
isReplaced = true;
|
||||||
|
continue;
|
||||||
|
case 0x00 or 0xff: //非文本文件
|
||||||
|
isBin = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fsw.WriteByte((byte)data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isReplaced && !isBin) {
|
||||||
|
MoveFile(tmpFile, file);
|
||||||
|
|
||||||
|
ShowMessage(0, 1, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
File.Delete(tmpFile);
|
||||||
|
ShowMessage(0, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ShowMessage(int procedCnt, int replaceCnt, int breakCnt)
|
||||||
|
{
|
||||||
|
lock (_lockObj) {
|
||||||
|
_procedCnt += procedCnt;
|
||||||
|
_replaceCnt += replaceCnt;
|
||||||
|
_breakCnt += breakCnt;
|
||||||
|
_step2Bar.Message = $"已处理:{_procedCnt}/{_totalCnt},替换:{_replaceCnt},跳过:{_breakCnt}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(Opt.Path)) throw new ArgumentException(nameof(Opt.Path), $"指定的路径“{Opt.Path}”不存在");
|
||||||
|
|
||||||
|
|
||||||
|
using var step1Bar = new IndeterminateProgressBar("查找文件...", DefaultProgressBarOptions);
|
||||||
|
|
||||||
|
|
||||||
|
var fileList = EnumerateFiles(Opt.Path, Opt.Filter);
|
||||||
|
_totalCnt = fileList.Count();
|
||||||
|
|
||||||
|
step1Bar.Message = "查找文件...OK";
|
||||||
|
step1Bar.Finished();
|
||||||
|
|
||||||
|
_step2Bar = step1Bar.Spawn(_totalCnt, string.Empty, DefaultProgressBarOptions);
|
||||||
|
|
||||||
|
Parallel.ForEach(fileList, FileHandle);
|
||||||
|
}
|
||||||
|
}
|
11
src/Convert2Lf/Option.cs
Normal file
11
src/Convert2Lf/Option.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace Dot.Convert2Lf;
|
||||||
|
|
||||||
|
[Verb("convert-lf", HelpText = "换行符转换为lf")]
|
||||||
|
public class Option : IOption
|
||||||
|
{
|
||||||
|
[Option('f', "filter", Required = false, HelpText = "文件通配符", Default = "*.*")]
|
||||||
|
public string Filter { get; set; } //normal options here
|
||||||
|
|
||||||
|
[Option('p', "path", Required = false, HelpText = "要处理的目录路径", Default = ".")]
|
||||||
|
public string Path { get; set; }
|
||||||
|
}
|
2
src/GlobalUsings.cs
Normal file
2
src/GlobalUsings.cs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
global using ShellProgressBar;
|
||||||
|
global using CommandLine;
|
17
src/Guid/Main.cs
Normal file
17
src/Guid/Main.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using TextCopy;
|
||||||
|
|
||||||
|
namespace Dot.Guid;
|
||||||
|
|
||||||
|
public sealed class Main : Tool<Option>
|
||||||
|
{
|
||||||
|
public Main(Option opt) : base(opt) { }
|
||||||
|
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
var guid = System.Guid.NewGuid().ToString();
|
||||||
|
if (Opt.Upper) guid = guid.ToUpper();
|
||||||
|
ClipboardService.SetText(guid);
|
||||||
|
Console.WriteLine($"已复制到剪贴板:{guid}");
|
||||||
|
}
|
||||||
|
}
|
8
src/Guid/Option.cs
Normal file
8
src/Guid/Option.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Dot.Guid;
|
||||||
|
|
||||||
|
[Verb("guid", HelpText = "GUID工具")]
|
||||||
|
public class Option : IOption
|
||||||
|
{
|
||||||
|
[Option('u', "upper", HelpText = "大写", Default = false)]
|
||||||
|
public bool Upper { get; set; } //normal options here
|
||||||
|
}
|
3
src/IOption.cs
Normal file
3
src/IOption.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace Dot;
|
||||||
|
|
||||||
|
public interface IOption { }
|
6
src/ITool.cs
Normal file
6
src/ITool.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Dot;
|
||||||
|
|
||||||
|
public interface ITool
|
||||||
|
{
|
||||||
|
void Run();
|
||||||
|
}
|
32
src/Program.cs
Normal file
32
src/Program.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Dot;
|
||||||
|
|
||||||
|
Type[] LoadVerbs()
|
||||||
|
{
|
||||||
|
return typeof(Program).Assembly.GetTypes()
|
||||||
|
//
|
||||||
|
.Where(x => x.GetCustomAttribute<VerbAttribute>() is not null)
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Run(object args)
|
||||||
|
{
|
||||||
|
var tool = ToolsFactory.Create(args as IOption);
|
||||||
|
tool.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Entry Point
|
||||||
|
|
||||||
|
var types = LoadVerbs();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Parser.Default.ParseArguments(args, types).WithParsed(Run);
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex) {
|
||||||
|
Console.Error.WriteLine(ex.Message);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
66
src/Random/Main.cs
Normal file
66
src/Random/Main.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using NSExt.Extensions;
|
||||||
|
using TextCopy;
|
||||||
|
|
||||||
|
namespace Dot.Random;
|
||||||
|
|
||||||
|
public sealed partial class Main : Tool<Option>
|
||||||
|
{
|
||||||
|
private readonly char[][] _charTable = {
|
||||||
|
"0123456789".ToCharArray() //
|
||||||
|
, "abcdefghijklmnopqrstuvwxyz".ToCharArray()
|
||||||
|
, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()
|
||||||
|
, "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".ToCharArray()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public Main(Option opt) : base(opt) { }
|
||||||
|
|
||||||
|
[GeneratedRegex("[a-z]")]
|
||||||
|
private static partial Regex RegexLowerCaseLetter();
|
||||||
|
|
||||||
|
[GeneratedRegex("\\d")]
|
||||||
|
private static partial Regex RegexNumber();
|
||||||
|
|
||||||
|
[GeneratedRegex("[^\\da-zA-Z]")]
|
||||||
|
private static partial Regex RegexSpecialCharacter();
|
||||||
|
|
||||||
|
[GeneratedRegex("[A-Z]")]
|
||||||
|
private static partial Regex RegexUpperCaseLetter();
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
var pSource = stackalloc char[_charTable.Sum(x => x.Length)];
|
||||||
|
var pDest = stackalloc char[Opt.Length];
|
||||||
|
var sourceLen = 0;
|
||||||
|
|
||||||
|
if (Opt.Type.HasFlag(Option.GenerateTypes.Number))
|
||||||
|
foreach (var c in _charTable[0])
|
||||||
|
*(pSource + sourceLen++) = c;
|
||||||
|
|
||||||
|
|
||||||
|
if (Opt.Type.HasFlag(Option.GenerateTypes.LowerCaseLetter))
|
||||||
|
foreach (var c in _charTable[1])
|
||||||
|
*(pSource + sourceLen++) = c;
|
||||||
|
|
||||||
|
if (Opt.Type.HasFlag(Option.GenerateTypes.UpperCaseLetter))
|
||||||
|
foreach (var c in _charTable[2])
|
||||||
|
*(pSource + sourceLen++) = c;
|
||||||
|
|
||||||
|
|
||||||
|
if (Opt.Type.HasFlag(Option.GenerateTypes.SpecialCharacter))
|
||||||
|
foreach (var c in _charTable[3])
|
||||||
|
*(pSource + sourceLen++) = c;
|
||||||
|
|
||||||
|
|
||||||
|
var randScope = new[] { 0, sourceLen };
|
||||||
|
for (var i = 0; i != Opt.Length; ++i) //
|
||||||
|
*(pDest + i) = *(pSource + randScope.Rand());
|
||||||
|
|
||||||
|
var result = new string(pDest, 0, Opt.Length);
|
||||||
|
ClipboardService.SetText(result);
|
||||||
|
Console.WriteLine($"已复制到剪贴板:{result}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
src/Random/Option.cs
Normal file
21
src/Random/Option.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
namespace Dot.Random;
|
||||||
|
|
||||||
|
[Verb("rand", HelpText = "随机数生成器")]
|
||||||
|
public class Option : IOption
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum GenerateTypes
|
||||||
|
{
|
||||||
|
Number = 1
|
||||||
|
, LowerCaseLetter = 2
|
||||||
|
, UpperCaseLetter = 4
|
||||||
|
, SpecialCharacter = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
[Value(1, MetaName = "长度", Required = true, HelpText = "随机数字长度")]
|
||||||
|
public int Length { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
[Value(0, MetaName = "生成类型", Required = true, HelpText = "BitSet 1:[0-9],2:[a-z],4:[A-Z],8:[ascii.0x21-0x2F]")]
|
||||||
|
public GenerateTypes Type { get; set; }
|
||||||
|
}
|
103
src/RemoveTrailingWhiteSpace/Main.cs
Normal file
103
src/RemoveTrailingWhiteSpace/Main.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using NSExt.Extensions;
|
||||||
|
|
||||||
|
namespace Dot.RemoveTrailingWhiteSpace;
|
||||||
|
|
||||||
|
public sealed class Main : Tool<Option>, IDisposable
|
||||||
|
{
|
||||||
|
private int _breakCnt;
|
||||||
|
private bool _disposed;
|
||||||
|
private static readonly object _lockObj = new();
|
||||||
|
private int _procedCnt;
|
||||||
|
private int _replaceCnt;
|
||||||
|
private ChildProgressBar _step2Bar;
|
||||||
|
private int _totalCnt;
|
||||||
|
public Main(Option opt) : base(opt) { }
|
||||||
|
|
||||||
|
|
||||||
|
~Main()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (_disposed) return;
|
||||||
|
if (disposing) _step2Bar?.Dispose();
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FileHandle(string file)
|
||||||
|
{
|
||||||
|
_step2Bar.Tick();
|
||||||
|
ShowMessage(1, 0, 0);
|
||||||
|
var spacesCnt = 0;
|
||||||
|
|
||||||
|
using var fsr = OpenFileToWrite(file);
|
||||||
|
if (fsr.Length == 0 || (spacesCnt = GetSpacesCnt(fsr)) == 0) {
|
||||||
|
ShowMessage(0, 0, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fsr.Seek(0, SeekOrigin.Begin);
|
||||||
|
if (!fsr.IsTextStream()) return;
|
||||||
|
ShowMessage(0, 1, 0);
|
||||||
|
fsr.SetLength(fsr.Length - spacesCnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetSpacesCnt(Stream fsr)
|
||||||
|
{
|
||||||
|
var trimLen = 0;
|
||||||
|
fsr.Seek(-1, SeekOrigin.End);
|
||||||
|
int data;
|
||||||
|
while ((data = fsr.ReadByte()) != -1)
|
||||||
|
if (new[] { 0x20, 0x0d, 0x0a }.Contains(data)) {
|
||||||
|
++trimLen;
|
||||||
|
if (fsr.Position - 2 < 0) break;
|
||||||
|
fsr.Seek(-2, SeekOrigin.Current);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return trimLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ShowMessage(int procedCnt, int removeCnt, int breakCnt)
|
||||||
|
{
|
||||||
|
lock (_lockObj) {
|
||||||
|
_procedCnt += procedCnt;
|
||||||
|
_replaceCnt += removeCnt;
|
||||||
|
_breakCnt += breakCnt;
|
||||||
|
_step2Bar.Message = $"已处理:{_procedCnt}/{_totalCnt},替换:{_replaceCnt},跳过:{_breakCnt}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(Opt.Path)) throw new ArgumentException(nameof(Opt.Path), $"指定的路径“{Opt.Path}”不存在");
|
||||||
|
|
||||||
|
|
||||||
|
using var step1Bar = new IndeterminateProgressBar("查找文件...", DefaultProgressBarOptions);
|
||||||
|
|
||||||
|
|
||||||
|
var fileList = EnumerateFiles(Opt.Path, Opt.Filter);
|
||||||
|
_totalCnt = fileList.Count();
|
||||||
|
|
||||||
|
step1Bar.Message = "查找文件...OK";
|
||||||
|
step1Bar.Finished();
|
||||||
|
|
||||||
|
_step2Bar = step1Bar.Spawn(_totalCnt, string.Empty, DefaultProgressBarOptions);
|
||||||
|
|
||||||
|
Parallel.ForEach(fileList, FileHandle);
|
||||||
|
}
|
||||||
|
}
|
11
src/RemoveTrailingWhiteSpace/Option.cs
Normal file
11
src/RemoveTrailingWhiteSpace/Option.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace Dot.RemoveTrailingWhiteSpace;
|
||||||
|
|
||||||
|
[Verb("remove-whitespace", HelpText = "移除文件尾部换行和空格")]
|
||||||
|
public class Option : IOption
|
||||||
|
{
|
||||||
|
[Option('f', "filter", Required = false, HelpText = "文件通配符", Default = "*.*")]
|
||||||
|
public string Filter { get; set; } //normal options here
|
||||||
|
|
||||||
|
[Option('p', "path", Required = false, HelpText = "要处理的目录路径", Default = ".")]
|
||||||
|
public string Path { get; set; }
|
||||||
|
}
|
106
src/Text/Main.cs
Normal file
106
src/Text/Main.cs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using NSExt.Extensions;
|
||||||
|
using TextCopy;
|
||||||
|
|
||||||
|
namespace Dot.Text;
|
||||||
|
|
||||||
|
public sealed class Main : Tool<Option>
|
||||||
|
{
|
||||||
|
private ref struct Output
|
||||||
|
{
|
||||||
|
public ReadOnlySpan<char> Base64;
|
||||||
|
public ReadOnlySpan<char> Base64DeCode;
|
||||||
|
public ReadOnlySpan<char> Base64DeCodeHex;
|
||||||
|
public ReadOnlySpan<char> EncodingName;
|
||||||
|
public ReadOnlySpan<char> Hex;
|
||||||
|
public ReadOnlySpan<char> HtmlDecode;
|
||||||
|
public ReadOnlySpan<char> HtmlEncode;
|
||||||
|
public ReadOnlySpan<char> Md5;
|
||||||
|
public ReadOnlySpan<char> OriginText;
|
||||||
|
public ReadOnlySpan<char> Sha1;
|
||||||
|
public ReadOnlySpan<char> Sha256;
|
||||||
|
public ReadOnlySpan<char> Sha512;
|
||||||
|
public ReadOnlySpan<char> UrlDecode;
|
||||||
|
public ReadOnlySpan<char> UrlEncode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Main(Option opt) : base(opt)
|
||||||
|
{
|
||||||
|
if (Opt.Text.NullOrEmpty()) Opt.Text = ClipboardService.GetText();
|
||||||
|
if (Opt.Text.NullOrEmpty()) throw new ArgumentException("输入文本为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Output BuildOutput(string text, Encoding enc)
|
||||||
|
{
|
||||||
|
Output ret;
|
||||||
|
var inputHex = text.Hex(enc);
|
||||||
|
ret.Base64DeCodeHex = ReadOnlySpan<char>.Empty;
|
||||||
|
ret.Base64DeCode = ReadOnlySpan<char>.Empty;
|
||||||
|
ret.EncodingName = enc.EncodingName;
|
||||||
|
ret.OriginText = text;
|
||||||
|
ret.Hex = inputHex.String();
|
||||||
|
ret.Base64 = text.Base64(enc);
|
||||||
|
ret.Md5 = MD5.HashData(inputHex).String();
|
||||||
|
ret.Sha1 = SHA1.HashData(inputHex).String();
|
||||||
|
ret.Sha256 = SHA256.HashData(inputHex).String();
|
||||||
|
ret.Sha512 = SHA512.HashData(inputHex).String();
|
||||||
|
ret.UrlEncode = text.Url();
|
||||||
|
ret.UrlDecode = text.UrlDe();
|
||||||
|
ret.HtmlDecode = text.HtmlDe();
|
||||||
|
ret.HtmlEncode = text.Html();
|
||||||
|
|
||||||
|
|
||||||
|
if (!text.IsBase64String()) return ret;
|
||||||
|
byte[] base64DeHex = null;
|
||||||
|
try {
|
||||||
|
base64DeHex = text.Base64De();
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base64DeHex == null) return ret;
|
||||||
|
ret.Base64DeCodeHex = base64DeHex.String();
|
||||||
|
ret.Base64DeCode = enc.GetString(base64DeHex);
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PrintOutput(Output o)
|
||||||
|
{
|
||||||
|
var outputTemp = $"""
|
||||||
|
origin-text: {o.OriginText}
|
||||||
|
{new string('-', 20)} {o.EncodingName} {new string('-', 30 - o.EncodingName.Length)}
|
||||||
|
hex: {o.Hex}
|
||||||
|
base64: {o.Base64}
|
||||||
|
base64-decode-hex: {o.Base64DeCodeHex}
|
||||||
|
base64-decode: {o.Base64DeCode}
|
||||||
|
md5: {o.Md5}
|
||||||
|
sha1: {o.Sha1}
|
||||||
|
sha256: {o.Sha256}
|
||||||
|
sha512: {o.Sha512}
|
||||||
|
url-encode: {o.UrlEncode}
|
||||||
|
url-decode: {o.UrlDecode}
|
||||||
|
html-encode: {o.HtmlEncode}
|
||||||
|
html-decode: {o.HtmlDecode}
|
||||||
|
""";
|
||||||
|
Console.WriteLine(outputTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
|
var ansi = BuildOutput(Opt.Text, Encoding.GetEncoding("gbk"));
|
||||||
|
var utf8 = BuildOutput(Opt.Text, Encoding.UTF8);
|
||||||
|
var unicodeLittleEndian = BuildOutput(Opt.Text, Encoding.Unicode);
|
||||||
|
var unicodeBigEndian = BuildOutput(Opt.Text, Encoding.BigEndianUnicode);
|
||||||
|
|
||||||
|
|
||||||
|
PrintOutput(ansi);
|
||||||
|
PrintOutput(utf8);
|
||||||
|
PrintOutput(unicodeLittleEndian);
|
||||||
|
PrintOutput(unicodeBigEndian);
|
||||||
|
}
|
||||||
|
}
|
8
src/Text/Option.cs
Normal file
8
src/Text/Option.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Dot.Text;
|
||||||
|
|
||||||
|
[Verb("text", HelpText = "文本编码工具")]
|
||||||
|
public class Option : IOption
|
||||||
|
{
|
||||||
|
[Value(0, MetaName = "文本", HelpText = "要处理的文本,不指定此参数:取剪贴板值")]
|
||||||
|
public string Text { get; set; }
|
||||||
|
}
|
62
src/Tool.cs
Normal file
62
src/Tool.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
namespace Dot;
|
||||||
|
|
||||||
|
public abstract class Tool<TOption> : ITool
|
||||||
|
{
|
||||||
|
protected readonly ProgressBarOptions //
|
||||||
|
DefaultProgressBarOptions = new() {
|
||||||
|
MessageEncodingName = "utf-8"
|
||||||
|
, ProgressBarOnBottom = true
|
||||||
|
, ForegroundColor = ConsoleColor.Yellow
|
||||||
|
, ForegroundColorDone = ConsoleColor.DarkGreen
|
||||||
|
, BackgroundColor = ConsoleColor.DarkGray
|
||||||
|
, BackgroundCharacter = '\u2593'
|
||||||
|
};
|
||||||
|
|
||||||
|
protected virtual TOption Opt { get; set; }
|
||||||
|
|
||||||
|
protected Tool(TOption opt)
|
||||||
|
{
|
||||||
|
Opt = opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static IEnumerable<string> EnumerateFiles(string path, string searchPattern)
|
||||||
|
{
|
||||||
|
var fileList = Directory
|
||||||
|
.EnumerateFiles(path, searchPattern
|
||||||
|
, new EnumerationOptions {
|
||||||
|
RecurseSubdirectories = true
|
||||||
|
, AttributesToSkip = FileAttributes.ReparsePoint
|
||||||
|
})
|
||||||
|
.Where(x => !new[] { ".git", "node_modules" }.Any(
|
||||||
|
y => x.Contains(y, StringComparison.OrdinalIgnoreCase)));
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void MoveFile(string source, string dest)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
File.Move(source, dest, true);
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException) {
|
||||||
|
File.SetAttributes(dest, new FileInfo(dest).Attributes & ~FileAttributes.ReadOnly);
|
||||||
|
File.Move(source, dest, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static FileStream OpenFileToWrite(string file)
|
||||||
|
{
|
||||||
|
FileStream fsr;
|
||||||
|
try {
|
||||||
|
fsr = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException) {
|
||||||
|
File.SetAttributes(file, new FileInfo(file).Attributes & ~FileAttributes.ReadOnly);
|
||||||
|
fsr = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public abstract void Run();
|
||||||
|
}
|
19
src/ToolsFactory.cs
Normal file
19
src/ToolsFactory.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using Dot.TrimUtf8Bom;
|
||||||
|
|
||||||
|
namespace Dot;
|
||||||
|
|
||||||
|
public static class ToolsFactory
|
||||||
|
{
|
||||||
|
public static ITool Create(IOption option)
|
||||||
|
{
|
||||||
|
return option switch {
|
||||||
|
Option o => new Main(o)
|
||||||
|
, Convert2Lf.Option o => new Convert2Lf.Main(o)
|
||||||
|
, RemoveTrailingWhiteSpace.Option o => new RemoveTrailingWhiteSpace.Main(o)
|
||||||
|
, Random.Option o => new Random.Main(o)
|
||||||
|
, Text.Option o => new Text.Main(o)
|
||||||
|
, Guid.Option o => new Guid.Main(o)
|
||||||
|
, _ => throw new ArgumentOutOfRangeException(nameof(option))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
90
src/TrimUtf8Bom/Main.cs
Normal file
90
src/TrimUtf8Bom/Main.cs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Dot.TrimUtf8Bom;
|
||||||
|
|
||||||
|
public sealed class Main : Tool<Option>, IDisposable
|
||||||
|
{
|
||||||
|
private int _breakCnt;
|
||||||
|
private bool _disposed;
|
||||||
|
private static readonly object _lockObj = new();
|
||||||
|
private int _procedCnt;
|
||||||
|
private ChildProgressBar _step2Bar;
|
||||||
|
private int _totalCnt;
|
||||||
|
private int _trimCnt;
|
||||||
|
public Main(Option opt) : base(opt) { }
|
||||||
|
|
||||||
|
|
||||||
|
~Main()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (_disposed) return;
|
||||||
|
if (disposing) _step2Bar?.Dispose();
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ShowMessage(int procedCnt, int replaceCnt, int breakCnt)
|
||||||
|
{
|
||||||
|
lock (_lockObj) {
|
||||||
|
_procedCnt += procedCnt;
|
||||||
|
_trimCnt += replaceCnt;
|
||||||
|
_breakCnt += breakCnt;
|
||||||
|
_step2Bar.Message = $"已处理:{_procedCnt}/{_totalCnt},移除BOM:{_trimCnt},跳过:{_breakCnt}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(Opt.Path)) throw new ArgumentException(nameof(Opt.Path), $"指定的路径“{Opt.Path}”不存在");
|
||||||
|
|
||||||
|
|
||||||
|
var utf8Bom = new byte[] { 0xef, 0xbb, 0xbf };
|
||||||
|
using var step1Bar = new IndeterminateProgressBar("查找文件...", DefaultProgressBarOptions);
|
||||||
|
|
||||||
|
|
||||||
|
var fileList = EnumerateFiles(Opt.Path, Opt.Filter);
|
||||||
|
_totalCnt = fileList.Count();
|
||||||
|
|
||||||
|
step1Bar.Message = "查找文件...OK";
|
||||||
|
step1Bar.Finished();
|
||||||
|
|
||||||
|
_step2Bar = step1Bar.Spawn(_totalCnt, string.Empty, DefaultProgressBarOptions);
|
||||||
|
|
||||||
|
Parallel.ForEach(fileList, file => {
|
||||||
|
_step2Bar.Tick();
|
||||||
|
ShowMessage(1, 0, 0);
|
||||||
|
|
||||||
|
var tmpFile = $"{file}.tmp";
|
||||||
|
var isReplaced = false;
|
||||||
|
using (var fsr = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
|
||||||
|
Span<byte> buffer = stackalloc byte[utf8Bom.Length];
|
||||||
|
var readLen = fsr.Read(buffer);
|
||||||
|
if (readLen == utf8Bom.Length && buffer.SequenceEqual(utf8Bom)) {
|
||||||
|
using var fsw = new FileStream(tmpFile, FileMode.OpenOrCreate, FileAccess.Write);
|
||||||
|
int data;
|
||||||
|
while ((data = fsr.ReadByte()) != -1) fsw.WriteByte((byte)data);
|
||||||
|
isReplaced = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isReplaced) {
|
||||||
|
MoveFile(tmpFile, file);
|
||||||
|
ShowMessage(0, 1, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ShowMessage(0, 0, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
11
src/TrimUtf8Bom/Option.cs
Normal file
11
src/TrimUtf8Bom/Option.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace Dot.TrimUtf8Bom;
|
||||||
|
|
||||||
|
[Verb("trim-utf8-bom", HelpText = "移除文件的uf8 bom")]
|
||||||
|
public class Option : IOption
|
||||||
|
{
|
||||||
|
[Option('f', "filter", Required = false, HelpText = "文件通配符", Default = "*.*")]
|
||||||
|
public string Filter { get; set; } //normal options here
|
||||||
|
|
||||||
|
[Option('p', "path", Required = false, HelpText = "要处理的目录路径", Default = ".")]
|
||||||
|
public string Path { get; set; }
|
||||||
|
}
|
32
src/dot.csproj
Normal file
32
src/dot.csproj
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<RootNamespace>Dot</RootNamespace>
|
||||||
|
<AssemblyName>dot</AssemblyName>
|
||||||
|
<Version>1.0.1</Version>
|
||||||
|
<Authors>nsnail</Authors>
|
||||||
|
<Copyright>Copyright (c) 2022 nsnail</Copyright>
|
||||||
|
<RepositoryUrl>https://github.com/nsnail/dot.git</RepositoryUrl>
|
||||||
|
<RepositoryType>git</RepositoryType>
|
||||||
|
<AssemblyTitle>功能全面的实用工具-程序员的瑞士军刀</AssemblyTitle>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommandLineParser" Version="2.9.1"/>
|
||||||
|
<PackageReference Include="NSExt" Version="1.0.6"/>
|
||||||
|
<PackageReference Include="ShellProgressBar" Version="5.2.0"/>
|
||||||
|
<PackageReference Include="TextCopy" Version="6.2.0"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
Loading…
x
Reference in New Issue
Block a user