├── .gitattributes ├── .github └── workflows │ ├── build.yml │ └── test.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── build.ps1 ├── docs └── Features-2.0.md └── src ├── Configurations.cs ├── Constants.cs ├── Extensions ├── CollectionExtensions.cs ├── FormsExtensions.cs ├── IOExtensions.cs └── SystemExtensions.cs ├── Forms ├── FileSortingInfoGettingWindow.Designer.cs ├── FileSortingInfoGettingWindow.cs ├── FileSortingInfoGettingWindow.resx ├── KeywordEditWindow.Designer.cs ├── KeywordEditWindow.cs ├── KeywordEditWindow.resx ├── KeywordGettingWindow.Designer.cs ├── KeywordGettingWindow.cs ├── KeywordGettingWindow.resx ├── ReleaseAssetDownloadingWindow.Designer.cs ├── ReleaseAssetDownloadingWindow.cs ├── ReleaseAssetDownloadingWindow.resx ├── UpdateCheckerWindow.Designer.cs ├── UpdateCheckerWindow.cs ├── UpdateCheckerWindow.resx ├── WindowMain.Designer.cs ├── WindowMain.cs └── WindowMain.resx ├── Models ├── AssetInfo.cs ├── Configuration{T}.cs ├── Features │ ├── FileSorter.cs │ └── Updater.cs ├── FileSorterConfig.cs ├── FileSortingInfo.cs ├── FormStyleController.cs ├── IReturnableForm.cs ├── Keyword.cs ├── Log.cs ├── Logger.cs ├── PowerControlTask.cs ├── ReleaseInfo.cs ├── Service.cs ├── ServiceCheckBox.cs └── UISettings.cs ├── Program.cs ├── Properties ├── Resources.Designer.cs └── Resources.resx ├── SeewoHelper.csproj ├── SeewoHelper.sln ├── Utilities ├── AutoStartUtilities.cs ├── FolderBrowserDialogUtilities.cs ├── IOUtilities.cs ├── MessageBoxUtilities.cs ├── NetUtilities.cs └── SystemUtilities.cs ├── app.manifest └── favicon.ico /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | paths: 5 | - 'src/**' 6 | 7 | env: 8 | ProjectName: SeewoHelper 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: windows-latest 14 | 15 | env: 16 | NET_TFM: net5.0-windows 17 | Configuration: Release 18 | 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v2 22 | with: 23 | submodules: true 24 | 25 | - name: Setup .NET 26 | uses: actions/setup-dotnet@v1 27 | 28 | - name: Build 29 | shell: pwsh 30 | run: .\build.ps1 31 | 32 | - name: Upload .NET App 33 | continue-on-error: true 34 | if: ${{ !startsWith(github.ref, 'refs/tags/') }} 35 | uses: actions/upload-artifact@v2 36 | with: 37 | name: ${{ env.ProjectName }}-App 38 | path: src\bin\${{ env.Configuration }}\${{ env.NET_TFM }}\publish\ 39 | 40 | - name: Upload x64 41 | continue-on-error: true 42 | if: ${{ !startsWith(github.ref, 'refs/tags/') }} 43 | uses: actions/upload-artifact@v2 44 | with: 45 | name: ${{ env.ProjectName }}-Win64 46 | path: src\bin\${{ env.Configuration }}\${{ env.NET_TFM }}\win-x64\publish\ 47 | 48 | - name: Upload x86 49 | continue-on-error: true 50 | if: ${{ !startsWith(github.ref, 'refs/tags/') }} 51 | uses: actions/upload-artifact@v2 52 | with: 53 | name: ${{ env.ProjectName }}-Win32 54 | path: src\bin\${{ env.Configuration }}\${{ env.NET_TFM }}\win-x86\publish\ 55 | 56 | - name: Package .NET App 57 | if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }} 58 | shell: pwsh 59 | run: | 60 | New-Item -ItemType Directory -Path C:\builtfiles -Force > $null 61 | 7z a -mx9 "C:\builtfiles\$env:ProjectName-App.7z" ".\src\bin\$env:Configuration\$env:NET_TFM\publish\*" 62 | 63 | - name: Package x64 64 | if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }} 65 | shell: pwsh 66 | run: | 67 | New-Item -ItemType Directory -Path C:\builtfiles -Force > $null 68 | 7z a -mx9 "C:\builtfiles\$env:ProjectName-Win64.7z" ".\src\bin\$env:Configuration\$env:NET_TFM\win-x64\publish\*" 69 | 70 | - name: Package x86 71 | if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }} 72 | shell: pwsh 73 | run: | 74 | New-Item -ItemType Directory -Path C:\builtfiles -Force > $null 75 | 7z a -mx9 "C:\builtfiles\$env:ProjectName-Win32.7z" ".\src\bin\$env:Configuration\$env:NET_TFM\win-x86\publish\*" 76 | 77 | - name: Create a new GitHub release if a new tag is pushed 78 | uses: softprops/action-gh-release@v1 79 | if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }} 80 | env: 81 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 82 | with: 83 | prerelease: true 84 | draft: false 85 | files: | 86 | C:\builtfiles\${{ env.ProjectName }}-App.7z 87 | C:\builtfiles\${{ env.ProjectName }}-Win64.7z 88 | C:\builtfiles\${{ env.ProjectName }}-Win32.7z 89 | body: | 90 | ## 更新日志 91 | * 这是 GitHub Action 自动化部署,更新日志将会手动更新。 -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: [pull_request] 3 | 4 | jobs: 5 | build: 6 | 7 | runs-on: windows-latest 8 | 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | 13 | - name: Setup .NET 14 | uses: actions/setup-dotnet@v1 15 | 16 | - name: Restore dependencies 17 | run: dotnet restore 18 | 19 | - name: Build 20 | run: dotnet build --no-restore -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Nuget personal access tokens and Credentials 210 | nuget.config 211 | 212 | # Microsoft Azure Build Output 213 | csx/ 214 | *.build.csdef 215 | 216 | # Microsoft Azure Emulator 217 | ecf/ 218 | rcf/ 219 | 220 | # Windows Store app package directories and files 221 | AppPackages/ 222 | BundleArtifacts/ 223 | Package.StoreAssociation.xml 224 | _pkginfo.txt 225 | *.appx 226 | *.appxbundle 227 | *.appxupload 228 | 229 | # Visual Studio cache files 230 | # files ending in .cache can be ignored 231 | *.[Cc]ache 232 | # but keep track of directories ending in .cache 233 | !?*.[Cc]ache/ 234 | 235 | # Others 236 | ClientBin/ 237 | ~$* 238 | *~ 239 | *.dbmdl 240 | *.dbproj.schemaview 241 | *.jfm 242 | *.pfx 243 | *.publishsettings 244 | orleans.codegen.cs 245 | 246 | # Including strong name files can present a security risk 247 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 248 | #*.snk 249 | 250 | # Since there are multiple workflows, uncomment next line to ignore bower_components 251 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 252 | #bower_components/ 253 | 254 | # RIA/Silverlight projects 255 | Generated_Code/ 256 | 257 | # Backup & report files from converting an old project file 258 | # to a newer Visual Studio version. Backup files are not needed, 259 | # because we have git ;-) 260 | _UpgradeReport_Files/ 261 | Backup*/ 262 | UpgradeLog*.XML 263 | UpgradeLog*.htm 264 | ServiceFabricBackup/ 265 | *.rptproj.bak 266 | 267 | # SQL Server files 268 | *.mdf 269 | *.ldf 270 | *.ndf 271 | 272 | # Business Intelligence projects 273 | *.rdl.data 274 | *.bim.layout 275 | *.bim_*.settings 276 | *.rptproj.rsuser 277 | *- [Bb]ackup.rdl 278 | *- [Bb]ackup ([0-9]).rdl 279 | *- [Bb]ackup ([0-9][0-9]).rdl 280 | 281 | # Microsoft Fakes 282 | FakesAssemblies/ 283 | 284 | # GhostDoc plugin setting file 285 | *.GhostDoc.xml 286 | 287 | # Node.js Tools for Visual Studio 288 | .ntvs_analysis.dat 289 | node_modules/ 290 | 291 | # Visual Studio 6 build log 292 | *.plg 293 | 294 | # Visual Studio 6 workspace options file 295 | *.opt 296 | 297 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 298 | *.vbw 299 | 300 | # Visual Studio LightSwitch build output 301 | **/*.HTMLClient/GeneratedArtifacts 302 | **/*.DesktopClient/GeneratedArtifacts 303 | **/*.DesktopClient/ModelManifest.xml 304 | **/*.Server/GeneratedArtifacts 305 | **/*.Server/ModelManifest.xml 306 | _Pvt_Extensions 307 | 308 | # Paket dependency manager 309 | .paket/paket.exe 310 | paket-files/ 311 | 312 | # FAKE - F# Make 313 | .fake/ 314 | 315 | # CodeRush personal settings 316 | .cr/personal 317 | 318 | # Python Tools for Visual Studio (PTVS) 319 | __pycache__/ 320 | *.pyc 321 | 322 | # Cake - Uncomment if you are using it 323 | # tools/** 324 | # !tools/packages.config 325 | 326 | # Tabs Studio 327 | *.tss 328 | 329 | # Telerik's JustMock configuration file 330 | *.jmconfig 331 | 332 | # BizTalk build output 333 | *.btp.cs 334 | *.btm.cs 335 | *.odx.cs 336 | *.xsd.cs 337 | 338 | # OpenCover UI analysis results 339 | OpenCover/ 340 | 341 | # Azure Stream Analytics local run output 342 | ASALocalRun/ 343 | 344 | # MSBuild Binary and Structured Log 345 | *.binlog 346 | 347 | # NVidia Nsight GPU debugger configuration file 348 | *.nvuser 349 | 350 | # MFractors (Xamarin productivity tool) working folder 351 | .mfractor/ 352 | 353 | # Local History for Visual Studio 354 | .localhistory/ 355 | 356 | # BeatPulse healthcheck temp database 357 | healthchecksdb 358 | 359 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 360 | MigrationBackup/ 361 | 362 | # Ionide (cross platform F# VS Code tools) working folder 363 | .ionide/ 364 | 365 | # Fody - auto-generated XML schema 366 | FodyWeavers.xsd 367 | 368 | # VS Code files for those working on multiple tools 369 | .vscode/* 370 | !.vscode/settings.json 371 | !.vscode/tasks.json 372 | !.vscode/launch.json 373 | !.vscode/extensions.json 374 | *.code-workspace 375 | 376 | # Local History for Visual Studio Code 377 | .history/ 378 | 379 | # Windows Installer files from build outputs 380 | *.cab 381 | *.msi 382 | *.msix 383 | *.msm 384 | *.msp 385 | 386 | # JetBrains Rider 387 | .idea/ 388 | *.sln.iml 389 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "build/DotNetDllPathPatcher"] 2 | path = build/DotNetDllPathPatcher 3 | url = https://github.com/HMBSbige/DotNetDllPathPatcher.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SeewoHelper 2 | 3 | ![GitHub Repo stars](https://img.shields.io/github/stars/Mo-Ink/SeewoHelper?style=social) 4 | ![GitHub watchers](https://img.shields.io/github/watchers/Mo-Ink/SeewoHelper?style=social) 5 | 6 | [![CodeFactor](https://www.codefactor.io/repository/github/mo-ink/seewohelper/badge)](https://www.codefactor.io/repository/github/mo-ink/seewohelper) 7 | [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/Mo-Ink/SeewoHelper/build)](https://github.com/Mo-Ink/SeewoHelper/actions) 8 | [![GitHub all releases](https://img.shields.io/github/downloads/Mo-Ink/SeewoHelper/total?color=green)](https://github.com/Mo-Ink/SeewoHelper/releases) 9 | [![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/Mo-Ink/SeewoHelper)](https://github.com/Mo-Ink/SeewoHelper/releases) 10 | [![GitHub last commit](https://img.shields.io/github/last-commit/Mo-Ink/SeewoHelper)](https://github.com/Mo-Ink/SeewoHelper/commits/main) 11 | 12 | 本项目是一个为**解决管理员在 Seewo 一体机或类似的触摸大屏设备上操作不便**而诞生的**教室多媒体辅助程序** 13 | 14 | **警告:你可能需要物理接触一体机才能部署它,使用本程序可能会对使用者带来安全风险,请谨慎使用!** 15 | 16 | 本项目主要使用 [.NET 5.0](https://dotnet.microsoft.com/download/dotnet/5.0) 实现 , IDE 使用 [Visual Studio 2022](https://visualstudio.microsoft.com/vs/)。 17 | 18 | → **[新版本计划](docs/Features-2.0.md)** ← 19 | ## 特性 20 | 21 | - 可设置开机自动启动 22 | - 可自动更新主程序 23 | - 可配置性 24 | 25 | 本项目制作较为仓促,部分代码实现非常暴力,如有更好的处理方案,请 **发布 Issue** 或 **提交 Pull Request**! 26 | 27 | **欢迎大佬参与开发!** 28 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | param([string]$buildtfm = 'all') 2 | $ErrorActionPreference = 'Stop' 3 | 4 | Write-Host 'dotnet SDK version' 5 | dotnet --version 6 | 7 | $exe = 'SeewoHelper.exe' 8 | $net_tfm = 'net5.0-windows' 9 | $dllpatcher_tfm = 'net5.0' 10 | $configuration = 'Release' 11 | $output_dir = "src\bin\$configuration" 12 | $dllpatcher_dir = "build\DotNetDllPathPatcher" 13 | $dllpatcher_exe = "$dllpatcher_dir\bin\$configuration\$dllpatcher_tfm\DotNetDllPathPatcher.exe" 14 | $proj_path = "src\SeewoHelper.csproj" 15 | 16 | $build = $buildtfm -eq 'all' -or $buildtfm -eq 'app' 17 | $buildX86 = $buildtfm -eq 'all' -or $buildtfm -eq 'x86' 18 | $buildX64 = $buildtfm -eq 'all' -or $buildtfm -eq 'x64' 19 | function Build-App 20 | { 21 | Write-Host 'Building .NET App' 22 | 23 | $outdir = "$output_dir\$net_tfm" 24 | $publishDir = "$outdir\publish" 25 | 26 | Remove-Item $publishDir -Recurse -Force -Confirm:$false -ErrorAction Ignore 27 | 28 | dotnet publish -c $configuration -f $net_tfm $proj_path 29 | if ($LASTEXITCODE) { exit $LASTEXITCODE } 30 | 31 | & $dllpatcher_exe $publishDir\$exe bin 32 | if ($LASTEXITCODE) { exit $LASTEXITCODE } 33 | } 34 | 35 | function Build-SelfContained 36 | { 37 | param([string]$rid) 38 | 39 | Write-Host "Building .NET App SelfContained $rid" 40 | 41 | $outdir = "$output_dir\$net_tfm\$rid" 42 | $publishDir = "$outdir\publish" 43 | 44 | Remove-Item $publishDir -Recurse -Force -Confirm:$false -ErrorAction Ignore 45 | 46 | dotnet publish -c $configuration -f $net_tfm -r $rid --self-contained true -p:PublishTrimmed=false $proj_path 47 | if ($LASTEXITCODE) { exit $LASTEXITCODE } 48 | 49 | & $dllpatcher_exe $publishDir\$exe bin 50 | if ($LASTEXITCODE) { exit $LASTEXITCODE } 51 | } 52 | 53 | dotnet build -c $configuration -f $dllpatcher_tfm $dllpatcher_dir\DotNetDllPathPatcher.csproj 54 | if ($LASTEXITCODE) { exit $LASTEXITCODE } 55 | 56 | if ($build) 57 | { 58 | Build-App 59 | } 60 | 61 | if ($buildX64) 62 | { 63 | Build-SelfContained win-x64 64 | } 65 | 66 | if ($buildX86) 67 | { 68 | Build-SelfContained win-x86 69 | } 70 | -------------------------------------------------------------------------------- /docs/Features-2.0.md: -------------------------------------------------------------------------------- 1 | # SeewoHelper 2.0 2 | 3 | ~~V1还没出就直接V2了是吧~~ 4 | 5 | ## 简介 6 | 在 SeewoHelper 2.0 中,本项目将会**更加精简**,**只保留核心功能**,同时提供**插件管理器**和**插件市场**,使您可以自由的定制您需要的功能。 7 | 8 | ## 特性 9 | 10 | - 新增 插件系统 11 | - 新增 插件市场 12 | - 新增 安装程序 13 | - 移除 桌面整理 14 | - 优化 自动更新 15 | - 迁移至 WPF 16 | - 优化触控和动画效果 17 | - 不再内置 .NET 环境 18 | 19 | **欢迎参与各路神仙参与开发!** 20 | -------------------------------------------------------------------------------- /src/Configurations.cs: -------------------------------------------------------------------------------- 1 | using Sunny.UI; 2 | using System; 3 | using System.IO; 4 | 5 | namespace SeewoHelper 6 | { 7 | public static class Configurations 8 | { 9 | /// 10 | /// 配置 11 | /// 12 | public static readonly Configuration FileSorterConfig = new(Path.Combine(Constants.ConfigurationDirectory, "FileSorterConfig.json"), new(ExtraFileSortingWay.None, Array.Empty())); 13 | 14 | /// 15 | /// 配置 16 | /// 17 | public static readonly Configuration UISettings = new(Path.Combine(Constants.ConfigurationDirectory, "UISettings.json"), new UISettings(UIStyle.Blue, LogLevel.Info, false, false, true, true)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using System.Windows.Forms; 5 | 6 | namespace SeewoHelper 7 | { 8 | /// 9 | /// 用于提供常量 10 | /// 11 | public static class Constants 12 | { 13 | /// 14 | /// 应用名称 15 | /// 16 | public static readonly string AppName = Application.ProductName; 17 | 18 | /// 19 | /// 项目链接 20 | /// 21 | public static readonly string RepositoryLink = "https://github.com/SugarMGP/SeewoHelper"; 22 | 23 | /// 24 | /// SugarMGP Github 主页 25 | /// 26 | public static readonly string SugarLink = "https://github.com/SugarMGP"; 27 | 28 | /// 29 | /// Ricky Github 主页 30 | /// 31 | public static readonly string RickyLink = "https://github.com/ricky8955555"; 32 | 33 | /// 34 | /// 应用版本 35 | /// 36 | public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version; 37 | 38 | /// 39 | /// Releases API 链接 40 | /// 41 | public static readonly string ReleasesLink = "https://api.github.com/repos/SugarMGP/SeewoHelper/releases"; 42 | 43 | /// 44 | /// 应用运行文件夹路径 45 | /// 46 | public static readonly string BaseDirectory = Environment.CurrentDirectory; 47 | 48 | /// 49 | /// 日志路径 50 | /// 51 | public static readonly string LogDirectory = Path.Combine(BaseDirectory, "logs"); 52 | 53 | /// 54 | /// 配置路径 55 | /// 56 | public static readonly string ConfigurationDirectory = Path.Combine(BaseDirectory, "configs"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Extensions/CollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace SeewoHelper 5 | { 6 | /// 7 | /// 提供 命名空间下相关的扩展方法 8 | /// 9 | public static class CollectionExtensions 10 | { 11 | /// 12 | /// 添加元素,并返回所添加的元素 13 | /// 14 | /// 的泛型类型 15 | /// 元素类型 16 | /// 目标集合 17 | /// 元素 18 | /// 所添加的元素 19 | public static TElement AddElement(this ICollection collection, TElement element) 20 | where TElement : TCollection 21 | { 22 | collection.Add(element); 23 | return element; 24 | } 25 | 26 | /// 27 | /// 通过 Value 获取对应 Key 28 | /// 29 | /// Key 类型 30 | /// Value 类型 31 | /// 实例 32 | /// 指定 Value 33 | /// 34 | public static TKey GetKey(this IDictionary dictionary, TValue value) => dictionary.Where(x => x.Value.Equals(value)).Single().Key; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Extensions/FormsExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace SeewoHelper 4 | { 5 | /// 6 | /// 提供 命名空间下相关的扩展方法 7 | /// 8 | public static class FormsExtensions 9 | { 10 | /// 11 | /// 移除所有选中项 12 | /// 13 | /// 集合 14 | public static void Remove(this ListView.SelectedListViewItemCollection collection) 15 | { 16 | foreach (ListViewItem item in collection) 17 | { 18 | item.Remove(); 19 | } 20 | } 21 | 22 | /// 23 | /// 设置文本 24 | /// 若文本为 时显示默认文本并设置 25 | /// 26 | /// 实例 27 | /// 文本 28 | /// 文本为 时显示的默认文本 29 | public static void SetText(this Control control, string text, string nullText) 30 | { 31 | control.Text = text ?? nullText; 32 | control.Enabled = text != null; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Extensions/IOExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | 5 | namespace SeewoHelper 6 | { 7 | /// 8 | /// 提供 命名空间下相关的扩展方法 9 | /// 10 | public static class IOExtensions 11 | { 12 | /// 13 | /// 移动已存在的文件到指定文件路径,并指示若目标已存在是否覆盖 14 | /// 15 | /// 文件信息 16 | /// 目标文件名 17 | /// 是否覆盖 18 | public static void MoveTo(this FileInfo file, string destFileName, bool overwrite) 19 | { 20 | file.CopyTo(destFileName, overwrite); 21 | file.Delete(); 22 | } 23 | 24 | /// 25 | /// 移动已存在的文件夹到指定路径,并指示若目标已存在是否覆盖 26 | /// 27 | /// 目录信息 28 | /// 目标文件夹名 29 | /// 是否覆盖 30 | public static void MoveTo(this DirectoryInfo directory, string destDirName, bool overwrite) 31 | { 32 | if (!Directory.Exists(destDirName)) 33 | { 34 | Directory.CreateDirectory(destDirName); 35 | } 36 | 37 | foreach (var fileSystemInfo in directory.GetFileSystemInfos()) 38 | { 39 | fileSystemInfo.MoveTo(Path.Combine(destDirName, fileSystemInfo.Name), overwrite); 40 | } 41 | 42 | if (!directory.GetFileSystemInfos().Any()) 43 | { 44 | directory.Delete(); 45 | } 46 | } 47 | 48 | /// 49 | /// 移动已存在的文件或文件夹到指定路径,并指示若目标已存在是否覆盖 50 | /// 51 | /// 文件系统信息 52 | /// 目标名称 53 | /// 是否覆盖 54 | public static void MoveTo(this FileSystemInfo fileSystemInfo, string destName, bool overwrite = false) 55 | { 56 | if (fileSystemInfo is FileInfo fileInfo) 57 | { 58 | fileInfo.MoveTo(destName, overwrite); 59 | } 60 | else if (fileSystemInfo is DirectoryInfo directoryInfo) 61 | { 62 | if (Directory.GetParent(destName).FullName == directoryInfo.FullName) 63 | { 64 | throw new InvalidOperationException("目标文件夹的父文件夹为当前文件夹。"); 65 | } 66 | 67 | directoryInfo.MoveTo(destName, overwrite); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Extensions/SystemExtensions.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Utilities; 2 | using System; 3 | 4 | namespace SeewoHelper 5 | { 6 | /// 7 | /// 提供 命名空间下相关的扩展方法 8 | /// 9 | public static class SystemExtensions 10 | { 11 | /// 12 | /// 使用 友好界面显示并在日志记录器中记录异常信息 13 | /// 14 | /// 异常 15 | /// 日志记录器 16 | /// 是否终止程序 17 | public static Exception ShowAndLog(this Exception ex, Logger logger, bool terminating = false) 18 | { 19 | logger.Add(new Log(ex.ToString(), terminating ? LogLevel.Fatal : LogLevel.Error)); 20 | MessageBoxUtilities.ShowError($"程序给你抛出了异常,异常消息:\n{ex.Message}\n详细信息请查看日志,并提交 Issue,有能力的话也可以发 Pull Request 哦"); 21 | 22 | return ex; 23 | } 24 | 25 | public static string NotEmptyOrDefault(this string str) => string.IsNullOrEmpty(str) ? null : str; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Forms/FileSortingInfoGettingWindow.Designer.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace SeewoHelper.Forms 3 | { 4 | partial class FileSortingInfoGettingWindow 5 | { 6 | /// 7 | /// Required designer variable. 8 | /// 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | /// 12 | /// Clean up any resources being used. 13 | /// 14 | /// true if managed resources should be disposed; otherwise, false. 15 | protected override void Dispose(bool disposing) 16 | { 17 | if (disposing && (components != null)) 18 | { 19 | components.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Windows Form Designer generated code 25 | 26 | /// 27 | /// Required method for Designer support - do not modify 28 | /// the contents of this method with the code editor. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | this.tableLayoutPanelButton = new System.Windows.Forms.TableLayoutPanel(); 33 | this.buttonOK = new Sunny.UI.UIButton(); 34 | this.buttonCancel = new Sunny.UI.UIButton(); 35 | this.label1 = new Sunny.UI.UILabel(); 36 | this.label2 = new Sunny.UI.UILabel(); 37 | this.label3 = new Sunny.UI.UILabel(); 38 | this.textBoxName = new Sunny.UI.UITextBox(); 39 | this.textBoxPath = new Sunny.UI.UITextBox(); 40 | this.textBoxKeywords = new Sunny.UI.UITextBox(); 41 | this.buttonGettingPath = new Sunny.UI.UIButton(); 42 | this.buttonEditKeyword = new Sunny.UI.UIButton(); 43 | this.tableLayoutPanelButton.SuspendLayout(); 44 | this.SuspendLayout(); 45 | // 46 | // tableLayoutPanelButton 47 | // 48 | this.tableLayoutPanelButton.ColumnCount = 2; 49 | this.tableLayoutPanelButton.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 50 | this.tableLayoutPanelButton.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 51 | this.tableLayoutPanelButton.Controls.Add(this.buttonOK, 0, 0); 52 | this.tableLayoutPanelButton.Controls.Add(this.buttonCancel, 1, 0); 53 | this.tableLayoutPanelButton.Location = new System.Drawing.Point(690, 143); 54 | this.tableLayoutPanelButton.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 55 | this.tableLayoutPanelButton.Name = "tableLayoutPanelButton"; 56 | this.tableLayoutPanelButton.RowCount = 1; 57 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 58 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 48F)); 59 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 48F)); 60 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 48F)); 61 | this.tableLayoutPanelButton.Size = new System.Drawing.Size(195, 48); 62 | this.tableLayoutPanelButton.TabIndex = 2; 63 | // 64 | // buttonOK 65 | // 66 | this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 67 | | System.Windows.Forms.AnchorStyles.Left) 68 | | System.Windows.Forms.AnchorStyles.Right))); 69 | this.buttonOK.Cursor = System.Windows.Forms.Cursors.Hand; 70 | this.buttonOK.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 71 | this.buttonOK.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 72 | this.buttonOK.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 73 | this.buttonOK.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 74 | this.buttonOK.Location = new System.Drawing.Point(3, 4); 75 | this.buttonOK.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 76 | this.buttonOK.MinimumSize = new System.Drawing.Size(1, 1); 77 | this.buttonOK.Name = "buttonOK"; 78 | this.buttonOK.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 79 | this.buttonOK.Size = new System.Drawing.Size(91, 40); 80 | this.buttonOK.Style = Sunny.UI.UIStyle.Blue; 81 | this.buttonOK.TabIndex = 0; 82 | this.buttonOK.Text = "确定"; 83 | this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); 84 | // 85 | // buttonCancel 86 | // 87 | this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 88 | | System.Windows.Forms.AnchorStyles.Left) 89 | | System.Windows.Forms.AnchorStyles.Right))); 90 | this.buttonCancel.Cursor = System.Windows.Forms.Cursors.Hand; 91 | this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 92 | this.buttonCancel.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 93 | this.buttonCancel.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 94 | this.buttonCancel.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 95 | this.buttonCancel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 96 | this.buttonCancel.Location = new System.Drawing.Point(100, 4); 97 | this.buttonCancel.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 98 | this.buttonCancel.MinimumSize = new System.Drawing.Size(1, 1); 99 | this.buttonCancel.Name = "buttonCancel"; 100 | this.buttonCancel.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 101 | this.buttonCancel.Size = new System.Drawing.Size(92, 40); 102 | this.buttonCancel.Style = Sunny.UI.UIStyle.Blue; 103 | this.buttonCancel.TabIndex = 1; 104 | this.buttonCancel.Text = "取消"; 105 | this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); 106 | // 107 | // label1 108 | // 109 | this.label1.AutoSize = true; 110 | this.label1.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 111 | this.label1.Location = new System.Drawing.Point(3, 50); 112 | this.label1.Name = "label1"; 113 | this.label1.Size = new System.Drawing.Size(48, 19); 114 | this.label1.Style = Sunny.UI.UIStyle.Blue; 115 | this.label1.TabIndex = 6; 116 | this.label1.Text = "名称:"; 117 | this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 118 | // 119 | // label2 120 | // 121 | this.label2.AutoSize = true; 122 | this.label2.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 123 | this.label2.Location = new System.Drawing.Point(3, 82); 124 | this.label2.Name = "label2"; 125 | this.label2.Size = new System.Drawing.Size(74, 19); 126 | this.label2.Style = Sunny.UI.UIStyle.Blue; 127 | this.label2.TabIndex = 7; 128 | this.label2.Text = "指定路径:"; 129 | this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 130 | // 131 | // label3 132 | // 133 | this.label3.AutoSize = true; 134 | this.label3.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 135 | this.label3.Location = new System.Drawing.Point(3, 116); 136 | this.label3.Name = "label3"; 137 | this.label3.Size = new System.Drawing.Size(61, 19); 138 | this.label3.Style = Sunny.UI.UIStyle.Blue; 139 | this.label3.TabIndex = 8; 140 | this.label3.Text = "关键词:"; 141 | this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 142 | // 143 | // textBoxName 144 | // 145 | this.textBoxName.Cursor = System.Windows.Forms.Cursors.IBeam; 146 | this.textBoxName.FillColor = System.Drawing.Color.White; 147 | this.textBoxName.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 148 | this.textBoxName.Location = new System.Drawing.Point(83, 44); 149 | this.textBoxName.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 150 | this.textBoxName.Maximum = 2147483647D; 151 | this.textBoxName.Minimum = -2147483648D; 152 | this.textBoxName.MinimumSize = new System.Drawing.Size(1, 1); 153 | this.textBoxName.Name = "textBoxName"; 154 | this.textBoxName.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); 155 | this.textBoxName.Size = new System.Drawing.Size(815, 25); 156 | this.textBoxName.Style = Sunny.UI.UIStyle.Blue; 157 | this.textBoxName.TabIndex = 9; 158 | // 159 | // textBoxPath 160 | // 161 | this.textBoxPath.Cursor = System.Windows.Forms.Cursors.IBeam; 162 | this.textBoxPath.FillColor = System.Drawing.Color.White; 163 | this.textBoxPath.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 164 | this.textBoxPath.Location = new System.Drawing.Point(83, 76); 165 | this.textBoxPath.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 166 | this.textBoxPath.Maximum = 2147483647D; 167 | this.textBoxPath.Minimum = -2147483648D; 168 | this.textBoxPath.MinimumSize = new System.Drawing.Size(1, 1); 169 | this.textBoxPath.Name = "textBoxPath"; 170 | this.textBoxPath.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); 171 | this.textBoxPath.ReadOnly = true; 172 | this.textBoxPath.Size = new System.Drawing.Size(768, 25); 173 | this.textBoxPath.Style = Sunny.UI.UIStyle.Blue; 174 | this.textBoxPath.TabIndex = 10; 175 | // 176 | // textBoxKeywords 177 | // 178 | this.textBoxKeywords.Cursor = System.Windows.Forms.Cursors.IBeam; 179 | this.textBoxKeywords.FillColor = System.Drawing.Color.White; 180 | this.textBoxKeywords.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 181 | this.textBoxKeywords.Location = new System.Drawing.Point(83, 110); 182 | this.textBoxKeywords.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 183 | this.textBoxKeywords.Maximum = 2147483647D; 184 | this.textBoxKeywords.Minimum = -2147483648D; 185 | this.textBoxKeywords.MinimumSize = new System.Drawing.Size(1, 1); 186 | this.textBoxKeywords.Name = "textBoxKeywords"; 187 | this.textBoxKeywords.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); 188 | this.textBoxKeywords.ReadOnly = true; 189 | this.textBoxKeywords.Size = new System.Drawing.Size(768, 25); 190 | this.textBoxKeywords.Style = Sunny.UI.UIStyle.Blue; 191 | this.textBoxKeywords.TabIndex = 11; 192 | // 193 | // buttonGettingPath 194 | // 195 | this.buttonGettingPath.Cursor = System.Windows.Forms.Cursors.Hand; 196 | this.buttonGettingPath.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 197 | this.buttonGettingPath.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 198 | this.buttonGettingPath.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 199 | this.buttonGettingPath.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 200 | this.buttonGettingPath.Location = new System.Drawing.Point(860, 76); 201 | this.buttonGettingPath.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 202 | this.buttonGettingPath.MinimumSize = new System.Drawing.Size(1, 1); 203 | this.buttonGettingPath.Name = "buttonGettingPath"; 204 | this.buttonGettingPath.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 205 | this.buttonGettingPath.Size = new System.Drawing.Size(38, 24); 206 | this.buttonGettingPath.Style = Sunny.UI.UIStyle.Blue; 207 | this.buttonGettingPath.TabIndex = 12; 208 | this.buttonGettingPath.Text = "..."; 209 | this.buttonGettingPath.Click += new System.EventHandler(this.ButtonGettingPath_Click); 210 | // 211 | // buttonEditKeyword 212 | // 213 | this.buttonEditKeyword.Cursor = System.Windows.Forms.Cursors.Hand; 214 | this.buttonEditKeyword.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 215 | this.buttonEditKeyword.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 216 | this.buttonEditKeyword.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 217 | this.buttonEditKeyword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 218 | this.buttonEditKeyword.Location = new System.Drawing.Point(860, 110); 219 | this.buttonEditKeyword.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 220 | this.buttonEditKeyword.MinimumSize = new System.Drawing.Size(1, 1); 221 | this.buttonEditKeyword.Name = "buttonEditKeyword"; 222 | this.buttonEditKeyword.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 223 | this.buttonEditKeyword.Size = new System.Drawing.Size(38, 24); 224 | this.buttonEditKeyword.Style = Sunny.UI.UIStyle.Blue; 225 | this.buttonEditKeyword.TabIndex = 13; 226 | this.buttonEditKeyword.Text = "编辑"; 227 | this.buttonEditKeyword.Click += new System.EventHandler(this.ButtonEditKeyword_Click); 228 | // 229 | // FileSortingInfoGettingWindow 230 | // 231 | this.AcceptButton = this.buttonOK; 232 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 233 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 234 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 235 | this.CancelButton = this.buttonCancel; 236 | this.ClientSize = new System.Drawing.Size(901, 204); 237 | this.Controls.Add(this.buttonEditKeyword); 238 | this.Controls.Add(this.buttonGettingPath); 239 | this.Controls.Add(this.label1); 240 | this.Controls.Add(this.label2); 241 | this.Controls.Add(this.label3); 242 | this.Controls.Add(this.textBoxName); 243 | this.Controls.Add(this.textBoxPath); 244 | this.Controls.Add(this.textBoxKeywords); 245 | this.Controls.Add(this.tableLayoutPanelButton); 246 | this.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 247 | this.Margin = new System.Windows.Forms.Padding(4); 248 | this.MaximizeBox = false; 249 | this.MinimizeBox = false; 250 | this.Name = "FileSortingInfoGettingWindow"; 251 | this.Style = Sunny.UI.UIStyle.Blue; 252 | this.Text = "添加/编辑文件整理信息"; 253 | this.Load += new System.EventHandler(this.FileSortingInfoGettingWindow_Load); 254 | this.tableLayoutPanelButton.ResumeLayout(false); 255 | this.ResumeLayout(false); 256 | this.PerformLayout(); 257 | 258 | } 259 | 260 | #endregion 261 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanelButton; 262 | private Sunny.UI.UIButton buttonOK; 263 | private Sunny.UI.UIButton buttonCancel; 264 | private Sunny.UI.UILabel label1; 265 | private Sunny.UI.UILabel label2; 266 | private Sunny.UI.UILabel label3; 267 | private Sunny.UI.UITextBox textBoxName; 268 | private Sunny.UI.UITextBox textBoxPath; 269 | private Sunny.UI.UITextBox textBoxKeywords; 270 | private Sunny.UI.UIButton buttonGettingPath; 271 | private Sunny.UI.UIButton buttonEditKeyword; 272 | } 273 | } -------------------------------------------------------------------------------- /src/Forms/FileSortingInfoGettingWindow.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Utilities; 2 | using Sunny.UI; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace SeewoHelper.Forms 8 | { 9 | public partial class FileSortingInfoGettingWindow : UIForm, IReturnableForm 10 | { 11 | private FileSortingInfo _subjectStorageInfo = null; 12 | private List _keywords = new(); 13 | 14 | public FileSortingInfoGettingWindow() 15 | { 16 | InitializeComponent(); 17 | Program.FormStyleController.Initialize(this); 18 | } 19 | 20 | public FileSortingInfo GetResult(FileSortingInfo info = null) 21 | { 22 | if (info != null) 23 | { 24 | textBoxName.Text = info.Name; 25 | textBoxPath.Text = info.Path; 26 | _keywords = info.Keywords; 27 | textBoxKeywords.Text = string.Join(", ", info.Keywords.Select(x => x.Pattern)); 28 | } 29 | 30 | ShowDialog(); 31 | return _subjectStorageInfo; 32 | } 33 | 34 | private void ButtonGettingPath_Click(object sender, EventArgs e) 35 | { 36 | textBoxPath.Text = FolderBrowserDialogUtilities.GetFilePath() ?? textBoxPath.Text; 37 | } 38 | 39 | private void ButtonOK_Click(object sender, EventArgs e) 40 | { 41 | if (SystemUtilities.IsNullOrWhiteSpace(textBoxName.Text, textBoxPath.Text) || !_keywords.Any()) 42 | { 43 | MessageBoxUtilities.ShowError("内容不可为空!"); 44 | } 45 | else if (!(IOUtilities.IsProperPath(textBoxPath.Text) && IOUtilities.GetPathType(textBoxPath.Text) == PathType.Directionary)) 46 | { 47 | MessageBoxUtilities.ShowError("路径不合法!"); 48 | } 49 | else 50 | { 51 | _subjectStorageInfo = new FileSortingInfo(textBoxName.Text, textBoxPath.Text, _keywords); 52 | Close(); 53 | } 54 | } 55 | 56 | private void ButtonCancel_Click(object sender, EventArgs e) 57 | { 58 | Close(); 59 | } 60 | 61 | private void ButtonEditKeyword_Click(object sender, EventArgs e) 62 | { 63 | _keywords = new KeywordEditWindow().GetResult(_keywords); 64 | textBoxKeywords.Text = string.Join(", ", _keywords.Select(x => x.Pattern)); 65 | } 66 | 67 | private void FileSortingInfoGettingWindow_Load(object sender, EventArgs e) 68 | { 69 | Program.Logger.Info($"开始加载 {nameof(FileSortingInfoGettingWindow)}"); 70 | Program.Logger.Info($"{nameof(FileSortingInfoGettingWindow)} 加载完成"); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Forms/FileSortingInfoGettingWindow.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/Forms/KeywordEditWindow.Designer.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace SeewoHelper.Forms 3 | { 4 | partial class KeywordEditWindow 5 | { 6 | /// 7 | /// Required designer variable. 8 | /// 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | /// 12 | /// Clean up any resources being used. 13 | /// 14 | /// true if managed resources should be disposed; otherwise, false. 15 | protected override void Dispose(bool disposing) 16 | { 17 | if (disposing && (components != null)) 18 | { 19 | components.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Windows Form Designer generated code 25 | 26 | /// 27 | /// Required method for Designer support - do not modify 28 | /// the contents of this method with the code editor. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | this.listViewKeywords = new System.Windows.Forms.ListView(); 33 | this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); 34 | this.buttonDelete = new Sunny.UI.UIButton(); 35 | this.buttonAdd = new Sunny.UI.UIButton(); 36 | this.tableLayoutPanelButton = new System.Windows.Forms.TableLayoutPanel(); 37 | this.buttonOK = new Sunny.UI.UIButton(); 38 | this.buttonCancel = new Sunny.UI.UIButton(); 39 | this.tableLayoutPanel.SuspendLayout(); 40 | this.tableLayoutPanelButton.SuspendLayout(); 41 | this.SuspendLayout(); 42 | // 43 | // listViewKeywords 44 | // 45 | this.listViewKeywords.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 46 | | System.Windows.Forms.AnchorStyles.Left))); 47 | this.listViewKeywords.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 48 | this.listViewKeywords.FullRowSelect = true; 49 | this.listViewKeywords.HideSelection = false; 50 | this.listViewKeywords.Location = new System.Drawing.Point(12, 45); 51 | this.listViewKeywords.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 52 | this.listViewKeywords.Name = "listViewKeywords"; 53 | this.listViewKeywords.Size = new System.Drawing.Size(405, 586); 54 | this.listViewKeywords.TabIndex = 0; 55 | this.listViewKeywords.UseCompatibleStateImageBehavior = false; 56 | this.listViewKeywords.View = System.Windows.Forms.View.List; 57 | this.listViewKeywords.DoubleClick += new System.EventHandler(this.ListViewKeywords_DoubleClick); 58 | // 59 | // tableLayoutPanel 60 | // 61 | this.tableLayoutPanel.ColumnCount = 1; 62 | this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); 63 | this.tableLayoutPanel.Controls.Add(this.buttonDelete, 0, 1); 64 | this.tableLayoutPanel.Controls.Add(this.buttonAdd, 0, 0); 65 | this.tableLayoutPanel.Location = new System.Drawing.Point(423, 39); 66 | this.tableLayoutPanel.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 67 | this.tableLayoutPanel.Name = "tableLayoutPanel"; 68 | this.tableLayoutPanel.RowCount = 2; 69 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 70 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 71 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F)); 72 | this.tableLayoutPanel.Size = new System.Drawing.Size(108, 91); 73 | this.tableLayoutPanel.TabIndex = 1; 74 | // 75 | // buttonDelete 76 | // 77 | this.buttonDelete.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); 78 | this.buttonDelete.Cursor = System.Windows.Forms.Cursors.Hand; 79 | this.buttonDelete.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 80 | this.buttonDelete.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 81 | this.buttonDelete.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 82 | this.buttonDelete.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 83 | this.buttonDelete.Location = new System.Drawing.Point(3, 51); 84 | this.buttonDelete.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 85 | this.buttonDelete.MinimumSize = new System.Drawing.Size(1, 1); 86 | this.buttonDelete.Name = "buttonDelete"; 87 | this.buttonDelete.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 88 | this.buttonDelete.Size = new System.Drawing.Size(102, 33); 89 | this.buttonDelete.Style = Sunny.UI.UIStyle.Blue; 90 | this.buttonDelete.TabIndex = 1; 91 | this.buttonDelete.Text = "删除"; 92 | this.buttonDelete.Click += new System.EventHandler(this.ButtonDelete_Click); 93 | // 94 | // buttonAdd 95 | // 96 | this.buttonAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); 97 | this.buttonAdd.Cursor = System.Windows.Forms.Cursors.Hand; 98 | this.buttonAdd.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 99 | this.buttonAdd.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 100 | this.buttonAdd.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 101 | this.buttonAdd.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 102 | this.buttonAdd.Location = new System.Drawing.Point(3, 6); 103 | this.buttonAdd.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 104 | this.buttonAdd.MinimumSize = new System.Drawing.Size(1, 1); 105 | this.buttonAdd.Name = "buttonAdd"; 106 | this.buttonAdd.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 107 | this.buttonAdd.Size = new System.Drawing.Size(102, 32); 108 | this.buttonAdd.Style = Sunny.UI.UIStyle.Blue; 109 | this.buttonAdd.TabIndex = 0; 110 | this.buttonAdd.Text = "新建"; 111 | this.buttonAdd.Click += new System.EventHandler(this.ButtonAdd_Click); 112 | // 113 | // tableLayoutPanelButton 114 | // 115 | this.tableLayoutPanelButton.ColumnCount = 2; 116 | this.tableLayoutPanelButton.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 117 | this.tableLayoutPanelButton.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 118 | this.tableLayoutPanelButton.Controls.Add(this.buttonOK, 0, 0); 119 | this.tableLayoutPanelButton.Controls.Add(this.buttonCancel, 1, 0); 120 | this.tableLayoutPanelButton.Location = new System.Drawing.Point(339, 639); 121 | this.tableLayoutPanelButton.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 122 | this.tableLayoutPanelButton.Name = "tableLayoutPanelButton"; 123 | this.tableLayoutPanelButton.RowCount = 1; 124 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 125 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 46F)); 126 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 46F)); 127 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 46F)); 128 | this.tableLayoutPanelButton.Size = new System.Drawing.Size(195, 50); 129 | this.tableLayoutPanelButton.TabIndex = 3; 130 | // 131 | // buttonOK 132 | // 133 | this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 134 | | System.Windows.Forms.AnchorStyles.Left) 135 | | System.Windows.Forms.AnchorStyles.Right))); 136 | this.buttonOK.Cursor = System.Windows.Forms.Cursors.Hand; 137 | this.buttonOK.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 138 | this.buttonOK.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 139 | this.buttonOK.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 140 | this.buttonOK.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 141 | this.buttonOK.Location = new System.Drawing.Point(3, 4); 142 | this.buttonOK.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 143 | this.buttonOK.MinimumSize = new System.Drawing.Size(1, 1); 144 | this.buttonOK.Name = "buttonOK"; 145 | this.buttonOK.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 146 | this.buttonOK.Size = new System.Drawing.Size(91, 42); 147 | this.buttonOK.Style = Sunny.UI.UIStyle.Blue; 148 | this.buttonOK.TabIndex = 0; 149 | this.buttonOK.Text = "确定"; 150 | this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); 151 | // 152 | // buttonCancel 153 | // 154 | this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 155 | | System.Windows.Forms.AnchorStyles.Left) 156 | | System.Windows.Forms.AnchorStyles.Right))); 157 | this.buttonCancel.Cursor = System.Windows.Forms.Cursors.Hand; 158 | this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 159 | this.buttonCancel.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 160 | this.buttonCancel.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 161 | this.buttonCancel.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 162 | this.buttonCancel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 163 | this.buttonCancel.Location = new System.Drawing.Point(100, 4); 164 | this.buttonCancel.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 165 | this.buttonCancel.MinimumSize = new System.Drawing.Size(1, 1); 166 | this.buttonCancel.Name = "buttonCancel"; 167 | this.buttonCancel.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 168 | this.buttonCancel.Size = new System.Drawing.Size(92, 42); 169 | this.buttonCancel.Style = Sunny.UI.UIStyle.Blue; 170 | this.buttonCancel.TabIndex = 1; 171 | this.buttonCancel.Text = "取消"; 172 | this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); 173 | // 174 | // KeywordEditWindow 175 | // 176 | this.AcceptButton = this.buttonOK; 177 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 178 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 179 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 180 | this.CancelButton = this.buttonCancel; 181 | this.ClientSize = new System.Drawing.Size(540, 700); 182 | this.Controls.Add(this.tableLayoutPanelButton); 183 | this.Controls.Add(this.tableLayoutPanel); 184 | this.Controls.Add(this.listViewKeywords); 185 | this.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 186 | this.Margin = new System.Windows.Forms.Padding(4); 187 | this.MaximizeBox = false; 188 | this.MinimizeBox = false; 189 | this.Name = "KeywordEditWindow"; 190 | this.Style = Sunny.UI.UIStyle.Blue; 191 | this.Text = "编辑关键词"; 192 | this.Load += new System.EventHandler(this.KeywordEditWindow_Load); 193 | this.tableLayoutPanel.ResumeLayout(false); 194 | this.tableLayoutPanelButton.ResumeLayout(false); 195 | this.ResumeLayout(false); 196 | 197 | } 198 | 199 | #endregion 200 | 201 | private System.Windows.Forms.ListView listViewKeywords; 202 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; 203 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanelButton; 204 | private Sunny.UI.UIButton buttonOK; 205 | private Sunny.UI.UIButton buttonCancel; 206 | private Sunny.UI.UIButton buttonDelete; 207 | private Sunny.UI.UIButton buttonAdd; 208 | } 209 | } -------------------------------------------------------------------------------- /src/Forms/KeywordEditWindow.cs: -------------------------------------------------------------------------------- 1 | using Sunny.UI; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows.Forms; 7 | 8 | namespace SeewoHelper.Forms 9 | { 10 | public partial class KeywordEditWindow : UIForm, IReturnableForm, List> 11 | { 12 | private List _keywords; 13 | 14 | public KeywordEditWindow() 15 | { 16 | InitializeComponent(); 17 | Program.FormStyleController.Initialize(this); 18 | } 19 | 20 | public List GetResult(List list) 21 | { 22 | _keywords = list; 23 | listViewKeywords.Items.AddRange(list.Select(x => new ListViewItem(x.Pattern) { Tag = x }).ToArray()); 24 | ShowDialog(); 25 | 26 | return _keywords; 27 | } 28 | 29 | private void ButtonOK_Click(object sender, EventArgs e) 30 | { 31 | _keywords = listViewKeywords.Items.Cast().Select(x => (Keyword)x.Tag).ToList(); 32 | Close(); 33 | } 34 | 35 | private void ButtonCancel_Click(object sender, EventArgs e) 36 | { 37 | Close(); 38 | } 39 | 40 | private void ButtonAdd_Click(object sender, EventArgs e) 41 | { 42 | var keyword = new KeywordGettingWindow().GetResult(); 43 | 44 | if (keyword is not null) 45 | { 46 | listViewKeywords.Items.Add(new ListViewItem(keyword.Pattern) { Tag = keyword }); 47 | } 48 | } 49 | 50 | private void ButtonDelete_Click(object sender, EventArgs e) 51 | { 52 | listViewKeywords.SelectedItems.Remove(); 53 | } 54 | 55 | private void ListViewKeywords_DoubleClick(object sender, EventArgs e) 56 | { 57 | var selectedItem = listViewKeywords.SelectedItems.Cast().SingleOrDefault(); 58 | 59 | if (selectedItem is not null) 60 | { 61 | var keyword = new KeywordGettingWindow().GetResult((Keyword)selectedItem.Tag); 62 | 63 | if (keyword is not null) 64 | { 65 | var item = new ListViewItem(keyword.Pattern) { Tag = keyword }; 66 | listViewKeywords.Items[selectedItem.Index] = item; 67 | } 68 | } 69 | } 70 | 71 | private void KeywordEditWindow_Load(object sender, EventArgs e) 72 | { 73 | Program.Logger.Info($"开始加载 {nameof(KeywordEditWindow)}"); 74 | Program.Logger.Info($"{nameof(KeywordEditWindow)} 加载完成"); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Forms/KeywordEditWindow.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/Forms/KeywordGettingWindow.Designer.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace SeewoHelper.Forms 3 | { 4 | partial class KeywordGettingWindow 5 | { 6 | /// 7 | /// Required designer variable. 8 | /// 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | /// 12 | /// Clean up any resources being used. 13 | /// 14 | /// true if managed resources should be disposed; otherwise, false. 15 | protected override void Dispose(bool disposing) 16 | { 17 | if (disposing && (components != null)) 18 | { 19 | components.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Windows Form Designer generated code 25 | 26 | /// 27 | /// Required method for Designer support - do not modify 28 | /// the contents of this method with the code editor. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); 33 | this.labelMatchingWay = new Sunny.UI.UILabel(); 34 | this.labelPattern = new Sunny.UI.UILabel(); 35 | this.textBoxPattern = new Sunny.UI.UITextBox(); 36 | this.comboBoxMatchingWay = new Sunny.UI.UIComboBox(); 37 | this.tableLayoutPanelButton = new System.Windows.Forms.TableLayoutPanel(); 38 | this.buttonCancel = new Sunny.UI.UIButton(); 39 | this.buttonOK = new Sunny.UI.UIButton(); 40 | this.tableLayoutPanel1.SuspendLayout(); 41 | this.tableLayoutPanelButton.SuspendLayout(); 42 | this.SuspendLayout(); 43 | // 44 | // tableLayoutPanel1 45 | // 46 | this.tableLayoutPanel1.ColumnCount = 2; 47 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10.30928F)); 48 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 89.69072F)); 49 | this.tableLayoutPanel1.Controls.Add(this.labelMatchingWay, 0, 1); 50 | this.tableLayoutPanel1.Controls.Add(this.labelPattern, 0, 0); 51 | this.tableLayoutPanel1.Controls.Add(this.textBoxPattern, 1, 0); 52 | this.tableLayoutPanel1.Controls.Add(this.comboBoxMatchingWay, 1, 1); 53 | this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 39); 54 | this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 55 | this.tableLayoutPanel1.Name = "tableLayoutPanel1"; 56 | this.tableLayoutPanel1.RowCount = 2; 57 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 58 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 59 | this.tableLayoutPanel1.Size = new System.Drawing.Size(780, 72); 60 | this.tableLayoutPanel1.TabIndex = 0; 61 | // 62 | // labelMatchingWay 63 | // 64 | this.labelMatchingWay.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 65 | | System.Windows.Forms.AnchorStyles.Left) 66 | | System.Windows.Forms.AnchorStyles.Right))); 67 | this.labelMatchingWay.AutoSize = true; 68 | this.labelMatchingWay.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 69 | this.labelMatchingWay.Location = new System.Drawing.Point(3, 36); 70 | this.labelMatchingWay.Name = "labelMatchingWay"; 71 | this.labelMatchingWay.Size = new System.Drawing.Size(74, 36); 72 | this.labelMatchingWay.Style = Sunny.UI.UIStyle.Blue; 73 | this.labelMatchingWay.TabIndex = 2; 74 | this.labelMatchingWay.Text = "匹配方式:"; 75 | this.labelMatchingWay.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 76 | // 77 | // labelPattern 78 | // 79 | this.labelPattern.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 80 | | System.Windows.Forms.AnchorStyles.Left) 81 | | System.Windows.Forms.AnchorStyles.Right))); 82 | this.labelPattern.AutoSize = true; 83 | this.labelPattern.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 84 | this.labelPattern.Location = new System.Drawing.Point(3, 0); 85 | this.labelPattern.Name = "labelPattern"; 86 | this.labelPattern.Size = new System.Drawing.Size(74, 36); 87 | this.labelPattern.Style = Sunny.UI.UIStyle.Blue; 88 | this.labelPattern.TabIndex = 1; 89 | this.labelPattern.Text = "关键词:"; 90 | this.labelPattern.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 91 | // 92 | // textBoxPattern 93 | // 94 | this.textBoxPattern.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 95 | | System.Windows.Forms.AnchorStyles.Left) 96 | | System.Windows.Forms.AnchorStyles.Right))); 97 | this.textBoxPattern.Cursor = System.Windows.Forms.Cursors.IBeam; 98 | this.textBoxPattern.FillColor = System.Drawing.Color.White; 99 | this.textBoxPattern.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); 100 | this.textBoxPattern.Location = new System.Drawing.Point(83, 4); 101 | this.textBoxPattern.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 102 | this.textBoxPattern.Maximum = 2147483647D; 103 | this.textBoxPattern.Minimum = -2147483648D; 104 | this.textBoxPattern.MinimumSize = new System.Drawing.Size(1, 1); 105 | this.textBoxPattern.Name = "textBoxPattern"; 106 | this.textBoxPattern.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); 107 | this.textBoxPattern.Size = new System.Drawing.Size(694, 28); 108 | this.textBoxPattern.Style = Sunny.UI.UIStyle.Blue; 109 | this.textBoxPattern.TabIndex = 2; 110 | this.textBoxPattern.TextAlignment = System.Drawing.ContentAlignment.MiddleLeft; 111 | // 112 | // comboBoxMatchingWay 113 | // 114 | this.comboBoxMatchingWay.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 115 | | System.Windows.Forms.AnchorStyles.Left) 116 | | System.Windows.Forms.AnchorStyles.Right))); 117 | this.comboBoxMatchingWay.DropDownStyle = Sunny.UI.UIDropDownStyle.DropDownList; 118 | this.comboBoxMatchingWay.FillColor = System.Drawing.Color.White; 119 | this.comboBoxMatchingWay.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); 120 | this.comboBoxMatchingWay.FormattingEnabled = true; 121 | this.comboBoxMatchingWay.ItemHeight = 30; 122 | this.comboBoxMatchingWay.Items.AddRange(new object[] { 123 | "正常", 124 | "不区分大小写", 125 | "正则表达式"}); 126 | this.comboBoxMatchingWay.Location = new System.Drawing.Point(83, 40); 127 | this.comboBoxMatchingWay.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 128 | this.comboBoxMatchingWay.MinimumSize = new System.Drawing.Size(50, 0); 129 | this.comboBoxMatchingWay.Name = "comboBoxMatchingWay"; 130 | this.comboBoxMatchingWay.Padding = new System.Windows.Forms.Padding(0, 0, 30, 2); 131 | this.comboBoxMatchingWay.Size = new System.Drawing.Size(694, 25); 132 | this.comboBoxMatchingWay.Style = Sunny.UI.UIStyle.Blue; 133 | this.comboBoxMatchingWay.TabIndex = 3; 134 | this.comboBoxMatchingWay.TextAlignment = System.Drawing.ContentAlignment.MiddleLeft; 135 | // 136 | // tableLayoutPanelButton 137 | // 138 | this.tableLayoutPanelButton.ColumnCount = 2; 139 | this.tableLayoutPanelButton.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 140 | this.tableLayoutPanelButton.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 141 | this.tableLayoutPanelButton.Controls.Add(this.buttonCancel, 1, 0); 142 | this.tableLayoutPanelButton.Controls.Add(this.buttonOK, 0, 0); 143 | this.tableLayoutPanelButton.Location = new System.Drawing.Point(573, 112); 144 | this.tableLayoutPanelButton.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 145 | this.tableLayoutPanelButton.Name = "tableLayoutPanelButton"; 146 | this.tableLayoutPanelButton.RowCount = 1; 147 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 148 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 48F)); 149 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 48F)); 150 | this.tableLayoutPanelButton.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 48F)); 151 | this.tableLayoutPanelButton.Size = new System.Drawing.Size(207, 48); 152 | this.tableLayoutPanelButton.TabIndex = 4; 153 | // 154 | // buttonCancel 155 | // 156 | this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 157 | | System.Windows.Forms.AnchorStyles.Left) 158 | | System.Windows.Forms.AnchorStyles.Right))); 159 | this.buttonCancel.Cursor = System.Windows.Forms.Cursors.Hand; 160 | this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 161 | this.buttonCancel.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 162 | this.buttonCancel.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 163 | this.buttonCancel.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 164 | this.buttonCancel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 165 | this.buttonCancel.Location = new System.Drawing.Point(107, 4); 166 | this.buttonCancel.Margin = new System.Windows.Forms.Padding(4); 167 | this.buttonCancel.MinimumSize = new System.Drawing.Size(1, 1); 168 | this.buttonCancel.Name = "buttonCancel"; 169 | this.buttonCancel.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 170 | this.buttonCancel.Size = new System.Drawing.Size(96, 40); 171 | this.buttonCancel.Style = Sunny.UI.UIStyle.Blue; 172 | this.buttonCancel.TabIndex = 1; 173 | this.buttonCancel.Text = "取消"; 174 | this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); 175 | // 176 | // buttonOK 177 | // 178 | this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 179 | | System.Windows.Forms.AnchorStyles.Left) 180 | | System.Windows.Forms.AnchorStyles.Right))); 181 | this.buttonOK.Cursor = System.Windows.Forms.Cursors.Hand; 182 | this.buttonOK.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 183 | this.buttonOK.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 184 | this.buttonOK.Font = new System.Drawing.Font("微软雅黑", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 185 | this.buttonOK.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 186 | this.buttonOK.Location = new System.Drawing.Point(3, 4); 187 | this.buttonOK.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 188 | this.buttonOK.MinimumSize = new System.Drawing.Size(1, 1); 189 | this.buttonOK.Name = "buttonOK"; 190 | this.buttonOK.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 191 | this.buttonOK.Size = new System.Drawing.Size(97, 40); 192 | this.buttonOK.Style = Sunny.UI.UIStyle.Blue; 193 | this.buttonOK.TabIndex = 0; 194 | this.buttonOK.Text = "确定"; 195 | this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); 196 | // 197 | // KeywordGettingWindow 198 | // 199 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 200 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 201 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 202 | this.ClientSize = new System.Drawing.Size(786, 171); 203 | this.Controls.Add(this.tableLayoutPanelButton); 204 | this.Controls.Add(this.tableLayoutPanel1); 205 | this.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 206 | this.Margin = new System.Windows.Forms.Padding(4); 207 | this.MaximizeBox = false; 208 | this.Name = "KeywordGettingWindow"; 209 | this.Style = Sunny.UI.UIStyle.Blue; 210 | this.Text = "修改关键词"; 211 | this.Load += new System.EventHandler(this.KeywordGettingWindow_Load); 212 | this.tableLayoutPanel1.ResumeLayout(false); 213 | this.tableLayoutPanel1.PerformLayout(); 214 | this.tableLayoutPanelButton.ResumeLayout(false); 215 | this.ResumeLayout(false); 216 | 217 | } 218 | 219 | #endregion 220 | 221 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; 222 | private Sunny.UI.UILabel labelMatchingWay; 223 | private Sunny.UI.UILabel labelPattern; 224 | private Sunny.UI.UITextBox textBoxPattern; 225 | private Sunny.UI.UIComboBox comboBoxMatchingWay; 226 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanelButton; 227 | private Sunny.UI.UIButton buttonOK; 228 | private Sunny.UI.UIButton buttonCancel; 229 | } 230 | } -------------------------------------------------------------------------------- /src/Forms/KeywordGettingWindow.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Utilities; 2 | using Sunny.UI; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace SeewoHelper.Forms 7 | { 8 | public partial class KeywordGettingWindow : UIForm, IReturnableForm 9 | { 10 | private Keyword _keyword = null; 11 | 12 | private static readonly Dictionary _keywordMatchingWayDictionary = new() 13 | { 14 | [KeywordMatchingWay.Normal] = "正常", 15 | [KeywordMatchingWay.CaseInsensitive] = "不区分大小写", 16 | [KeywordMatchingWay.Regex] = "正则表达式" 17 | }; 18 | 19 | public KeywordGettingWindow() 20 | { 21 | InitializeComponent(); 22 | Program.FormStyleController.Initialize(this); 23 | } 24 | 25 | public Keyword GetResult(Keyword keyword = null) 26 | { 27 | if (keyword == null) 28 | { 29 | comboBoxMatchingWay.SelectedIndex = 0; 30 | } 31 | else 32 | { 33 | _keyword = keyword; 34 | textBoxPattern.Text = keyword.Pattern; 35 | comboBoxMatchingWay.Text = _keywordMatchingWayDictionary[keyword.MatchingWay]; 36 | } 37 | 38 | ShowDialog(); 39 | return _keyword; 40 | } 41 | 42 | private void ButtonOK_Click(object sender, EventArgs e) 43 | { 44 | if (string.IsNullOrWhiteSpace(textBoxPattern.Text) || comboBoxMatchingWay.SelectedIndex == -1) 45 | { 46 | MessageBoxUtilities.ShowError("内容不可为空!"); 47 | } 48 | else 49 | { 50 | _keyword = new Keyword(textBoxPattern.Text, _keywordMatchingWayDictionary.GetKey(comboBoxMatchingWay.Text)); 51 | Close(); 52 | } 53 | } 54 | 55 | private void ButtonCancel_Click(object sender, EventArgs e) 56 | { 57 | Close(); 58 | } 59 | 60 | private void KeywordGettingWindow_Load(object sender, EventArgs e) 61 | { 62 | Program.Logger.Info($"开始加载 {nameof(KeywordGettingWindow)}"); 63 | Program.Logger.Info($"{nameof(KeywordGettingWindow)} 加载完成"); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Forms/KeywordGettingWindow.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/Forms/ReleaseAssetDownloadingWindow.Designer.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace SeewoHelper.Forms 3 | { 4 | partial class ReleaseAssetDownloadingWindow 5 | { 6 | /// 7 | /// Required designer variable. 8 | /// 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | /// 12 | /// Clean up any resources being used. 13 | /// 14 | /// true if managed resources should be disposed; otherwise, false. 15 | protected override void Dispose(bool disposing) 16 | { 17 | if (disposing && (components != null)) 18 | { 19 | components.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Windows Form Designer generated code 25 | 26 | /// 27 | /// Required method for Designer support - do not modify 28 | /// the contents of this method with the code editor. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | this.listBoxRelease = new Sunny.UI.UIListBox(); 33 | this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); 34 | this.checkBoxFastGit = new Sunny.UI.UICheckBox(); 35 | this.labelVersion = new Sunny.UI.UILabel(); 36 | this.tableLayoutPanel.SuspendLayout(); 37 | this.SuspendLayout(); 38 | // 39 | // listBoxRelease 40 | // 41 | this.listBoxRelease.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 42 | | System.Windows.Forms.AnchorStyles.Left) 43 | | System.Windows.Forms.AnchorStyles.Right))); 44 | this.listBoxRelease.AutoScroll = true; 45 | this.listBoxRelease.FillColor = System.Drawing.Color.White; 46 | this.listBoxRelease.Font = new System.Drawing.Font("微软雅黑", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 47 | this.listBoxRelease.FormatString = ""; 48 | this.listBoxRelease.ItemHeight = 35; 49 | this.listBoxRelease.ItemSelectForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 50 | this.listBoxRelease.Location = new System.Drawing.Point(4, 38); 51 | this.listBoxRelease.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); 52 | this.listBoxRelease.MinimumSize = new System.Drawing.Size(1, 1); 53 | this.listBoxRelease.Name = "listBoxRelease"; 54 | this.listBoxRelease.Padding = new System.Windows.Forms.Padding(2); 55 | this.listBoxRelease.Size = new System.Drawing.Size(300, 330); 56 | this.listBoxRelease.Style = Sunny.UI.UIStyle.Blue; 57 | this.listBoxRelease.TabIndex = 0; 58 | this.listBoxRelease.Text = null; 59 | this.listBoxRelease.TextAlignment = System.Drawing.StringAlignment.Center; 60 | this.listBoxRelease.ItemDoubleClick += new System.EventHandler(this.ListBoxRelease_ItemDoubleClick); 61 | // 62 | // tableLayoutPanel 63 | // 64 | this.tableLayoutPanel.ColumnCount = 1; 65 | this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); 66 | this.tableLayoutPanel.Controls.Add(this.checkBoxFastGit, 0, 2); 67 | this.tableLayoutPanel.Controls.Add(this.listBoxRelease, 0, 1); 68 | this.tableLayoutPanel.Controls.Add(this.labelVersion, 0, 0); 69 | this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; 70 | this.tableLayoutPanel.Location = new System.Drawing.Point(0, 35); 71 | this.tableLayoutPanel.Name = "tableLayoutPanel"; 72 | this.tableLayoutPanel.RowCount = 3; 73 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 8F)); 74 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 82F)); 75 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); 76 | this.tableLayoutPanel.Size = new System.Drawing.Size(308, 415); 77 | this.tableLayoutPanel.TabIndex = 1; 78 | // 79 | // checkBoxFastGit 80 | // 81 | this.checkBoxFastGit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom))); 82 | this.checkBoxFastGit.Checked = true; 83 | this.checkBoxFastGit.Cursor = System.Windows.Forms.Cursors.Hand; 84 | this.checkBoxFastGit.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 85 | this.checkBoxFastGit.Location = new System.Drawing.Point(82, 376); 86 | this.checkBoxFastGit.MinimumSize = new System.Drawing.Size(1, 1); 87 | this.checkBoxFastGit.Name = "checkBoxFastGit"; 88 | this.checkBoxFastGit.Padding = new System.Windows.Forms.Padding(22, 0, 0, 0); 89 | this.checkBoxFastGit.Size = new System.Drawing.Size(144, 36); 90 | this.checkBoxFastGit.Style = Sunny.UI.UIStyle.Blue; 91 | this.checkBoxFastGit.TabIndex = 1; 92 | this.checkBoxFastGit.Text = "使用FastGit加速"; 93 | // 94 | // labelVersion 95 | // 96 | this.labelVersion.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 97 | | System.Windows.Forms.AnchorStyles.Left) 98 | | System.Windows.Forms.AnchorStyles.Right))); 99 | this.labelVersion.AutoSize = true; 100 | this.labelVersion.Font = new System.Drawing.Font("微软雅黑", 13.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); 101 | this.labelVersion.Location = new System.Drawing.Point(3, 0); 102 | this.labelVersion.Name = "labelVersion"; 103 | this.labelVersion.Size = new System.Drawing.Size(302, 33); 104 | this.labelVersion.Style = Sunny.UI.UIStyle.Blue; 105 | this.labelVersion.TabIndex = 2; 106 | this.labelVersion.Text = "当前版本"; 107 | this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 108 | // 109 | // ReleaseAssetDownloadingWindow 110 | // 111 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 112 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 113 | this.ClientSize = new System.Drawing.Size(308, 450); 114 | this.Controls.Add(this.tableLayoutPanel); 115 | this.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 116 | this.MaximizeBox = false; 117 | this.MinimizeBox = false; 118 | this.Name = "ReleaseAssetDownloadingWindow"; 119 | this.Style = Sunny.UI.UIStyle.Blue; 120 | this.Text = "双击Release以下载"; 121 | this.Load += new System.EventHandler(this.UpdateReleaseChooseWindow_Load); 122 | this.tableLayoutPanel.ResumeLayout(false); 123 | this.tableLayoutPanel.PerformLayout(); 124 | this.ResumeLayout(false); 125 | 126 | } 127 | 128 | #endregion 129 | 130 | private Sunny.UI.UIListBox listBoxRelease; 131 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; 132 | private Sunny.UI.UICheckBox checkBoxFastGit; 133 | private Sunny.UI.UILabel labelVersion; 134 | } 135 | } -------------------------------------------------------------------------------- /src/Forms/ReleaseAssetDownloadingWindow.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Utilities; 2 | using Sunny.UI; 3 | using System; 4 | using System.Linq; 5 | 6 | namespace SeewoHelper.Forms 7 | { 8 | public partial class ReleaseAssetDownloadingWindow : UIForm 9 | { 10 | private readonly ReleaseInfo _release; 11 | 12 | public ReleaseAssetDownloadingWindow(ReleaseInfo release) 13 | { 14 | InitializeComponent(); 15 | Program.FormStyleController.Initialize(this); 16 | _release = release; 17 | } 18 | 19 | private void ListBoxRelease_ItemDoubleClick(object sender, EventArgs e) 20 | { 21 | if (checkBoxFastGit.Checked) 22 | { 23 | NetUtilities.Start(_release.Assets[listBoxRelease.SelectedIndex].FastGitUrl); 24 | } 25 | else 26 | { 27 | NetUtilities.Start(_release.Assets[listBoxRelease.SelectedIndex].Url); 28 | } 29 | } 30 | 31 | private void UpdateReleaseChooseWindow_Load(object sender, EventArgs e) 32 | { 33 | Program.Logger.Info($"开始加载 {nameof(ReleaseAssetDownloadingWindow)}"); 34 | labelVersion.Text = "版本:" + _release.Name; 35 | listBoxRelease.Items.AddRange(_release.Assets.Select(x => x.Name).ToArray()); 36 | Program.Logger.Info($"{nameof(ReleaseAssetDownloadingWindow)} 加载完成"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Forms/ReleaseAssetDownloadingWindow.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/Forms/UpdateCheckerWindow.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SeewoHelper.Forms 2 | { 3 | partial class UpdateCheckerWindow 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.ButtonOK = new Sunny.UI.UIButton(); 32 | this.labelTitle = new Sunny.UI.UILabel(); 33 | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); 34 | this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); 35 | this.labelPreRelease = new Sunny.UI.UILabel(); 36 | this.linkLabelRelease = new Sunny.UI.UILinkLabel(); 37 | this.linkLabelPrerelease = new Sunny.UI.UILinkLabel(); 38 | this.labelRelease = new Sunny.UI.UILabel(); 39 | this.ButtonCheckAgain = new Sunny.UI.UIButton(); 40 | this.tableLayoutPanel1.SuspendLayout(); 41 | this.tableLayoutPanel2.SuspendLayout(); 42 | this.SuspendLayout(); 43 | // 44 | // ButtonOK 45 | // 46 | this.ButtonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom))); 47 | this.ButtonOK.Cursor = System.Windows.Forms.Cursors.Hand; 48 | this.ButtonOK.DialogResult = System.Windows.Forms.DialogResult.OK; 49 | this.ButtonOK.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 50 | this.ButtonOK.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 51 | this.ButtonOK.Font = new System.Drawing.Font("微软雅黑", 10.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 52 | this.ButtonOK.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 53 | this.ButtonOK.IsScaled = false; 54 | this.ButtonOK.Location = new System.Drawing.Point(284, 282); 55 | this.ButtonOK.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 56 | this.ButtonOK.MinimumSize = new System.Drawing.Size(1, 1); 57 | this.ButtonOK.Name = "ButtonOK"; 58 | this.ButtonOK.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 59 | this.ButtonOK.Size = new System.Drawing.Size(97, 42); 60 | this.ButtonOK.Style = Sunny.UI.UIStyle.Blue; 61 | this.ButtonOK.TabIndex = 4; 62 | this.ButtonOK.Text = "确定"; 63 | this.ButtonOK.Click += new System.EventHandler(this.ButtonOK_Click); 64 | // 65 | // labelTitle 66 | // 67 | this.labelTitle.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 68 | | System.Windows.Forms.AnchorStyles.Left) 69 | | System.Windows.Forms.AnchorStyles.Right))); 70 | this.labelTitle.AutoSize = true; 71 | this.labelTitle.Font = new System.Drawing.Font("微软雅黑", 26.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); 72 | this.labelTitle.Location = new System.Drawing.Point(3, 0); 73 | this.labelTitle.Name = "labelTitle"; 74 | this.labelTitle.Size = new System.Drawing.Size(384, 82); 75 | this.labelTitle.TabIndex = 2; 76 | this.labelTitle.Text = "检查更新"; 77 | this.labelTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 78 | // 79 | // tableLayoutPanel1 80 | // 81 | this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 82 | | System.Windows.Forms.AnchorStyles.Left) 83 | | System.Windows.Forms.AnchorStyles.Right))); 84 | this.tableLayoutPanel1.ColumnCount = 1; 85 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); 86 | this.tableLayoutPanel1.Controls.Add(this.labelTitle, 0, 0); 87 | this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 1); 88 | this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 39); 89 | this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 90 | this.tableLayoutPanel1.Name = "tableLayoutPanel1"; 91 | this.tableLayoutPanel1.RowCount = 2; 92 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 35F)); 93 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 65F)); 94 | this.tableLayoutPanel1.Size = new System.Drawing.Size(390, 235); 95 | this.tableLayoutPanel1.TabIndex = 0; 96 | // 97 | // tableLayoutPanel2 98 | // 99 | this.tableLayoutPanel2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 100 | | System.Windows.Forms.AnchorStyles.Left) 101 | | System.Windows.Forms.AnchorStyles.Right))); 102 | this.tableLayoutPanel2.ColumnCount = 2; 103 | this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 104 | this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 105 | this.tableLayoutPanel2.Controls.Add(this.labelPreRelease, 0, 1); 106 | this.tableLayoutPanel2.Controls.Add(this.linkLabelRelease, 1, 0); 107 | this.tableLayoutPanel2.Controls.Add(this.linkLabelPrerelease, 1, 1); 108 | this.tableLayoutPanel2.Controls.Add(this.labelRelease, 0, 0); 109 | this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 86); 110 | this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 111 | this.tableLayoutPanel2.Name = "tableLayoutPanel2"; 112 | this.tableLayoutPanel2.RowCount = 2; 113 | this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 114 | this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 115 | this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 19F)); 116 | this.tableLayoutPanel2.Size = new System.Drawing.Size(384, 145); 117 | this.tableLayoutPanel2.TabIndex = 3; 118 | // 119 | // labelPreRelease 120 | // 121 | this.labelPreRelease.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 122 | | System.Windows.Forms.AnchorStyles.Left) 123 | | System.Windows.Forms.AnchorStyles.Right))); 124 | this.labelPreRelease.AutoSize = true; 125 | this.labelPreRelease.Font = new System.Drawing.Font("微软雅黑", 17F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 126 | this.labelPreRelease.Location = new System.Drawing.Point(3, 72); 127 | this.labelPreRelease.Name = "labelPreRelease"; 128 | this.labelPreRelease.Size = new System.Drawing.Size(186, 73); 129 | this.labelPreRelease.Style = Sunny.UI.UIStyle.Blue; 130 | this.labelPreRelease.TabIndex = 1; 131 | this.labelPreRelease.Text = "最新开发版:"; 132 | this.labelPreRelease.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 133 | // 134 | // linkLabelRelease 135 | // 136 | this.linkLabelRelease.ActiveLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(155)))), ((int)(((byte)(40))))); 137 | this.linkLabelRelease.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 138 | | System.Windows.Forms.AnchorStyles.Left) 139 | | System.Windows.Forms.AnchorStyles.Right))); 140 | this.linkLabelRelease.AutoSize = true; 141 | this.linkLabelRelease.DisabledLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); 142 | this.linkLabelRelease.Enabled = false; 143 | this.linkLabelRelease.Font = new System.Drawing.Font("微软雅黑", 16F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); 144 | this.linkLabelRelease.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48))))); 145 | this.linkLabelRelease.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline; 146 | this.linkLabelRelease.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48))))); 147 | this.linkLabelRelease.Location = new System.Drawing.Point(195, 0); 148 | this.linkLabelRelease.Name = "linkLabelRelease"; 149 | this.linkLabelRelease.Size = new System.Drawing.Size(186, 72); 150 | this.linkLabelRelease.Style = Sunny.UI.UIStyle.Blue; 151 | this.linkLabelRelease.TabIndex = 2; 152 | this.linkLabelRelease.TabStop = true; 153 | this.linkLabelRelease.Text = "检测中……"; 154 | this.linkLabelRelease.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 155 | this.linkLabelRelease.UseCompatibleTextRendering = true; 156 | this.linkLabelRelease.VisitedLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(80)))), ((int)(((byte)(80))))); 157 | this.linkLabelRelease.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelRelease_LinkClicked); 158 | // 159 | // linkLabelPrerelease 160 | // 161 | this.linkLabelPrerelease.ActiveLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(155)))), ((int)(((byte)(40))))); 162 | this.linkLabelPrerelease.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 163 | | System.Windows.Forms.AnchorStyles.Left) 164 | | System.Windows.Forms.AnchorStyles.Right))); 165 | this.linkLabelPrerelease.AutoSize = true; 166 | this.linkLabelPrerelease.DisabledLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); 167 | this.linkLabelPrerelease.Enabled = false; 168 | this.linkLabelPrerelease.Font = new System.Drawing.Font("微软雅黑", 16F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); 169 | this.linkLabelPrerelease.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48))))); 170 | this.linkLabelPrerelease.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline; 171 | this.linkLabelPrerelease.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48))))); 172 | this.linkLabelPrerelease.Location = new System.Drawing.Point(195, 72); 173 | this.linkLabelPrerelease.Name = "linkLabelPrerelease"; 174 | this.linkLabelPrerelease.Size = new System.Drawing.Size(186, 73); 175 | this.linkLabelPrerelease.Style = Sunny.UI.UIStyle.Blue; 176 | this.linkLabelPrerelease.TabIndex = 3; 177 | this.linkLabelPrerelease.TabStop = true; 178 | this.linkLabelPrerelease.Text = "检测中……"; 179 | this.linkLabelPrerelease.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 180 | this.linkLabelPrerelease.UseCompatibleTextRendering = true; 181 | this.linkLabelPrerelease.VisitedLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(80)))), ((int)(((byte)(80))))); 182 | this.linkLabelPrerelease.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelPreRelease_LinkClicked); 183 | // 184 | // labelRelease 185 | // 186 | this.labelRelease.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 187 | | System.Windows.Forms.AnchorStyles.Left) 188 | | System.Windows.Forms.AnchorStyles.Right))); 189 | this.labelRelease.AutoSize = true; 190 | this.labelRelease.Font = new System.Drawing.Font("微软雅黑", 17F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 191 | this.labelRelease.Location = new System.Drawing.Point(3, 0); 192 | this.labelRelease.Name = "labelRelease"; 193 | this.labelRelease.Size = new System.Drawing.Size(186, 72); 194 | this.labelRelease.Style = Sunny.UI.UIStyle.Blue; 195 | this.labelRelease.TabIndex = 0; 196 | this.labelRelease.Text = "最新正式版:"; 197 | this.labelRelease.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 198 | // 199 | // ButtonCheckAgain 200 | // 201 | this.ButtonCheckAgain.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom))); 202 | this.ButtonCheckAgain.Cursor = System.Windows.Forms.Cursors.Hand; 203 | this.ButtonCheckAgain.DialogResult = System.Windows.Forms.DialogResult.OK; 204 | this.ButtonCheckAgain.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 205 | this.ButtonCheckAgain.FillHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 206 | this.ButtonCheckAgain.Font = new System.Drawing.Font("微软雅黑", 10.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 207 | this.ButtonCheckAgain.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 208 | this.ButtonCheckAgain.IsScaled = false; 209 | this.ButtonCheckAgain.Location = new System.Drawing.Point(170, 282); 210 | this.ButtonCheckAgain.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 211 | this.ButtonCheckAgain.MinimumSize = new System.Drawing.Size(1, 1); 212 | this.ButtonCheckAgain.Name = "ButtonCheckAgain"; 213 | this.ButtonCheckAgain.RectHoverColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255))))); 214 | this.ButtonCheckAgain.Size = new System.Drawing.Size(108, 42); 215 | this.ButtonCheckAgain.Style = Sunny.UI.UIStyle.Blue; 216 | this.ButtonCheckAgain.TabIndex = 5; 217 | this.ButtonCheckAgain.Text = "重新检测"; 218 | this.ButtonCheckAgain.Click += new System.EventHandler(this.ButtonCheckAgain_Click); 219 | // 220 | // UpdateCheckerWindow 221 | // 222 | this.AcceptButton = this.ButtonOK; 223 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 224 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 225 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255))))); 226 | this.CancelButton = this.ButtonOK; 227 | this.ClientSize = new System.Drawing.Size(396, 338); 228 | this.Controls.Add(this.ButtonCheckAgain); 229 | this.Controls.Add(this.ButtonOK); 230 | this.Controls.Add(this.tableLayoutPanel1); 231 | this.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 232 | this.Margin = new System.Windows.Forms.Padding(4); 233 | this.MaximizeBox = false; 234 | this.MinimizeBox = false; 235 | this.Name = "UpdateCheckerWindow"; 236 | this.Style = Sunny.UI.UIStyle.Blue; 237 | this.Text = "检查更新"; 238 | this.Load += new System.EventHandler(this.UpgradeWindow_Load); 239 | this.tableLayoutPanel1.ResumeLayout(false); 240 | this.tableLayoutPanel1.PerformLayout(); 241 | this.tableLayoutPanel2.ResumeLayout(false); 242 | this.tableLayoutPanel2.PerformLayout(); 243 | this.ResumeLayout(false); 244 | 245 | } 246 | 247 | #endregion 248 | private Sunny.UI.UIButton ButtonOK; 249 | private Sunny.UI.UILabel labelTitle; 250 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; 251 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; 252 | private Sunny.UI.UILabel labelRelease; 253 | private Sunny.UI.UILabel labelPreRelease; 254 | private Sunny.UI.UILinkLabel linkLabelRelease; 255 | private Sunny.UI.UILinkLabel linkLabelPrerelease; 256 | private Sunny.UI.UIButton ButtonCheckAgain; 257 | } 258 | } -------------------------------------------------------------------------------- /src/Forms/UpdateCheckerWindow.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Features; 2 | using Sunny.UI; 3 | using System; 4 | using System.Windows.Forms; 5 | 6 | namespace SeewoHelper.Forms 7 | { 8 | public partial class UpdateCheckerWindow : UIForm 9 | { 10 | private readonly Updater _updater = new(); 11 | private bool _isChecking = false; 12 | 13 | public UpdateCheckerWindow() 14 | { 15 | InitializeComponent(); 16 | Program.FormStyleController.Initialize(this); 17 | } 18 | 19 | private void ButtonOK_Click(object sender, EventArgs e) 20 | { 21 | Close(); 22 | } 23 | 24 | private void UpgradeWindow_Load(object sender, EventArgs e) 25 | { 26 | Program.Logger.Info($"开始加载 {nameof(UpdateCheckerWindow)}"); 27 | 28 | CheckUpdate(); 29 | 30 | Program.Logger.Info($"{nameof(UpdateCheckerWindow)} 加载完成"); 31 | } 32 | 33 | private void LinkLabelRelease_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 34 | { 35 | new ReleaseAssetDownloadingWindow(_updater.Release).ShowDialog(); 36 | } 37 | 38 | private void LinkLabelPreRelease_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 39 | { 40 | new ReleaseAssetDownloadingWindow(_updater.Prerelease).ShowDialog(); 41 | } 42 | 43 | private void ButtonCheckAgain_Click(object sender, EventArgs e) 44 | { 45 | if (!_isChecking) 46 | { 47 | CheckUpdate(); 48 | } 49 | } 50 | 51 | private async void CheckUpdate() 52 | { 53 | _isChecking = true; 54 | linkLabelPrerelease.SetText(null, "检测中……"); 55 | linkLabelRelease.SetText(null, "检测中……"); 56 | await _updater.GetInfo(); 57 | linkLabelPrerelease.SetText(_updater.Prerelease?.Name, "暂无"); 58 | linkLabelRelease.SetText(_updater.Release?.Name, "暂无"); 59 | _isChecking = false; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Forms/UpdateCheckerWindow.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/Forms/WindowMain.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Features; 2 | using SeewoHelper.Utilities; 3 | using Sunny.UI; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace SeewoHelper.Forms 12 | { 13 | public partial class WindowMain : UIForm 14 | { 15 | private PowerControlTask _powerControlTask; 16 | 17 | private static readonly Dictionary _extraFileSortingWayDictionary = new() 18 | { 19 | [ExtraFileSortingWay.None] = "不进行操作", 20 | [ExtraFileSortingWay.Delete] = "删除" 21 | }; 22 | 23 | public WindowMain() 24 | { 25 | InitializeComponent(); 26 | Program.HandleCreated += Program_HandleCreated; 27 | Program.FormStyleController.Initialize(this); 28 | } 29 | 30 | private void Program_HandleCreated(object sender, EventArgs e) 31 | { 32 | Invoke(new MethodInvoker(ShowWindow)); 33 | } 34 | 35 | private void ButtonSubjectInfoRemove_Click(object sender, EventArgs e) 36 | { 37 | listViewFileSortingInfos.SelectedItems.Remove(); 38 | UpdateSubjectStorageInfoConfig(); 39 | } 40 | 41 | private void ButtonSubjectStorageInfoAdd_Click(object sender, EventArgs e) 42 | { 43 | var info = new FileSortingInfoGettingWindow().GetResult(); 44 | 45 | if (info is not null) 46 | { 47 | AddSubjectStorageInfoToList(info); 48 | } 49 | } 50 | 51 | private void AddSubjectStorageInfoToList(FileSortingInfo info) 52 | { 53 | var item = new ListViewItem(new string[] { info.Name, info.Path, string.Join(", ", info.Keywords.Select(x => x.Pattern)) }) { Tag = info }; 54 | listViewFileSortingInfos.Items.Add(item); 55 | UpdateSubjectStorageInfoConfig(); 56 | } 57 | 58 | private void ListViewSubjectStorageInfos_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e) 59 | { 60 | e.Cancel = true; 61 | e.NewWidth = listViewFileSortingInfos.Columns[e.ColumnIndex].Width; 62 | } 63 | 64 | private async void ButtonStartFileSorting_Click(object sender, EventArgs e) 65 | { 66 | var infos = listViewFileSortingInfos.Items.Cast().Select(x => (FileSortingInfo)x.Tag); 67 | 68 | foreach (var info in infos) 69 | { 70 | Directory.CreateDirectory(info.Path); 71 | } 72 | 73 | var sorter = new FileSorter(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), infos); 74 | await sorter.SortMore(); 75 | 76 | await sorter.SortExtraFiles(_extraFileSortingWayDictionary.GetKey((string)comboBoxExtraFileSortingWay.SelectedItem)); 77 | 78 | MessageBoxUtilities.ShowSuccess("已完成!"); 79 | } 80 | 81 | private void WindowMain_Load(object sender, EventArgs e) 82 | { 83 | Program.Logger.Info($"开始加载 {nameof(WindowMain)}"); 84 | 85 | LoadSubjectStorageInfoConfig(); 86 | LoadLoggerConfig(); 87 | CreateServiceCheckBox(); 88 | LoadComboBoxStyle(); 89 | LoadComboBoxExtraFileSortingWay(); 90 | LoadComboBoxLogLevel(); 91 | LoadAutoCheckUpdate(); 92 | LoadHideWhenStart(); 93 | 94 | checkBoxDoubleClickNotify.Checked = Configurations.UISettings.Content.IsDoubleClickNotify; 95 | checkBoxAutoStart.Checked = AutoStartUtilities.IsAutoStart(); 96 | checkBoxHideToNotify.Checked = Configurations.UISettings.Content.IsHideToNotify; 97 | 98 | Program.Logger.Info($"{nameof(WindowMain)} 加载完成"); 99 | } 100 | 101 | private void LoadComboBoxExtraFileSortingWay() 102 | { 103 | comboBoxExtraFileSortingWay.Items.AddRange(_extraFileSortingWayDictionary.Values.ToArray()); 104 | comboBoxExtraFileSortingWay.SelectedItem = _extraFileSortingWayDictionary[Configurations.FileSorterConfig.Content.ExtraFileSortingWay]; 105 | } 106 | 107 | private void LoadHideWhenStart() 108 | { 109 | bool isHideWhenStart = Configurations.UISettings.Content.IsHideWhenStart; 110 | 111 | checkBoxHideWhenStart.Checked = isHideWhenStart; 112 | 113 | if (isHideWhenStart) 114 | { 115 | HideWindow(); 116 | } 117 | } 118 | 119 | private async void LoadAutoCheckUpdate() 120 | { 121 | bool isAutoCheckUpdate = Configurations.UISettings.Content.IsAutoCheckUpdate; 122 | 123 | checkBoxAutoCheckUpdate.Checked = isAutoCheckUpdate; 124 | 125 | if (isAutoCheckUpdate) 126 | { 127 | await Task.Delay(1000); 128 | new UpdateCheckerWindow().Show(); 129 | } 130 | } 131 | 132 | private void CreateServiceCheckBox() 133 | { 134 | checkBoxDisableServiceShellHardwareDetection.Tag = new ServiceCheckBox(checkBoxDisableServiceShellHardwareDetection, "ShellHWDetection", true) { PreAction = () => Cursor = Cursors.WaitCursor, PostAction = () => Cursor = Cursors.Default }; 135 | checkBoxDisableServiceWindowsUpdate.Tag = new ServiceCheckBox(checkBoxDisableServiceWindowsUpdate, "wuauserv", true) { PreAction = () => Cursor = Cursors.WaitCursor, PostAction = () => Cursor = Cursors.Default }; 136 | checkBoxDisableServiceWindowsSearch.Tag = new ServiceCheckBox(checkBoxDisableServiceWindowsSearch, "WSearch", true) { PreAction = () => Cursor = Cursors.WaitCursor, PostAction = () => Cursor = Cursors.Default }; 137 | } 138 | 139 | private void LoadComboBoxStyle() 140 | { 141 | comboBoxStyle.Items.AddRange(Enum.GetValues().SkipWhile(x => x == UIStyle.Custom).Cast().ToArray()); 142 | comboBoxStyle.SelectedItem = Program.FormStyleController.CurrentStyle; 143 | } 144 | 145 | private void LoadComboBoxLogLevel() 146 | { 147 | comboBoxLogLevel.Items.AddRange(Enum.GetValues().Cast().ToArray()); 148 | comboBoxLogLevel.SelectedItem = Configurations.UISettings.Content.LogLevel; 149 | } 150 | 151 | private void LoadLoggerConfig() 152 | { 153 | UpdateLoggerElement(); 154 | Program.Logger.CollectionChanged += (sender, e) => UpdateLoggerElement(); 155 | } 156 | 157 | private void UpdateLoggerElement() 158 | { 159 | textBoxLogs.Invoke(new MethodInvoker(() => textBoxLogs.Text = Program.Logger.ToString(Configurations.UISettings.Content.LogLevel))); 160 | } 161 | 162 | private void ListViewSubjectStorageInfos_DoubleClick(object sender, EventArgs e) 163 | { 164 | var selectedItem = listViewFileSortingInfos.SelectedItems.Cast().SingleOrDefault(); 165 | 166 | if (selectedItem is not null) 167 | { 168 | var info = new FileSortingInfoGettingWindow().GetResult((FileSortingInfo)selectedItem.Tag); 169 | 170 | if (info is not null) 171 | { 172 | var item = new ListViewItem(new string[] { info.Name, info.Path, string.Join(", ", info.Keywords.Select(x => x.Pattern)) }) { Tag = info }; 173 | listViewFileSortingInfos.Items[selectedItem.Index] = item; 174 | } 175 | } 176 | } 177 | 178 | private void WindowMain_FormClosing(object sender, FormClosingEventArgs e) 179 | { 180 | if (Configurations.UISettings.Content.IsHideToNotify && e.CloseReason == CloseReason.UserClosing) 181 | { 182 | e.Cancel = true; 183 | HideWindow(); 184 | } 185 | } 186 | 187 | private void UpdateSubjectStorageInfoConfig() 188 | { 189 | var infos = listViewFileSortingInfos.Items.Cast().Select(x => (FileSortingInfo)x.Tag); 190 | Configurations.FileSorterConfig.Content = Configurations.FileSorterConfig.Content with { FileSortingInfos = infos.ToArray() }; 191 | Configurations.FileSorterConfig.Save(); 192 | } 193 | 194 | private void LoadSubjectStorageInfoConfig() 195 | { 196 | var info = Configurations.FileSorterConfig.Content; 197 | 198 | foreach (var subject in info.FileSortingInfos) 199 | { 200 | AddSubjectStorageInfoToList(subject); 201 | } 202 | } 203 | 204 | private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) 205 | { 206 | if (Configurations.UISettings.Content.IsDoubleClickNotify) 207 | { 208 | ShowWindow(); 209 | } 210 | } 211 | 212 | private void OpenToolStripMenuItem_Click(object sender, EventArgs e) 213 | { 214 | ShowWindow(); 215 | } 216 | 217 | private async void ShowWindow() 218 | { 219 | Visible = true; 220 | await Task.Delay(150); 221 | WindowState = FormWindowState.Normal; 222 | ShowInTaskbar = true; 223 | Activate(); 224 | } 225 | 226 | private async void HideWindow() 227 | { 228 | WindowState = FormWindowState.Minimized; 229 | ShowInTaskbar = false; 230 | await Task.Delay(500); 231 | Visible = false; 232 | } 233 | 234 | private void ExitToolStripMenuItem_Click(object sender, EventArgs e) 235 | { 236 | Application.Exit(); 237 | } 238 | 239 | private void ToolStripMenuItemUpdateCheckerShow_Click(object sender, EventArgs e) 240 | { 241 | new UpdateCheckerWindow().Show(); 242 | } 243 | 244 | private void ComboBoxStyle_SelectedIndexChanged(object sender, EventArgs e) 245 | { 246 | var style = (UIStyle)comboBoxStyle.SelectedItem; 247 | Program.FormStyleController.SetStyle(style); 248 | Configurations.UISettings.Content = Configurations.UISettings.Content with { Style = style }; 249 | Configurations.UISettings.Save(); 250 | } 251 | 252 | private void CheckBoxAutoStart_ValueChanged(object sender, bool value) 253 | { 254 | AutoStartUtilities.SetMeStart(checkBoxAutoStart.Checked); 255 | } 256 | 257 | private void ButtonCleanLog_Click(object sender, EventArgs e) 258 | { 259 | foreach (var file in Directory.GetFiles(Constants.LogDirectory).Where(x => x != Program.Logger.Path)) 260 | { 261 | File.Delete(file); 262 | } 263 | } 264 | 265 | private void ComboBoxLogLevel_SelectedIndexChanged(object sender, EventArgs e) 266 | { 267 | Configurations.UISettings.Content = Configurations.UISettings.Content with { LogLevel = (LogLevel)comboBoxLogLevel.SelectedItem }; 268 | Configurations.UISettings.Save(); 269 | UpdateLoggerElement(); 270 | } 271 | 272 | private void CheckBoxAutoCheckUpdate_ValueChanged(object sender, bool value) 273 | { 274 | Configurations.UISettings.Content = Configurations.UISettings.Content with { IsAutoCheckUpdate = checkBoxAutoCheckUpdate.Checked }; 275 | Configurations.UISettings.Save(); 276 | } 277 | 278 | private void CheckBoxHideWhenStart_ValueChanged(object sender, bool value) 279 | { 280 | checkBoxAutoCheckUpdate.Enabled = !checkBoxHideWhenStart.Checked; 281 | checkBoxAutoCheckUpdate.Checked = false; 282 | Configurations.UISettings.Content = Configurations.UISettings.Content with { IsHideWhenStart = checkBoxHideWhenStart.Checked }; 283 | Configurations.UISettings.Save(); 284 | } 285 | 286 | private void LinkLabelGithub_Click(object sender, EventArgs e) 287 | { 288 | NetUtilities.Start(Constants.RepositoryLink); 289 | } 290 | 291 | private void TabPageAbout_Paint(object sender, PaintEventArgs e) 292 | { 293 | labelVersion.Text = "应用版本:" + Constants.Version.ToString(3); 294 | } 295 | 296 | private void LinkLabelMoInkGithub_Click(object sender, EventArgs e) 297 | { 298 | NetUtilities.Start(Constants.SugarLink); 299 | } 300 | 301 | private void LinkLabelRickyGithub_Click(object sender, EventArgs e) 302 | { 303 | NetUtilities.Start(Constants.RickyLink); 304 | } 305 | 306 | private void CheckBoxDoubleClickNotify_CheckedChanged(object sender, EventArgs e) 307 | { 308 | Configurations.UISettings.Content = Configurations.UISettings.Content with { IsDoubleClickNotify = checkBoxDoubleClickNotify.Checked }; 309 | Configurations.UISettings.Save(); 310 | } 311 | 312 | private void CheckBoxHideToNotify_CheckedChanged(object sender, EventArgs e) 313 | { 314 | checkBoxDoubleClickNotify.Enabled = checkBoxHideToNotify.Checked; 315 | Configurations.UISettings.Content = Configurations.UISettings.Content with { IsHideToNotify = checkBoxHideToNotify.Checked }; 316 | Configurations.UISettings.Save(); 317 | } 318 | 319 | private void ButtonShutdown_Click(object sender, EventArgs e) 320 | { 321 | if (_powerControlTask is null) 322 | { 323 | _powerControlTask = new PowerControlTask(PowerControlType.Shutdown, TimeSpan.FromSeconds(10)).Start(); 324 | timerQuicklyControl.Start(); 325 | } 326 | } 327 | 328 | private void ButtonRestart_Click(object sender, EventArgs e) 329 | { 330 | if (_powerControlTask is null) 331 | { 332 | _powerControlTask = new PowerControlTask(PowerControlType.Reboot, TimeSpan.FromSeconds(10)).Start(); 333 | timerQuicklyControl.Start(); 334 | } 335 | } 336 | 337 | private void ButtonLogout_Click(object sender, EventArgs e) 338 | { 339 | if (_powerControlTask is null) 340 | { 341 | _powerControlTask = new PowerControlTask(PowerControlType.Logout, TimeSpan.FromSeconds(10)).Start(); 342 | timerQuicklyControl.Start(); 343 | } 344 | } 345 | 346 | private void ButtonCancel_Click(object sender, EventArgs e) 347 | { 348 | if (_powerControlTask is not null) 349 | { 350 | _powerControlTask.Cancel(); 351 | _powerControlTask = null; 352 | 353 | timerQuicklyControl.Stop(); 354 | 355 | processBarQuicklyControl.Value = 0; 356 | processBarQuicklyControl.Text = "0.0%"; 357 | } 358 | } 359 | 360 | private void TimerQuicklyControl_Tick(object sender, EventArgs e) 361 | { 362 | if (_powerControlTask is null) 363 | { 364 | return; 365 | } 366 | 367 | double result = _powerControlTask.Elapsed / _powerControlTask.Delay * 100; 368 | 369 | processBarQuicklyControl.Value = (int)(result * 10); 370 | processBarQuicklyControl.Text = $"{result:f1}%"; 371 | } 372 | } 373 | } -------------------------------------------------------------------------------- /src/Models/AssetInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace SeewoHelper 4 | { 5 | public record AssetInfo 6 | { 7 | /// 8 | /// 下载链接 9 | /// 10 | [JsonPropertyName("browser_download_url")] 11 | public string Url { get; init; } 12 | 13 | /// 14 | /// 文件名 15 | /// 16 | [JsonPropertyName("name")] 17 | public string Name { get; init; } 18 | 19 | /// 20 | /// 使用FastGit加速的下载链接 21 | /// 22 | [JsonIgnore] 23 | public string FastGitUrl { get; init; } 24 | 25 | [JsonConstructor] 26 | public AssetInfo(string url, string name) 27 | { 28 | Url = url; 29 | Name = name; 30 | FastGitUrl = Url.Replace("github.com", "download.fastgit.org"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Models/Configuration{T}.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Utilities; 2 | using System; 3 | using System.IO; 4 | using System.Text.Json; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace SeewoHelper 9 | { 10 | /// 11 | /// 表示配置 12 | /// 13 | /// 配置类型 14 | public class Configuration 15 | { 16 | private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; 17 | 18 | private readonly SemaphoreSlim _semaphoreSlim = new(1, 1); 19 | 20 | /// 21 | /// 配置内容 22 | /// 23 | public T Content { get; set; } 24 | 25 | /// 26 | /// 文件路径 27 | /// 28 | public string Path { get; } 29 | 30 | /// 31 | /// 读取 32 | /// 33 | private void Read() 34 | { 35 | Program.Logger.Debug($"正在读取配置文件 {Path}"); 36 | string data = File.ReadAllText(Path); 37 | 38 | Program.Logger.Debug($"读取完毕"); 39 | Program.Logger.Debug($"读取到内容为 {data}"); 40 | 41 | if (!string.IsNullOrWhiteSpace(data)) 42 | { 43 | Content = JsonSerializer.Deserialize(data, JsonSerializerOptions); 44 | } 45 | } 46 | 47 | /// 48 | /// 保存 49 | /// 50 | public void Save() 51 | { 52 | _ = SaveAsync(); 53 | } 54 | 55 | /// 56 | /// 保存 57 | /// 58 | public async Task SaveAsync() 59 | { 60 | Program.Logger.Debug($"正在保存配置类 {Content.GetType()}({Content})"); 61 | Program.Logger.Debug($"等待上一个操作写入"); 62 | await _semaphoreSlim.WaitAsync(); 63 | Program.Logger.Debug($"等待完毕,开始保存"); 64 | 65 | Program.Logger.Debug($"正在序列化配置类 {Content.GetType()}({Content})"); 66 | string data = JsonSerializer.Serialize(Content, JsonSerializerOptions); 67 | Program.Logger.Debug($"序列化结果为 {data}"); 68 | 69 | Program.Logger.Debug($"正在保存配置文件 {Content.GetType()}({Content})"); 70 | await File.WriteAllTextAsync(Path, JsonSerializer.Serialize(Content, JsonSerializerOptions)); 71 | Program.Logger.Debug($"保存完毕"); 72 | 73 | _semaphoreSlim.Release(); 74 | } 75 | 76 | /// 77 | /// 创建 实例 78 | /// 79 | /// 文件夹目录 80 | /// 默认值 81 | public Configuration(string path, T defaultValue) 82 | { 83 | Path = path ?? throw new ArgumentNullException(path); 84 | 85 | if (IOUtilities.IsProperPath(path) && IOUtilities.GetPathType(path) == PathType.File) 86 | { 87 | IOUtilities.CreateFile(path, false); 88 | Read(); 89 | 90 | Content ??= defaultValue; 91 | } 92 | else 93 | { 94 | throw new InvalidOperationException(); 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Models/Features/FileSorter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace SeewoHelper.Features 8 | { 9 | /// 10 | /// 定义文件整理器 11 | /// 12 | public class FileSorter 13 | { 14 | /// 15 | /// 文件信息列表 16 | /// 17 | private readonly IEnumerable _fileSortingInfos; 18 | 19 | /// 20 | /// 搜索文件夹信息 21 | /// 22 | private readonly DirectoryInfo _directory; 23 | 24 | /// 25 | /// 整理多个文件 26 | /// 27 | public async Task SortMore() 28 | { 29 | Program.Logger.Info("开始整理文件"); 30 | 31 | foreach (var info in _fileSortingInfos) 32 | { 33 | await Sort(info); 34 | } 35 | 36 | Program.Logger.Info("整理文件完成"); 37 | } 38 | 39 | /// 40 | /// 整理文件 41 | /// 42 | /// 科目存储信息 43 | private Task Sort(FileSortingInfo info) => Task.Run(() => 44 | { 45 | var fileSystemInfos = _directory.GetFileSystemInfos(); // 获取目录下所有文件及文件夹 46 | var selectedFileSystemInfos = new List(); // 创建用于记录匹配到的文件及文件夹信息 47 | 48 | Program.Logger.Info($"开始整理:{info.Name},目标路径:{info.Path}"); 49 | 50 | foreach (var keyword in info.Keywords) 51 | { 52 | Program.Logger.Info($"正在匹配关键词:{keyword.Pattern} ({keyword.MatchingWay})"); 53 | 54 | var matchedFileSystemInfos = fileSystemInfos.Where(x => keyword.IsMatch(x.Name)); // 匹配当前关键词 55 | selectedFileSystemInfos.AddRange(matchedFileSystemInfos); // 将匹配到的信息添加至列表 56 | 57 | Program.Logger.Info($"匹配到:{string.Join(", ", matchedFileSystemInfos)}"); 58 | } 59 | 60 | var processFileSystemInfos = selectedFileSystemInfos.Distinct().Where(x => x.FullName != Path.GetFullPath(info.Path)); // 排除重复元素 61 | 62 | Program.Logger.Info($"将要处理:{string.Join(", ", processFileSystemInfos)}"); 63 | 64 | foreach (var fileSystemInfo in processFileSystemInfos) 65 | { 66 | Program.Logger.Info($"正在移动:{fileSystemInfo}"); 67 | 68 | try 69 | { 70 | fileSystemInfo.MoveTo(Path.Combine(info.Path, fileSystemInfo.Name), true); // 移动文件或文件夹至目标路径 71 | } 72 | catch (IOException e) 73 | { 74 | Program.Logger.Error($"移动 {fileSystemInfo} 失败,异常消息:{e.Message}"); 75 | } 76 | } 77 | 78 | Program.Logger.Info($"{info.Name} 整理完成"); 79 | }); 80 | 81 | public Task SortExtraFiles(ExtraFileSortingWay extraFileSortingWay) => Task.Run(() => 82 | { 83 | switch (extraFileSortingWay) 84 | { 85 | case ExtraFileSortingWay.None: 86 | break; 87 | 88 | case ExtraFileSortingWay.Delete: 89 | foreach (var file in _directory.GetFiles()) 90 | { 91 | file.Delete(); 92 | } 93 | break; 94 | 95 | default: 96 | throw new NotSupportedException(); 97 | } 98 | }); 99 | 100 | public FileSorter(string path, IEnumerable info) 101 | { 102 | _directory = new DirectoryInfo(path); 103 | _fileSortingInfos = info; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/Models/Features/Updater.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Net.Http; 3 | using System.Text.Json; 4 | using System.Threading.Tasks; 5 | 6 | namespace SeewoHelper.Features 7 | { 8 | /// 9 | /// 定义更新器 10 | /// 11 | public class Updater 12 | { 13 | /// 14 | /// 最新 Release 信息 15 | /// 16 | public ReleaseInfo Release { get; private set; } 17 | 18 | /// 19 | /// 最新 Pre-Release 信息 20 | /// 21 | public ReleaseInfo Prerelease { get; private set; } 22 | 23 | public async Task GetInfo() 24 | { 25 | Program.Logger.Info("开始获取 Release 信息"); 26 | var client = new HttpClient(); 27 | client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.50 Safari/537.36 Edge/88.0.705.29"); // 添加 User-Agent 头信息 28 | 29 | var res = await client.GetAsync(Constants.ReleasesLink); // 获取信息 30 | res.EnsureSuccessStatusCode(); // 当获取状态码为失败时抛出异常 31 | Program.Logger.Info("Release 信息获取完成"); 32 | 33 | Program.Logger.Info("开始读取 Release 内容"); 34 | string content = await res.Content.ReadAsStringAsync(); // 读取内容 35 | var infos = JsonSerializer.Deserialize(content); // 反序列化信息 36 | Program.Logger.Info("Release 内容读取完成"); 37 | 38 | Release = infos.FirstOrDefault(x => !x.IsPrerelease); // 赋值 Release 为符合 !IsPrerelease 第一个元素 39 | Prerelease = infos.FirstOrDefault(x => x.IsPrerelease); // 赋值 Prerelease 为符合 IsPrerelease 第一个元素 40 | } 41 | 42 | public Updater() 43 | { 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Models/FileSorterConfig.cs: -------------------------------------------------------------------------------- 1 | namespace SeewoHelper 2 | { 3 | public record FileSorterConfig(ExtraFileSortingWay ExtraFileSortingWay, FileSortingInfo[] FileSortingInfos); 4 | 5 | public enum ExtraFileSortingWay 6 | { 7 | None, 8 | Delete 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Models/FileSortingInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SeewoHelper 4 | { 5 | /// 6 | /// 用于为 提供数据 7 | /// 8 | public record FileSortingInfo(string Name, string Path, List Keywords); 9 | } 10 | -------------------------------------------------------------------------------- /src/Models/FormStyleController.cs: -------------------------------------------------------------------------------- 1 | using Sunny.UI; 2 | using System.Collections.Generic; 3 | using System.Windows.Forms; 4 | 5 | namespace SeewoHelper 6 | { 7 | public class FormStyleController 8 | { 9 | private readonly List _forms = new(); 10 | 11 | public UIStyle CurrentStyle { get; private set; } = UIStyle.Custom; 12 | 13 | public void SetStyle(UIStyle style) 14 | { 15 | if (CurrentStyle != style) 16 | { 17 | Program.Logger.Info($"设置 Style 为 {style}"); 18 | CurrentStyle = style; 19 | 20 | foreach (var form in _forms) 21 | { 22 | form.Style = style; 23 | } 24 | } 25 | } 26 | 27 | public void Initialize(UIForm form) 28 | { 29 | _forms.Add(form); 30 | form.Style = CurrentStyle; 31 | form.FormClosed += Form_FormClosed; 32 | } 33 | 34 | private void Form_FormClosed(object sender, FormClosedEventArgs e) 35 | { 36 | _forms.Remove((UIForm)sender); 37 | } 38 | 39 | public FormStyleController() 40 | { 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Models/IReturnableForm.cs: -------------------------------------------------------------------------------- 1 | namespace SeewoHelper 2 | { 3 | /// 4 | /// 带返回结果的 5 | /// 6 | /// 返回结果类型 7 | public interface IReturnableForm 8 | { 9 | /// 10 | /// 无参数获取结果 11 | /// 12 | TResult GetResult(); 13 | } 14 | 15 | /// 16 | /// 带返回结果的 17 | /// 18 | /// 返回结果类型 19 | /// 传入参数类型 20 | public interface IReturnableForm 21 | { 22 | /// 23 | /// 需传入 1 个参数获取结果 24 | /// 25 | /// 参数 26 | TResult GetResult(T arg); 27 | } 28 | 29 | /// 30 | /// 带返回结果的 31 | /// 32 | /// 返回结果类型 33 | /// 传入参数 1 类型 34 | /// 传入参数 2 类型 35 | public interface IReturnableForm 36 | { 37 | /// 38 | /// 需传入 2 个参数获取结果 39 | /// 40 | /// 参数 1 41 | /// 参数 2 42 | /// 43 | TResult GetResult(T1 arg1, T2 arg2); 44 | } 45 | 46 | /// 47 | /// 带返回结果的 48 | /// 49 | /// 返回结果类型 50 | /// 传入参数 1 类型 51 | /// 传入参数 2 类型 52 | /// 传入参数 3 类型 53 | public interface IReturnableForm 54 | { 55 | /// 56 | /// 需传入 3 个参数获取结果 57 | /// 58 | /// 参数 1 59 | /// 参数 2 60 | /// 参数 3 61 | /// 62 | TResult GetResult(T1 arg1, T2 arg2, T3 arg3); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Models/Keyword.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace SeewoHelper 5 | { 6 | /// 7 | /// 表示关键词 8 | /// 9 | public record Keyword(string Pattern, KeywordMatchingWay MatchingWay) 10 | { 11 | /// 12 | /// 判断输入字符串是否匹配 13 | /// 14 | /// 输入字符串 15 | /// 16 | public bool IsMatch(string input) => MatchingWay switch 17 | { 18 | KeywordMatchingWay.Normal => input.Contains(Pattern), 19 | KeywordMatchingWay.CaseInsensitive => input.Contains(Pattern, StringComparison.CurrentCultureIgnoreCase), 20 | KeywordMatchingWay.Regex => new Regex(Pattern).IsMatch(input), 21 | _ => throw new InvalidOperationException() 22 | }; 23 | } 24 | 25 | public enum KeywordMatchingWay 26 | { 27 | Normal, 28 | CaseInsensitive, 29 | Regex 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Models/Log.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SeewoHelper 4 | { 5 | /// 6 | /// 表示日志 7 | /// 8 | public record Log(string Content, LogLevel Level = LogLevel.Info) 9 | { 10 | /// 11 | /// 时间 12 | /// 13 | public DateTime Time { get; } = DateTime.Now; 14 | 15 | /// 16 | public override string ToString() => $"[ {Level.ToString().ToUpper()} ] {Time:F}: {Content}"; 17 | } 18 | 19 | /// 20 | /// 日志等级 21 | /// 22 | public enum LogLevel 23 | { 24 | Debug = 0, 25 | Info = 1, 26 | Warning = 2, 27 | Error = 3, 28 | Fatal = 4 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Models/Logger.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Utilities; 2 | using System; 3 | using System.Collections.ObjectModel; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace SeewoHelper 10 | { 11 | /// 12 | /// 定义日志记录器 13 | /// 14 | public class Logger : ObservableCollection 15 | { 16 | private readonly SemaphoreSlim _semaphoreSlim = new(1, 1); 17 | 18 | /// 19 | /// 文件路径 20 | /// 21 | public string Path { get; } 22 | 23 | /// 24 | /// 添加 的日志 25 | /// 26 | /// 内容 27 | public void Debug(string content) => Add(new Log(content, LogLevel.Debug)); 28 | 29 | /// 30 | /// 添加 的日志 31 | /// 32 | /// 内容 33 | public void Info(string content) => Add(new Log(content)); 34 | 35 | /// 36 | /// 添加 的日志 37 | /// 38 | /// 内容 39 | public void Warning(string content) => Add(new Log(content, LogLevel.Warning)); 40 | 41 | /// 42 | /// 添加 的日志 43 | /// 44 | /// 内容 45 | public void Error(string content) => Add(new Log(content, LogLevel.Error)); 46 | 47 | /// 48 | /// 添加 的日志 49 | /// 50 | /// 内容 51 | public void Fatal(string content) => Add(new Log(content, LogLevel.Fatal)); 52 | 53 | /// 54 | /// 保存 55 | /// 56 | public async Task SaveAsync() 57 | { 58 | await _semaphoreSlim.WaitAsync(); 59 | await File.WriteAllTextAsync(Path, ToString()); 60 | _semaphoreSlim.Release(); 61 | } 62 | 63 | /// 64 | public override string ToString() => string.Join(Environment.NewLine, this); 65 | 66 | /// 67 | /// 返回指定日志级别的日志记录器字符串 68 | /// 69 | /// 70 | public string ToString(LogLevel level) => string.Join(Environment.NewLine, this.Where(x => x.Level >= level)); 71 | 72 | /// 73 | /// 创建 实例 74 | /// 75 | /// 路径 76 | public Logger(string path) 77 | { 78 | Path = path ?? throw new ArgumentNullException(nameof(path)); 79 | 80 | if (IOUtilities.IsProperPath(path) && IOUtilities.GetPathType(path) == PathType.File) 81 | { 82 | IOUtilities.CreateFile(path); 83 | CollectionChanged += async (sender, e) => await SaveAsync(); 84 | } 85 | else 86 | { 87 | throw new InvalidOperationException(); 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Models/PowerControlTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace SeewoHelper 7 | { 8 | public class PowerControlTask 9 | { 10 | private readonly Process _process; 11 | private readonly Task _task; 12 | private readonly Stopwatch _stopwatch = new(); 13 | private readonly EventWaitHandle _eventWaitHandle = new(false, EventResetMode.AutoReset); 14 | 15 | public PowerControlTask(PowerControlType type, TimeSpan delay) 16 | { 17 | _process = type switch 18 | { 19 | PowerControlType.Shutdown => GetProcess("-s -t 0"), 20 | PowerControlType.Reboot => GetProcess("-r -t 0"), 21 | PowerControlType.Logout => GetProcess("-l -t 0"), 22 | _ => throw new ArgumentOutOfRangeException(nameof(type)) 23 | }; 24 | 25 | _task = new Task(HandleAsync, TaskCreationOptions.LongRunning); 26 | 27 | Delay = delay; 28 | } 29 | 30 | public TimeSpan Delay { get; } 31 | 32 | public TimeSpan Elapsed => _stopwatch.Elapsed; 33 | 34 | public bool IsStarted { get; private set; } 35 | 36 | public bool IsCancelled { get; private set; } 37 | 38 | public PowerControlTask Start() 39 | { 40 | if (IsStarted || IsCancelled) 41 | { 42 | throw new InvalidOperationException(); 43 | } 44 | 45 | IsStarted = true; 46 | 47 | _stopwatch.Start(); 48 | _task.Start(); 49 | return this; 50 | } 51 | 52 | public void Cancel() 53 | { 54 | IsStarted = false; 55 | IsCancelled = true; 56 | 57 | _stopwatch.Stop(); 58 | _stopwatch.Reset(); 59 | } 60 | 61 | public void Wait() 62 | { 63 | if (!IsStarted) 64 | { 65 | throw new InvalidOperationException(); 66 | } 67 | 68 | if (!_task.IsCompleted) 69 | { 70 | _eventWaitHandle.WaitOne(); 71 | } 72 | 73 | _process.WaitForExit(); 74 | } 75 | 76 | private static Process GetProcess(string arguments) 77 | { 78 | return new() { StartInfo = new ProcessStartInfo("shutdown.exe", arguments) }; 79 | } 80 | 81 | private async void HandleAsync() 82 | { 83 | await Task.Delay(Delay); 84 | 85 | if (!IsCancelled) 86 | { 87 | _process.Start(); 88 | _eventWaitHandle.Set(); 89 | 90 | Cancel(); 91 | } 92 | } 93 | } 94 | 95 | public enum PowerControlType 96 | { 97 | Shutdown, 98 | Reboot, 99 | Logout 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Models/ReleaseInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace SeewoHelper 4 | { 5 | /// 6 | /// 表示 Release 信息 7 | /// 8 | public record ReleaseInfo 9 | { 10 | /// 11 | /// 页面 Url 12 | /// 13 | [JsonPropertyName("html_url")] 14 | public string Url { get; init; } 15 | 16 | /// 17 | /// Release 名称 18 | /// 19 | [JsonPropertyName("name")] 20 | public string Name { get; init; } 21 | 22 | /// 23 | /// Tag 名称 24 | /// 25 | [JsonPropertyName("tag_name")] 26 | public string Tag { get; init; } 27 | 28 | /// 29 | /// 是否为 Pre-Release 30 | /// 31 | [JsonPropertyName("prerelease")] 32 | public bool IsPrerelease { get; init; } 33 | 34 | /// 35 | /// Release 资源 36 | /// 37 | [JsonPropertyName("assets")] 38 | public AssetInfo[] Assets { get; init; } 39 | 40 | /// 41 | /// 创建 实例 42 | /// 43 | /// 页面 Url 44 | /// Release 名称 45 | /// Release 资源 46 | /// Tag 名称 47 | /// 是否为 Pre-Release 48 | [JsonConstructor] 49 | public ReleaseInfo(string url, string name, string tag, bool isPrerelease, AssetInfo[] assets) 50 | { 51 | Url = url; 52 | Name = name; 53 | Tag = tag; 54 | IsPrerelease = isPrerelease; 55 | Assets = assets; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Models/Service.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.ServiceProcess; 5 | using System.Threading.Tasks; 6 | 7 | namespace SeewoHelper 8 | { 9 | /// 10 | /// 定义服务 11 | /// 12 | public class Service 13 | { 14 | /// 15 | /// 名称 16 | /// 17 | public string Name { get; } 18 | 19 | /// 20 | /// 状态 21 | /// 22 | public ServiceControllerStatus Status => Refresh().Status; 23 | 24 | /// 25 | /// 启动类型 26 | /// 27 | public ServiceStartMode StartType => Refresh().StartType; 28 | 29 | /// 30 | /// 当前 实例的 31 | /// 32 | private readonly ServiceController _controller; 33 | 34 | /// 35 | /// 对应 指令词典 36 | /// 37 | private static readonly Dictionary _serviceStartModeDictionary = new() 38 | { 39 | [ServiceStartMode.Boot] = "boot", 40 | [ServiceStartMode.System] = "system", 41 | [ServiceStartMode.Automatic] = "auto", 42 | [ServiceStartMode.Manual] = "demand", 43 | [ServiceStartMode.Disabled] = "disabled" 44 | }; 45 | 46 | /// 47 | /// 刷新 48 | /// 49 | /// 刷新后的 50 | private ServiceController Refresh() 51 | { 52 | _controller.Refresh(); 53 | return _controller; 54 | } 55 | 56 | /// 57 | /// 异步启动 58 | /// 59 | public async Task StartAsync() 60 | { 61 | _controller.Start(); 62 | await Task.Run(() => _controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMinutes(1))); 63 | 64 | Program.Logger.Info($"启动 {Name} 服务"); 65 | } 66 | 67 | /// 68 | /// 异步停止 69 | /// 70 | public async Task StopAsync() 71 | { 72 | _controller.Stop(); 73 | await Task.Run(() => _controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMinutes(1))); 74 | 75 | Program.Logger.Info($"停止 {Name} 服务"); 76 | } 77 | 78 | /// 79 | /// 设置启动类型 80 | /// 81 | public async Task SetStartTypeAsync(ServiceStartMode startType) 82 | { 83 | var processStartInfo = new ProcessStartInfo("sc.exe", $"config {Name} start= {_serviceStartModeDictionary[startType]}") { CreateNoWindow = false, WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = true }; 84 | await Process.Start(processStartInfo).WaitForExitAsync(); 85 | 86 | Program.Logger.Info($"将 {Name} 服务的 StartType 调整为 {startType}"); 87 | } 88 | 89 | /// 90 | /// 创建 实例 91 | /// 92 | /// 名称 93 | public Service(string name) 94 | { 95 | Name = name ?? throw new ArgumentNullException(nameof(name)); 96 | _controller = new ServiceController(name); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/Models/ServiceCheckBox.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Utilities; 2 | using Sunny.UI; 3 | using System; 4 | using System.ServiceProcess; 5 | using System.Threading.Tasks; 6 | 7 | namespace SeewoHelper 8 | { 9 | /// 10 | /// 定义控制服务开关的 11 | /// 12 | public class ServiceCheckBox 13 | { 14 | /// 15 | /// 实例 16 | /// 17 | private readonly UICheckBox _checkBox; 18 | 19 | /// 20 | /// 实例 21 | /// 22 | private readonly Service _service; 23 | 24 | /// 25 | /// 是否反转 状态 26 | /// 27 | private readonly bool _isReverseChecked; 28 | 29 | /// 30 | /// 启用时设置的启动类型 31 | /// 32 | private readonly ServiceStartMode _startType; 33 | 34 | /// 35 | /// 当前 应为的状态 36 | /// 37 | private bool IsChecked => SystemUtilities.ReverseBool(_isReverseChecked, _service.Status == ServiceControllerStatus.Running); 38 | 39 | /// 40 | /// 预操作 41 | /// 42 | public Action PreAction { get; set; } 43 | 44 | /// 45 | /// 后操作 46 | /// 47 | public Action PostAction { get; set; } 48 | 49 | /// 50 | /// 设置服务状态 51 | /// 52 | /// 是否启用 53 | private async Task SetService(bool enable) 54 | { 55 | if (enable) 56 | { 57 | await _service.SetStartTypeAsync(_startType); 58 | await _service.StartAsync(); 59 | } 60 | else 61 | { 62 | await _service.StopAsync(); 63 | await _service.SetStartTypeAsync(ServiceStartMode.Disabled); 64 | } 65 | } 66 | 67 | /// 68 | /// 当 状态改变时触发 69 | /// 70 | private async void CheckBox_ValueChanged(object sender, bool value) 71 | { 72 | // --- 用于保留当前状态,解决部分问题 --- 73 | bool current = _service.Status == ServiceControllerStatus.Running; 74 | bool isChecked = SystemUtilities.ReverseBool(_isReverseChecked, current); 75 | // --- ! --- 76 | 77 | if (_checkBox.Checked != isChecked) 78 | { 79 | PreAction?.Invoke(); 80 | _checkBox.Enabled = false; 81 | 82 | try 83 | { 84 | await SetService(!current); 85 | } 86 | catch 87 | { 88 | _checkBox.Checked = IsChecked; 89 | throw; 90 | } 91 | finally 92 | { 93 | _checkBox.Enabled = true; 94 | PostAction?.Invoke(); 95 | } 96 | } 97 | } 98 | 99 | /// 100 | /// 创建 实例 101 | /// 102 | /// 实例 103 | /// 服务名称 104 | /// 是否反转 状态 105 | /// 启用时设置的启动类型 106 | public ServiceCheckBox(UICheckBox checkBox, string serviceName, bool isReverseChecked, ServiceStartMode startType = ServiceStartMode.Automatic) 107 | { 108 | _checkBox = checkBox ?? throw new ArgumentNullException(nameof(checkBox)); 109 | _service = new Service(serviceName ?? throw new ArgumentNullException(nameof(serviceName))); 110 | _isReverseChecked = isReverseChecked; 111 | _startType = startType; 112 | 113 | checkBox.Checked = IsChecked; 114 | checkBox.ValueChanged += CheckBox_ValueChanged; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Models/UISettings.cs: -------------------------------------------------------------------------------- 1 | using Sunny.UI; 2 | 3 | namespace SeewoHelper 4 | { 5 | /// 6 | /// 表示 UI 设置 7 | /// 8 | public record UISettings(UIStyle Style, LogLevel LogLevel, bool IsHideWhenStart, bool IsAutoCheckUpdate, bool IsDoubleClickNotify, bool IsHideToNotify); 9 | } 10 | -------------------------------------------------------------------------------- /src/Program.cs: -------------------------------------------------------------------------------- 1 | using SeewoHelper.Forms; 2 | using System; 3 | using System.IO; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace SeewoHelper 9 | { 10 | internal static class Program 11 | { 12 | public static Logger Logger { get; private set; } 13 | 14 | public static FormStyleController FormStyleController { get; } = new FormStyleController(); 15 | 16 | public static event EventHandler HandleCreated; 17 | 18 | /// 19 | /// 应用程序的主入口点。 20 | /// 21 | [STAThread] 22 | private static void Main() 23 | { 24 | using var eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.AppName, out bool createdNew); 25 | 26 | if (createdNew) 27 | { 28 | Logger = new Logger(Path.Combine(Constants.LogDirectory, DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".log")); 29 | 30 | Application.ThreadException += Application_ThreadException; // 处理主线程的异常 31 | AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; // 处理子线程未捕获异常 32 | 33 | Application.SetHighDpiMode(HighDpiMode.SystemAware); 34 | Application.EnableVisualStyles(); 35 | Application.SetCompatibleTextRenderingDefault(false); 36 | 37 | FormStyleController.SetStyle(Configurations.UISettings.Content.Style); // 设置窗体风格 38 | 39 | _ = HandleNewInstanceAsync(); 40 | 41 | Logger.Info("应用启动完毕"); 42 | 43 | Application.Run(new WindowMain()); 44 | } 45 | else 46 | { 47 | eventWaitHandle.Set(); 48 | } 49 | 50 | Task HandleNewInstanceAsync() => Task.Factory.StartNew(() => 51 | { 52 | while (eventWaitHandle.WaitOne()) 53 | { 54 | HandleCreated?.Invoke(null, new()); 55 | } 56 | }, TaskCreationOptions.LongRunning); 57 | } 58 | 59 | private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) 60 | { 61 | e.Exception.ShowAndLog(Logger); 62 | } 63 | 64 | private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 65 | { 66 | (e.ExceptionObject as Exception)?.ShowAndLog(Logger, e.IsTerminating); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SeewoHelper.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SeewoHelper.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性,对 51 | /// 使用此强类型资源类的所有资源查找执行重写。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /src/SeewoHelper.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net5.0-windows 6 | true 7 | SugarMGP 8 | 一个为 Seewo 等一体机定制的教室多媒体辅助程序 9 | app.manifest 10 | favicon.ico 11 | SeewoHelper.Program 12 | 0.4.7 13 | zh-CN 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | True 24 | True 25 | Resources.resx 26 | 27 | 28 | 29 | 30 | 31 | ResXFileCodeGenerator 32 | Resources.Designer.cs 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/SeewoHelper.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30523.141 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SeewoHelper", "SeewoHelper.csproj", "{84FC0603-FD33-45D1-8749-4AEC1FC5D792}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {84FC0603-FD33-45D1-8749-4AEC1FC5D792}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {84FC0603-FD33-45D1-8749-4AEC1FC5D792}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {84FC0603-FD33-45D1-8749-4AEC1FC5D792}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {84FC0603-FD33-45D1-8749-4AEC1FC5D792}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {BBD58032-0B6C-4182-8CE0-EE1C055F5D4E} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/Utilities/AutoStartUtilities.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | 6 | namespace SeewoHelper.Utilities 7 | { 8 | /// 9 | /// 提供处理开机自动启动相关的方法 10 | /// 11 | public static class AutoStartUtilities 12 | { 13 | /// 14 | /// 将本程序设为开启自启 15 | /// 16 | /// 自启开关 17 | /// 18 | public static void SetMeStart(bool enabled) 19 | { 20 | if (enabled) 21 | { 22 | Program.Logger.Info("设置开机自启"); 23 | } 24 | else 25 | { 26 | Program.Logger.Info("关闭开机自启"); 27 | } 28 | 29 | var module = Process.GetCurrentProcess().MainModule; 30 | SetAutoStart(enabled, module.ModuleName, module.FileName); 31 | } 32 | 33 | /// 34 | /// 将应用程序设为或不设为开机启动 35 | /// 36 | /// 自启开关 37 | /// 应用程序名 38 | /// 应用程序完全路径 39 | public static void SetAutoStart(bool enabled, string name, string path) 40 | { 41 | var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); 42 | 43 | if (key is null) 44 | { 45 | throw new InvalidOperationException(); 46 | } 47 | 48 | // 若开机自启动则添加键值对 49 | if (enabled) 50 | { 51 | key.SetValue(name, path); 52 | key.Close(); 53 | } 54 | else // 否则删除键值对 55 | { 56 | var keyNames = key.GetValueNames().Where(keyName => keyName.Equals(name, StringComparison.OrdinalIgnoreCase)); 57 | 58 | foreach (string keyName in keyNames) 59 | { 60 | key.DeleteValue(name); 61 | key.Close(); 62 | } 63 | } 64 | } 65 | 66 | /// 67 | /// 判断当前程序是否开机自启 68 | /// 69 | public static bool IsAutoStart() => KeyExists(Process.GetCurrentProcess().MainModule.ModuleName); 70 | 71 | /// 72 | /// 判断注册键值对是否存在,即是否处于开机启动状态 73 | /// 74 | /// 键值名 75 | /// 76 | private static bool KeyExists(string keyName) 77 | { 78 | var runs = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); 79 | 80 | if (runs is null) 81 | { 82 | throw new InvalidOperationException(); 83 | } 84 | 85 | return runs.GetValueNames().Any(name => name.Equals(keyName, StringComparison.OrdinalIgnoreCase)); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Utilities/FolderBrowserDialogUtilities.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace SeewoHelper.Utilities 4 | { 5 | /// 6 | /// 提供 相关的方法 7 | /// 8 | public static class FolderBrowserDialogUtilities 9 | { 10 | /// 11 | /// 获取文件路径 12 | /// 13 | /// 描述 14 | public static string GetFilePath(string description = "") 15 | { 16 | var dialog = new FolderBrowserDialog() { Description = description }; 17 | dialog.ShowDialog(); 18 | 19 | return dialog.SelectedPath.NotEmptyOrDefault(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Utilities/IOUtilities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace SeewoHelper.Utilities 6 | { 7 | /// 8 | /// 提供 命名空间下相关的方法 9 | /// 10 | public static class IOUtilities 11 | { 12 | /// 13 | /// 检测路径是否合法 14 | /// 15 | /// 路径 16 | /// 是否允许为根目录 17 | /// 18 | public static bool IsProperPath(string path, bool allowRoot = true) 19 | { 20 | if (string.IsNullOrWhiteSpace(path)) 21 | { 22 | throw new ArgumentException($"“{nameof(path)}”不能为 Null 或空白", nameof(path)); 23 | } 24 | 25 | var regex = new Regex(@"^[a-zA-Z]:[\\]((?! )(?![^\\/]*\s+[\\/])[\w -]+[\\/])*(?! )(?![^.]*\s+\.)[\w -]+$"); 26 | var regexRoot = new Regex(@"^[a-zA-Z]:[\\]"); 27 | 28 | return regex.IsMatch(path) || (allowRoot && regexRoot.IsMatch(path)); 29 | } 30 | 31 | /// 32 | /// 获取路径类型 33 | /// 34 | /// 路径 35 | /// 36 | public static PathType GetPathType(string path) 37 | { 38 | if (string.IsNullOrWhiteSpace(path)) 39 | { 40 | throw new ArgumentException($"“{nameof(path)}”不能为 Null 或空白", nameof(path)); 41 | } 42 | 43 | if (Directory.Exists(path) || (Path.GetExtension(path) == string.Empty && !File.Exists(path))) 44 | { 45 | return PathType.Directionary; 46 | } 47 | else 48 | { 49 | return PathType.File; 50 | } 51 | } 52 | 53 | /// 54 | /// 创建文件 55 | /// 56 | /// 路径 57 | /// 是否覆盖 58 | public static void CreateFile(string path, bool overwrite = true) 59 | { 60 | if (string.IsNullOrWhiteSpace(path)) 61 | { 62 | throw new ArgumentException($"“{nameof(path)}”不能为 Null 或空白", nameof(path)); 63 | } 64 | 65 | var fileInfo = new FileInfo(path); 66 | 67 | if (overwrite || !fileInfo.Exists) 68 | { 69 | Directory.CreateDirectory(fileInfo.DirectoryName); 70 | fileInfo.Create().Close(); 71 | } 72 | } 73 | } 74 | 75 | public enum PathType 76 | { 77 | Directionary, 78 | File 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Utilities/MessageBoxUtilities.cs: -------------------------------------------------------------------------------- 1 | using Sunny.UI; 2 | 3 | namespace SeewoHelper.Utilities 4 | { 5 | public static class MessageBoxUtilities 6 | { 7 | /// 8 | /// 显示提示框 9 | /// 10 | public static bool Show(string text, string caption, bool showMask = false, UIMessageBoxButtons buttons = UIMessageBoxButtons.OK) 11 | { 12 | Program.Logger.Info($"显示消息框,参数:[text: {text}, caption: {caption}, showMask: {showMask}, buttons: {buttons}]"); 13 | return UIMessageBox.Show(text, caption, Program.FormStyleController.CurrentStyle, buttons, showMask); 14 | } 15 | 16 | /// 17 | /// 显示询问信息提示框 18 | /// 19 | public static bool ShowAsk(string text, bool showMask = false) 20 | { 21 | return Show(text, "询问", showMask, UIMessageBoxButtons.OKCancel); 22 | } 23 | 24 | /// 25 | /// 显示错误信息提示框 26 | /// 27 | public static void ShowError(string text, bool showMask = false) 28 | { 29 | Show(text, "错误", showMask); 30 | } 31 | 32 | /// 33 | /// 显示信息提示框 34 | /// 35 | public static void ShowInfo(string text, bool showMask = false) 36 | { 37 | Show(text, "提示", showMask); 38 | } 39 | 40 | /// 41 | /// 显示成功信息提示框 42 | /// 43 | public static void ShowSuccess(string text, bool showMask = false) 44 | { 45 | Show(text, "成功", showMask); 46 | } 47 | 48 | /// 49 | /// 显示警告信息提示框 50 | /// 51 | public static void ShowWarning(string text, bool showMask = false) 52 | { 53 | Show(text, "警告", showMask); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Utilities/NetUtilities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace SeewoHelper.Utilities 5 | { 6 | /// 7 | /// 提供 命名空间下相关的方法 8 | /// 9 | public static class NetUtilities 10 | { 11 | /// 12 | /// 打开指定地址的网页 13 | /// 14 | /// 15 | public static void Start(string url) 16 | { 17 | var uriBuilder = new UriBuilder(url); 18 | 19 | if (uriBuilder.Scheme == Uri.UriSchemeHttp || uriBuilder.Scheme == Uri.UriSchemeHttps) 20 | { 21 | Process.Start("explorer.exe", url); // 使用 explorer.exe 调用默认浏览器打开对应地址 22 | } 23 | else 24 | { 25 | throw new UriFormatException(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Utilities/SystemUtilities.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace SeewoHelper.Utilities 4 | { 5 | /// 6 | /// 提供 命名空间下相关的方法 7 | /// 8 | public static class SystemUtilities 9 | { 10 | /// 11 | /// 判断一个或多个字符串是否为 或为空或仅存在空格符 12 | /// 13 | /// 14 | /// 15 | public static bool IsNullOrWhiteSpace(params string[] strs) => strs.Any(string.IsNullOrWhiteSpace); 16 | 17 | /// 18 | /// 反转 19 | /// 20 | /// 是否反转 21 | /// 指定 bool 22 | /// 23 | public static bool ReverseBool(bool isReverse, bool b) => isReverse ? !b : b; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 58 | 59 | 60 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SugarWorkshop/SeewoHelper/b90bb6a8301c5752125da5fe0cf0cf3f046abe91/src/favicon.ico --------------------------------------------------------------------------------