├── .clang-format ├── .github ├── ISSUE_TEMPLATE │ ├── BugReport.yml │ ├── BugReport.zh-CN.yml │ ├── FeatureRequest.yml │ ├── FeatureRequest.zh-CN.yml │ └── config.yml ├── PULL_REQUEST_TEMPLATE │ ├── en-US.yml │ └── zh-CN.yml └── workflows │ ├── build.yml │ ├── clangformat.yml │ ├── codecov.yml │ ├── codeql.yml │ ├── gitmsg.yml │ └── wiki.yml ├── .gitignore ├── .gitmsgrc.cjs ├── CONTRIBUTING.md ├── CONTRIBUTING.zh-CN.md ├── LICENSE ├── README.md ├── README.zh-CN.md ├── SECURITY.md ├── SECURITY.zh-CN.md ├── UnitTest ├── UnitTest.cpp ├── UnitTest.vcxproj ├── UnitTest.vcxproj.filters └── UnitTest.vcxproj.user ├── WCH.cpp ├── WCH.ico ├── WCH.manifest ├── WCH.rc ├── WCH.sln ├── WCH.vcxproj ├── WCH.vcxproj.filters ├── WCH.vcxproj.user ├── codecov.yml ├── modules ├── apis.hpp ├── basic.hpp ├── commands.hpp ├── file-process.hpp ├── functions.hpp └── init.hpp ├── resources ├── en-US │ ├── config.json │ ├── help.json │ └── interactive.json └── zh-CN │ ├── config.json │ ├── help.json │ └── interactive.json ├── scripts ├── build.ps1 ├── copy-internal.ps1 ├── copy-public.ps1 ├── shasum.ps1 └── sign.ps1 ├── shasum.hpp ├── version.hpp └── wiki ├── Brief.md ├── Build.md ├── Contact.md ├── Contribution.md ├── Directories.md ├── FAQ.md ├── Home.md ├── Installation.md ├── Scripts.md ├── Use.md ├── _Footer.md └── _Sidebar.md /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Google 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: Align 6 | AlignArrayOfStructures: None 7 | AlignConsecutiveMacros: None 8 | AlignConsecutiveAssignments: None 9 | AlignConsecutiveBitFields: None 10 | AlignConsecutiveDeclarations: None 11 | AlignEscapedNewlines: Left 12 | AlignOperands: Align 13 | AlignTrailingComments: true 14 | AllowAllArgumentsOnNextLine: true 15 | AllowAllParametersOfDeclarationOnNextLine: true 16 | AllowShortEnumsOnASingleLine: true 17 | AllowShortBlocksOnASingleLine: Never 18 | AllowShortCaseLabelsOnASingleLine: false 19 | AllowShortFunctionsOnASingleLine: All 20 | AllowShortLambdasOnASingleLine: All 21 | AllowShortIfStatementsOnASingleLine: WithoutElse 22 | AllowShortLoopsOnASingleLine: true 23 | AlwaysBreakAfterDefinitionReturnType: None 24 | AlwaysBreakAfterReturnType: None 25 | AlwaysBreakBeforeMultilineStrings: false 26 | AlwaysBreakTemplateDeclarations: No 27 | AttributeMacros: 28 | - __capability 29 | BinPackArguments: true 30 | BinPackParameters: true 31 | BraceWrapping: 32 | AfterCaseLabel: false 33 | AfterClass: true 34 | AfterControlStatement: Never 35 | AfterEnum: false 36 | AfterFunction: true 37 | AfterNamespace: true 38 | AfterObjCDeclaration: true 39 | AfterStruct: true 40 | AfterUnion: false 41 | AfterExternBlock: true 42 | BeforeCatch: true 43 | BeforeElse: true 44 | BeforeLambdaBody: true 45 | BeforeWhile: true 46 | IndentBraces: false 47 | SplitEmptyFunction: true 48 | SplitEmptyRecord: true 49 | SplitEmptyNamespace: true 50 | BreakBeforeBinaryOperators: None 51 | BreakBeforeConceptDeclarations: true 52 | BreakBeforeBraces: Attach 53 | BreakBeforeInheritanceComma: false 54 | BreakInheritanceList: BeforeColon 55 | BreakBeforeTernaryOperators: true 56 | BreakConstructorInitializersBeforeComma: false 57 | BreakConstructorInitializers: BeforeColon 58 | BreakAfterJavaFieldAnnotations: false 59 | BreakStringLiterals: true 60 | ColumnLimit: 0 61 | CommentPragmas: '^ IWYU pragma:' 62 | QualifierAlignment: Leave 63 | CompactNamespaces: false 64 | ConstructorInitializerIndentWidth: 4 65 | ContinuationIndentWidth: 4 66 | Cpp11BracedListStyle: true 67 | DeriveLineEnding: true 68 | DerivePointerAlignment: true 69 | DisableFormat: false 70 | EmptyLineAfterAccessModifier: Never 71 | EmptyLineBeforeAccessModifier: Never 72 | ExperimentalAutoDetectBinPacking: false 73 | PackConstructorInitializers: NextLine 74 | BasedOnStyle: '' 75 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 76 | AllowAllConstructorInitializersOnNextLine: true 77 | FixNamespaceComments: false 78 | ForEachMacros: 79 | - foreach 80 | - Q_FOREACH 81 | - BOOST_FOREACH 82 | IfMacros: 83 | - KJ_IF_MAYBE 84 | IncludeBlocks: Regroup 85 | IncludeCategories: 86 | - Regex: '^' 87 | Priority: 2 88 | SortPriority: 0 89 | CaseSensitive: false 90 | - Regex: '^<.*\.h>' 91 | Priority: 1 92 | SortPriority: 0 93 | CaseSensitive: false 94 | - Regex: '^<.*' 95 | Priority: 2 96 | SortPriority: 0 97 | CaseSensitive: false 98 | - Regex: '.*' 99 | Priority: 3 100 | SortPriority: 0 101 | CaseSensitive: false 102 | IncludeIsMainRegex: '([-_](test|unittest))?$' 103 | IncludeIsMainSourceRegex: '' 104 | IndentAccessModifiers: false 105 | IndentCaseLabels: true 106 | IndentCaseBlocks: true 107 | IndentGotoLabels: true 108 | IndentPPDirectives: BeforeHash 109 | IndentExternBlock: Indent 110 | IndentRequires: true 111 | IndentWidth: 4 112 | IndentWrappedFunctionNames: false 113 | InsertTrailingCommas: None 114 | JavaScriptQuotes: Leave 115 | JavaScriptWrapImports: true 116 | KeepEmptyLinesAtTheStartOfBlocks: false 117 | LambdaBodyIndentation: Signature 118 | MacroBlockBegin: '' 119 | MacroBlockEnd: '' 120 | MaxEmptyLinesToKeep: 1 121 | NamespaceIndentation: Inner 122 | ObjCBinPackProtocolList: Never 123 | ObjCBlockIndentWidth: 2 124 | ObjCBreakBeforeNestedBlockParam: true 125 | ObjCSpaceAfterProperty: true 126 | ObjCSpaceBeforeProtocolList: true 127 | PenaltyBreakAssignment: 2 128 | PenaltyBreakBeforeFirstCallParameter: 1 129 | PenaltyBreakComment: 300 130 | PenaltyBreakFirstLessLess: 120 131 | PenaltyBreakOpenParenthesis: 0 132 | PenaltyBreakString: 1000 133 | PenaltyBreakTemplateDeclaration: 10 134 | PenaltyExcessCharacter: 1000000 135 | PenaltyReturnTypeOnItsOwnLine: 200 136 | PenaltyIndentedWhitespace: 0 137 | PointerAlignment: Right 138 | PPIndentWidth: -1 139 | QualifierAlignment: Left 140 | RawStringFormats: 141 | - Language: Cpp 142 | Delimiters: 143 | - cc 144 | - CC 145 | - cpp 146 | - Cpp 147 | - CPP 148 | - 'c++' 149 | - 'C++' 150 | CanonicalDelimiter: '' 151 | BasedOnStyle: google 152 | - Language: TextProto 153 | Delimiters: 154 | - pb 155 | - PB 156 | - proto 157 | - PROTO 158 | EnclosingFunctions: 159 | - EqualsProto 160 | - EquivToProto 161 | - PARSE_PARTIAL_TEXT_PROTO 162 | - PARSE_TEST_PROTO 163 | - PARSE_TEXT_PROTO 164 | - ParseTextOrDie 165 | - ParseTextProtoOrDie 166 | - ParseTestProto 167 | - ParsePartialTestProto 168 | CanonicalDelimiter: pb 169 | BasedOnStyle: google 170 | ReferenceAlignment: Pointer 171 | ReflowComments: true 172 | RemoveBracesLLVM: false 173 | SeparateDefinitionBlocks: Leave 174 | ShortNamespaceLines: 1 175 | SortIncludes: Never 176 | SortJavaStaticImport: Before 177 | SortUsingDeclarations: false 178 | SpaceAfterCStyleCast: false 179 | SpaceAfterLogicalNot: false 180 | SpaceAfterTemplateKeyword: true 181 | SpaceBeforeAssignmentOperators: true 182 | SpaceBeforeCaseColon: false 183 | SpaceBeforeCpp11BracedList: true 184 | SpaceBeforeCtorInitializerColon: false 185 | SpaceBeforeInheritanceColon: false 186 | SpaceBeforeParens: Custom 187 | SpaceBeforeParensOptions: 188 | AfterControlStatements: true 189 | AfterForeachMacros: true 190 | AfterFunctionDefinitionName: false 191 | AfterFunctionDeclarationName: false 192 | AfterIfMacros: true 193 | AfterOverloadedOperator: false 194 | BeforeNonEmptyParentheses: false 195 | SpaceAroundPointerQualifiers: Default 196 | SpaceBeforeRangeBasedForLoopColon: true 197 | SpaceBeforeSquareBrackets: false 198 | SpaceInEmptyBlock: false 199 | SpaceInEmptyParentheses: false 200 | SpacesBeforeTrailingComments: 1 201 | SpacesInAngles: Never 202 | SpacesInConditionalStatement: false 203 | SpacesInContainerLiterals: false 204 | SpacesInCStyleCastParentheses: false 205 | SpacesInLineCommentPrefix: 206 | Minimum: 1 207 | Maximum: -1 208 | SpacesInParentheses: false 209 | SpacesInSquareBrackets: false 210 | SpaceBeforeSquareBrackets: false 211 | BitFieldColonSpacing: Both 212 | Standard: Auto 213 | StatementAttributeLikeMacros: 214 | - Q_EMIT 215 | StatementMacros: 216 | - Q_UNUSED 217 | - QT_REQUIRE_VERSION 218 | TabWidth: 4 219 | UseCRLF: true 220 | UseTab: ForContinuationAndIndentation 221 | WhitespaceSensitiveMacros: 222 | - STRINGIZE 223 | - PP_STRINGIZE 224 | - BOOST_PP_STRINGIZE 225 | - NS_SWIFT_NAME 226 | - CF_SWIFT_NAME 227 | ... 228 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BugReport.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Report a bug. 3 | labels: ["bug"] 4 | 5 | body: 6 | - type: textarea 7 | id: description 8 | validations: 9 | required: true 10 | attributes: 11 | label: Describe the Bug 12 | description: | 13 | Please describe the bug. (Causation, influence, etc) 14 | placeholder: | 15 | (Description) 16 | - type: textarea 17 | id: details 18 | validations: 19 | required: true 20 | attributes: 21 | label: Detailed Information 22 | description: | 23 | Please add screenshots, console outputs and log file contents here. 24 | placeholder: | 25 | (Screenshot) 26 | 27 | ```plain 28 | Console Output 29 | ``` 30 | 31 | ```plain 32 | Log File 33 | ``` 34 | - type: textarea 35 | id: version 36 | validations: 37 | required: true 38 | attributes: 39 | label: Program Version 40 | description: | 41 | Which version of the program are you using? 42 | placeholder: | 43 | ```plain 44 | e.g. 45 | 1.0.0 46 | 2.0.1-beta.4 47 | 2.1.0-rc.1 48 | 2.1.2-alpha.1 49 | ``` 50 | - type: textarea 51 | id: environment 52 | validations: 53 | required: true 54 | attributes: 55 | label: Environment 56 | description: | 57 | Get your environment information by running command `sysinfo`. 58 | placeholder: | 59 | ```plain 60 | e.g. 61 | OS version: 10.0.22623 62 | OS architecture: x64 63 | Program architecture: x86 64 | ``` 65 | - type: textarea 66 | id: other 67 | attributes: 68 | label: Other Information 69 | description: | 70 | Tell us anything else you think we should know. 71 | - type: dropdown 72 | id: self-bugfix 73 | validations: 74 | required: true 75 | attributes: 76 | label: Self Bugfix 77 | description: Are you going to fix this bug by yourself? 78 | options: 79 | - "Yes" 80 | - "No" 81 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BugReport.zh-CN.yml: -------------------------------------------------------------------------------- 1 | name: 故障报告 2 | description: 报告一个故障. 3 | labels: ["bug"] 4 | 5 | body: 6 | - type: textarea 7 | id: description 8 | validations: 9 | required: true 10 | attributes: 11 | label: 故障描述 12 | description: | 13 | 请描述这个故障. (触发方式和带来影响等) 14 | placeholder: | 15 | (描述) 16 | - type: textarea 17 | id: details 18 | validations: 19 | required: true 20 | attributes: 21 | label: 细节信息 22 | description: | 23 | 请在这里加入屏幕截图, 控制台输出和日志文件. 24 | placeholder: | 25 | (屏幕截图) 26 | 27 | ```plain 28 | 控制台输出 29 | ``` 30 | 31 | ```plain 32 | 日志文件 33 | ``` 34 | - type: textarea 35 | id: version 36 | validations: 37 | required: true 38 | attributes: 39 | label: 程序版本 40 | description: | 41 | 您在使用哪个版本? 42 | placeholder: | 43 | ```plain 44 | 例: 45 | 1.0.0 46 | 2.0.1-beta.4 47 | 2.1.0-rc.1 48 | 2.1.2-alpha.1 49 | ``` 50 | - type: textarea 51 | id: environment 52 | validations: 53 | required: true 54 | attributes: 55 | label: 环境 56 | description: | 57 | 通过运行 `sysinfo` 命令获取环境信息. 58 | placeholder: | 59 | ```plain 60 | 例: 61 | 操作系统版本: 10.0.22623 62 | 操作系统架构: x64 63 | 程序架构: x86 64 | ``` 65 | - type: textarea 66 | id: other 67 | attributes: 68 | label: 其它信息 69 | description: | 70 | 请告诉我们其它您觉得我们需要知道的信息. 71 | - type: dropdown 72 | id: self-bugfix 73 | validations: 74 | required: true 75 | attributes: 76 | label: 是否自己修复故障 77 | description: 您将要自己修复这个故障吗? 78 | options: 79 | - 是 80 | - 否 81 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FeatureRequest.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Request a feature. 3 | labels: ["enhancement"] 4 | 5 | body: 6 | - type: textarea 7 | id: description 8 | validations: 9 | required: true 10 | attributes: 11 | label: Describe the Feature 12 | description: | 13 | Please describe the feature. (Causation, influence, etc) 14 | placeholder: | 15 | (Description) 16 | - type: textarea 17 | id: details 18 | attributes: 19 | label: Detailed Information 20 | description: | 21 | Please add expected screenshots here. (If any) 22 | placeholder: | 23 | (Screenshot) 24 | - type: textarea 25 | id: other 26 | attributes: 27 | label: Other Information 28 | description: | 29 | Tell us anything else you think we should know. 30 | - type: dropdown 31 | id: self-resolve 32 | validations: 33 | required: true 34 | attributes: 35 | label: Self Resolve 36 | description: Are you going to resolve this feature by yourself? 37 | options: 38 | - "Yes" 39 | - "No" 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FeatureRequest.zh-CN.yml: -------------------------------------------------------------------------------- 1 | name: 特性请求 2 | description: 请求一个特性. 3 | labels: ["enhancement"] 4 | 5 | body: 6 | - type: textarea 7 | id: description 8 | validations: 9 | required: true 10 | attributes: 11 | label: 特性描述 12 | description: | 13 | 请描述这个特性. (触发方式和带来影响等) 14 | placeholder: | 15 | (描述) 16 | - type: textarea 17 | id: details 18 | attributes: 19 | label: 细节信息 20 | description: | 21 | 请加入您的期望特性屏幕截图. (如果有) 22 | placeholder: | 23 | (屏幕截图) 24 | - type: textarea 25 | id: other 26 | attributes: 27 | label: 其它信息 28 | description: | 29 | 请告诉我们其它您觉得我们需要知道的信息. 30 | - type: dropdown 31 | id: self-resolve 32 | validations: 33 | required: true 34 | attributes: 35 | label: 是否自己实现特性 36 | description: 您将要自己实现这个特性吗? 37 | options: 38 | - 是 39 | - 否 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Class Tools Develop Team QQ Group 4 | url: https://jq.qq.com/?_wv=1027&k=PYH4ldDF 5 | about: Discuss with our team members here. 6 | - name: Class Tools Develop Team Official Website 7 | url: https://class-tools.github.io 8 | about: See introductions of our team here. 9 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/en-US.yml: -------------------------------------------------------------------------------- 1 | name: PR en-US 2 | description: PR template for en-US. 3 | 4 | body: 5 | - type: textarea 6 | id: motivation 7 | validations: 8 | required: true 9 | attributes: 10 | label: Motivation 11 | description: | 12 | Please describe the motivation of this PR and the goal you want to achieve through this PR. 13 | placeholder: | 14 | (Motivation) 15 | - type: textarea 16 | id: modification 17 | validations: 18 | required: true 19 | attributes: 20 | label: Modification 21 | description: | 22 | Please briefly describe what modification is made in this PR. 23 | placeholder: | 24 | (Modification) 25 | - type: textarea 26 | id: other 27 | attributes: 28 | label: Other Information 29 | description: | 30 | Tell us anything else you think we should know. 31 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/zh-CN.yml: -------------------------------------------------------------------------------- 1 | name: PR zh-CN 2 | description: zh-CN PR 模板. 3 | 4 | body: 5 | - type: textarea 6 | id: motivation 7 | validations: 8 | required: true 9 | attributes: 10 | label: 原因 11 | description: | 12 | 请描述您新建此 PR 的原因与您想通过此 PR 达成什么目标. 13 | placeholder: | 14 | (原因) 15 | - type: textarea 16 | id: modification 17 | validations: 18 | required: true 19 | attributes: 20 | label: 更改 21 | description: | 22 | 请您主要说明此 PR 更改了什么. 23 | placeholder: | 24 | (更改) 25 | - type: textarea 26 | id: other 27 | attributes: 28 | label: 其它信息 29 | description: | 30 | 请告诉我们其它您觉得我们需要知道的信息. 31 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: "Build" 4 | 5 | on: [push, pull_request] 6 | 7 | jobs: 8 | build-x86: 9 | name: Build x86 10 | runs-on: windows-latest 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v3 14 | - name: Initialize vcpkg 15 | uses: johnwason/vcpkg-action@v4 16 | with: 17 | pkgs: jsoncpp openssl spdlog 18 | triplet: x86-windows-static 19 | token: ${{ github.token }} 20 | - name: Build solution 21 | run: | 22 | .\vcpkg\vcpkg integrate install 23 | .\scripts\build.ps1 Release x86 24 | build-x64: 25 | name: Build x64 26 | runs-on: windows-latest 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v3 30 | - name: Initialize vcpkg 31 | uses: johnwason/vcpkg-action@v4 32 | with: 33 | pkgs: jsoncpp openssl spdlog 34 | triplet: x64-windows-static 35 | token: ${{ github.token }} 36 | - name: Build solution 37 | run: | 38 | .\vcpkg\vcpkg integrate install 39 | .\scripts\build.ps1 Release x64 40 | build-arm: 41 | name: Build ARM 42 | runs-on: windows-latest 43 | steps: 44 | - name: Checkout repository 45 | uses: actions/checkout@v3 46 | - name: Initialize vcpkg 47 | uses: johnwason/vcpkg-action@v4 48 | with: 49 | pkgs: jsoncpp openssl spdlog 50 | triplet: arm-windows-static 51 | token: ${{ github.token }} 52 | - name: Build solution 53 | run: | 54 | .\vcpkg\vcpkg integrate install 55 | .\scripts\build.ps1 Release ARM 56 | build-arm64: 57 | name: Build ARM64 58 | runs-on: windows-latest 59 | steps: 60 | - name: Checkout repository 61 | uses: actions/checkout@v3 62 | - name: Initialize vcpkg 63 | uses: johnwason/vcpkg-action@v4 64 | with: 65 | pkgs: jsoncpp openssl spdlog 66 | triplet: arm64-windows-static 67 | token: ${{ github.token }} 68 | - name: Build solution 69 | run: | 70 | .\vcpkg\vcpkg integrate install 71 | .\scripts\build.ps1 Release ARM64 72 | -------------------------------------------------------------------------------- /.github/workflows/clangformat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: "Lint" 4 | 5 | on: push 6 | 7 | jobs: 8 | check: 9 | name: Check 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v3 14 | - name: Run Clang Format 15 | uses: DoozyX/clang-format-lint-action@v0.14 16 | with: 17 | source: '.' 18 | exclude: './UnitTest/*' 19 | extensions: 'cpp,hpp' 20 | clangFormatVersion: 14 21 | inplace: True 22 | - name: Commit changes 23 | uses: EndBug/add-and-commit@v9 24 | with: 25 | default_author: github_actions 26 | message: 'SUM Adjust Source Code Format' 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | -------------------------------------------------------------------------------- /.github/workflows/codecov.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: "Codecov" 4 | 5 | on: [push, pull_request] 6 | 7 | jobs: 8 | analyze: 9 | name: Analyze 10 | runs-on: windows-latest 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v3 14 | - name: Initialize vcpkg 15 | uses: johnwason/vcpkg-action@v4 16 | with: 17 | pkgs: jsoncpp openssl spdlog 18 | triplet: x64-windows-static 19 | token: ${{ github.token }} 20 | - name: Build solution 21 | run: | 22 | .\vcpkg\vcpkg integrate install 23 | .\scripts\build.ps1 Release x64 24 | - name: Setup VSTest and add to PATH 25 | uses: darenm/Setup-VSTest@v1 26 | - name: Setup OpenCppCoverage and add to PATH 27 | run: | 28 | choco install OpenCppCoverage -y 29 | echo "C:\Program Files\OpenCppCoverage" >> $env:GITHUB_PATH 30 | - name: Generate report 31 | run: OpenCppCoverage --sources modules\apis.hpp --sources modules\basic.hpp --sources UnitTest\UnitTest.cpp --excluded_line_regex "\s*else.*" --excluded_line_regex "\s*\}.*" --export_type cobertura:WCH.xml -- "vstest.console.exe" x64\Release\UnitTest.dll 32 | - name: Upload report to Codecov 33 | uses: codecov/codecov-action@v3 34 | with: 35 | files: .\WCH.xml 36 | fail_ci_if_error: true 37 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: "CodeQL" 4 | 5 | on: [push, pull_request] 6 | 7 | jobs: 8 | analyze: 9 | name: Analyze 10 | runs-on: windows-latest 11 | permissions: 12 | security-events: write 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v3 16 | - name: Initialize vcpkg 17 | uses: johnwason/vcpkg-action@v4 18 | with: 19 | pkgs: jsoncpp openssl spdlog 20 | triplet: x64-windows-static 21 | token: ${{ github.token }} 22 | - name: Initialize CodeQL 23 | uses: github/codeql-action/init@v2 24 | with: 25 | languages: cpp 26 | queries: security-and-quality 27 | - name: Build solution 28 | run: | 29 | .\vcpkg\vcpkg integrate install 30 | .\scripts\build.ps1 Release x64 31 | - name: Perform CodeQL analysis 32 | uses: github/codeql-action/analyze@v2 33 | -------------------------------------------------------------------------------- /.github/workflows/gitmsg.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: "Commit" 4 | 5 | on: [push, pull_request] 6 | 7 | jobs: 8 | check: 9 | name: Check 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v3 14 | - name: Setup Node.js 15 | uses: actions/setup-node@v3 16 | with: 17 | node-version: 16 18 | - name: Check commit messages 19 | env: 20 | COMMIT_MSG: ${{ toJson(github.event.commits.*.message) }} 21 | run: | 22 | npm config set registry http://registry.npmjs.org/ 23 | yarn config set registry https://registry.yarnpkg.com 24 | yarn add ct-git-commit-msg-std 25 | node ./node_modules/ct-git-commit-msg-std/check.js -c "$PWD/.gitmsgrc.cjs" -e COMMIT_MSG 26 | -------------------------------------------------------------------------------- /.github/workflows/wiki.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: "Wiki" 4 | 5 | on: 6 | push: 7 | branches: master 8 | 9 | jobs: 10 | update-wiki: 11 | name: Update Wiki 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Update Wiki 15 | uses: OrlovM/Wiki-Action@v1 16 | with: 17 | path: 'wiki' 18 | token: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /x64/ 2 | /x86/ 3 | /ARM/ 4 | /ARM64/ 5 | /UnitTest/x64/ 6 | /UnitTest/x86/ 7 | /UnitTest/ARM/ 8 | /UnitTest/ARM64/ 9 | /.vscode/ 10 | /.vs/ 11 | -------------------------------------------------------------------------------- /.gitmsgrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | debug: false, 3 | itemTy: o => o.concat(""), 4 | checker: {} 5 | } 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | **English** | [简体中文](./CONTRIBUTING.zh-CN.md) 4 | 5 | Welcome to Web Class Helper! 6 | 7 | Thanks for contributing, and thanks for reading this document before doing it! 8 | 9 | The [project wiki](https://github.com/class-tools/Web-Class-Helper/wiki) contains information about how to get started, how the program works, and more. 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.zh-CN.md: -------------------------------------------------------------------------------- 1 | ## 贡献 2 | 3 | [English](./CONTRIBUTING.md) | **简体中文** 4 | 5 | 欢迎来到 Web Class Helper! 6 | 7 | 感谢您的贡献,也感谢您在做这之前阅读本文档! 8 | 9 | [项目 Wiki](https://github.com/class-tools/Web-Class-Helper/wiki) 包含了关于如何开始使用、程序的工作方式等等信息。 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 - 2023 Class Tools Develop Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Warning: This project was archived, all the branches of this repository will never be worked on. If you want to continue developing, the branch `gui` (broken) can be referenced. 2 | 3 |

4 | 5 |

6 | 7 |

- Web Class Helper -

8 | 9 |

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |

24 | 25 | A command line tool using with online class. 26 | 27 | **English** | [简体中文](./README.zh-CN.md) 28 | 29 | ### Contributors 30 | 31 | |
ren-yc (Yuchen Ren) |
jsh-jsh (jinshuhang) |
hjl2011 | 32 | | :---: | :---: | :---: | 33 | | ![](https://shields.io/badge/Maintainer-green?logo=visual-studio-code&style=for-the-badge)
![](https://shields.io/badge/BugTester-yellow?logo=open-bug-bounty&style=for-the-badge) | ![](https://shields.io/badge/Creator-green?logo=visual-studio-code&style=for-the-badge)
![](https://shields.io/badge/BugTester-yellow?logo=open-bug-bounty&style=for-the-badge) | ![](https://shields.io/badge/Coding-green?logo=visual-studio-code&style=for-the-badge)
![](https://shields.io/badge/BugTester-yellow?logo=open-bug-bounty&style=for-the-badge) | 34 | 35 | **For more information, please go to [Wiki](https://github.com/class-tools/Web-Class-Helper/wiki)**. 36 | -------------------------------------------------------------------------------- /README.zh-CN.md: -------------------------------------------------------------------------------- 1 | # 警告: 此项目已被归档, 此存储库的所有分支将永远不会被处理. 如果你希望继续开发, 分支 `gui` (损坏) 可以被参考. 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 | [English](./README.md) | **简体中文** 28 | 29 | ### 贡献名单 30 | 31 | |
ren-yc (Yuchen Ren) |
jsh-jsh (jinshuhang) |
hjl2011 | 32 | | :---: | :---: | :---: | 33 | | ![](https://shields.io/badge/Maintainer-green?logo=visual-studio-code&style=for-the-badge)
![](https://shields.io/badge/BugTester-yellow?logo=open-bug-bounty&style=for-the-badge) | ![](https://shields.io/badge/Creator-green?logo=visual-studio-code&style=for-the-badge)
![](https://shields.io/badge/BugTester-yellow?logo=open-bug-bounty&style=for-the-badge) | ![](https://shields.io/badge/Coding-green?logo=visual-studio-code&style=for-the-badge)
![](https://shields.io/badge/BugTester-yellow?logo=open-bug-bounty&style=for-the-badge) | 34 | 35 | **更多信息请至 [Wiki](https://github.com/class-tools/Web-Class-Helper/wiki)**。 36 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security Policy 2 | 3 | **English** | [简体中文](./SECURITY.zh-CN.md) 4 | 5 | ## Supported Operating Systems 6 | 7 | | Windows Version | Supported | 8 | | :---: | :---: | 9 | | 10.0.x.y | ✅ | 10 | | 6.3.x.y | ✅ | 11 | | 6.2.x.y | ✅ | 12 | | 6.1.x.y | ❓ | 13 | | < 6.1.0.0 | ❌ | 14 | 15 | ## Supported CPU Architectures 16 | 17 | * x64 18 | 19 | * x86 20 | 21 | * ARM 22 | 23 | * ARM64 24 | 25 | ## Reporting a Vulnerability 26 | 27 | Please use private ways to contact maintainers of this project like E-mail. 28 | 29 | DO NOT USE PUBLIC WAYS LIKE GITHUB ISSUES! 30 | -------------------------------------------------------------------------------- /SECURITY.zh-CN.md: -------------------------------------------------------------------------------- 1 | ## 安全性策略 2 | 3 | [English](./SECURITY.md) | **简体中文** 4 | 5 | ## 受支持的操作系统 6 | 7 | | Windows 版本 | 受支持性 | 8 | | :---: | :---: | 9 | | 10.0.x.y | ✅ | 10 | | 6.3.x.y | ✅ | 11 | | 6.2.x.y | ✅ | 12 | | 6.1.x.y | ❓ | 13 | | < 6.1.0.0 | ❌ | 14 | 15 | ## 受支持的 CPU 架构 16 | 17 | * x64 18 | 19 | * x86 20 | 21 | * ARM 22 | 23 | * ARM64 24 | 25 | ## 报告漏洞 26 | 27 | 请使用非公开的方式联系本项目的维护者,如 E-mail。 28 | 29 | 请不要使用公开的方式,如 GitHub Issues! 30 | -------------------------------------------------------------------------------- /UnitTest/UnitTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper Unit Test Main File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: ren-yc 6 | */ 7 | #include "../version.hpp" 8 | #include "../shasum.hpp" 9 | #include "../modules/file-process.hpp" 10 | #include "../modules/init.hpp" 11 | #include "../modules/commands.hpp" 12 | #include "../modules/functions.hpp" 13 | #include "../modules/apis.hpp" 14 | #include "../modules/basic.hpp" 15 | #include "CppUnitTest.h" 16 | 17 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 18 | 19 | namespace APIs { 20 | TEST_CLASS(String) { 21 | public: 22 | TEST_METHOD(StrConvert) { 23 | Assert::AreEqual(StrToWstr("Test").c_str(), L"Test"); 24 | Assert::AreEqual(WstrToStr(L"Test").c_str(), "Test"); 25 | Assert::AreEqual(StrToWstr("测试").c_str(), L"测试"); 26 | Assert::AreEqual(WstrToStr(L"测试").c_str(), "测试"); 27 | Assert::AreEqual(StrToWstr("テスト").c_str(), L"テスト"); 28 | Assert::AreEqual(WstrToStr(L"テスト").c_str(), "テスト"); 29 | } 30 | TEST_METHOD(EncodeURL) { 31 | Assert::AreEqual(UrlEncode("测试").c_str(), "%E6%B5%8B%E8%AF%95"); 32 | Assert::AreEqual(UrlEncode("测 试").c_str(), "%E6%B5%8B+%E8%AF%95"); 33 | Assert::AreEqual(UrlEncode("测.试").c_str(), "%E6%B5%8B.%E8%AF%95"); 34 | Assert::AreEqual(UrlEncode("测A试").c_str(), "%E6%B5%8BA%E8%AF%95"); 35 | } 36 | TEST_METHOD(StrSplit) { 37 | Assert::IsTrue(WCH_split(L"A BC") == []() { 38 | vector _tmp = {L"A", L"BC"}; 39 | return _tmp; 40 | }()); 41 | Assert::IsTrue(WCH_split(L"\"A B\" C") == []() { 42 | vector _tmp = {L"A B", L"C"}; 43 | return _tmp; 44 | }()); 45 | Assert::IsTrue(WCH_split(L"A B C") == []() { 46 | vector _tmp = {L"A", L"B", L"C"}; 47 | return _tmp; 48 | }()); 49 | Assert::IsTrue(WCH_split(L"你 \"好 啊\"") == []() { 50 | vector _tmp = {L"你", L"好 啊"}; 51 | return _tmp; 52 | }()); 53 | Assert::IsTrue(WCH_split(L"A B C\"") == []() { 54 | vector _tmp = {L"Incorrect"}; 55 | return _tmp; 56 | }()); 57 | } 58 | TEST_METHOD(StrDisplaySize) { 59 | Assert::AreEqual(WCH_GetWstrDisplaySize(L"Test"), (size_t)4); 60 | Assert::AreEqual(WCH_GetWstrDisplaySize(L"测试"), (size_t)4); 61 | Assert::AreEqual(WCH_GetWstrDisplaySize(L"テスト"), (size_t)6); 62 | Assert::AreEqual(WCH_GetWstrDisplaySize(L"T测テ"), (size_t)5); 63 | } 64 | TEST_METHOD(NewlineCount) { 65 | Assert::AreEqual(WCH_NewlineCount(L"\nTest\n"), (size_t)2); 66 | Assert::AreEqual(WCH_NewlineCount(L"\n\n\n"), (size_t)3); 67 | } 68 | }; 69 | 70 | TEST_CLASS(Version) { 71 | public: 72 | TEST_METHOD(CheckVersion) { 73 | WCH_Version Temp1 = {0, 0, 0}, Temp2 = {2147483647, 2147483647, 2147483647}; 74 | Assert::IsFalse(Temp1 < Temp1); 75 | Assert::IsTrue(Temp1 < Temp2); 76 | } 77 | TEST_METHOD(GetVersion) { 78 | WCH_Version Temp; 79 | Temp = {0, 0, 0}; 80 | Assert::IsTrue(WCH_GetVersion(L"0.0.0") == Temp); 81 | Temp = {2147483647, 2147483647, 2147483647}; 82 | Assert::IsTrue(WCH_GetVersion(L"2147483647.2147483647.2147483647") == Temp); 83 | } 84 | }; 85 | 86 | TEST_CLASS(Other) { 87 | public: 88 | TEST_METHOD(NumDigits) { 89 | Assert::AreEqual(WCH_GetNumDigits((size_t)0), (size_t)1); 90 | Assert::AreEqual(WCH_GetNumDigits((size_t)18446744073709551615), (size_t)20); 91 | } 92 | TEST_METHOD(CheckConfigValid) { 93 | pair Temp; 94 | Temp = WCH_CheckConfigValid(L"FocusEndContent", L"Test"); 95 | Assert::IsTrue(Temp.first); 96 | Assert::AreEqual(Temp.second.c_str(), L"String"); 97 | Temp = WCH_CheckConfigValid(L"FocusEndPrompt", L"True"); 98 | Assert::IsTrue(Temp.first); 99 | Assert::AreEqual(Temp.second.c_str(), L"Boolean"); 100 | Temp = WCH_CheckConfigValid(L"FocusKillInterval", L"2147483647"); 101 | Assert::IsFalse(Temp.first); 102 | Assert::AreEqual(Temp.second.c_str(), L"String"); 103 | Temp = WCH_CheckConfigValid(L"FocusKillInterval", L"60000"); 104 | Assert::IsTrue(Temp.first); 105 | Assert::AreEqual(Temp.second.c_str(), L"Number"); 106 | Temp = WCH_CheckConfigValid(L"Language", L"Test"); 107 | Assert::IsFalse(Temp.first); 108 | Assert::AreEqual(Temp.second.c_str(), L"String"); 109 | Temp = WCH_CheckConfigValid(L"ScreenshotSavePath", L"C:\\Test"); 110 | Assert::IsFalse(Temp.first); 111 | Assert::AreEqual(Temp.second.c_str(), L"String"); 112 | Temp = WCH_CheckConfigValid(L"Test", L"Test"); 113 | Assert::IsFalse(Temp.first); 114 | Assert::AreEqual(Temp.second.c_str(), L"String"); 115 | } 116 | }; 117 | } 118 | -------------------------------------------------------------------------------- /UnitTest/UnitTest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Debug 9 | Win32 10 | 11 | 12 | Release 13 | Win32 14 | 15 | 16 | Debug 17 | x64 18 | 19 | 20 | Release 21 | x64 22 | 23 | 24 | Debug 25 | ARM 26 | 27 | 28 | Release 29 | ARM 30 | 31 | 32 | Debug 33 | ARM64 34 | 35 | 36 | Release 37 | ARM64 38 | 39 | 40 | 41 | 17.0 42 | {386F008D-1D4D-4237-9721-846B013DFC35} 43 | Win32Proj 44 | UnitTest 45 | 10.0 46 | NativeUnitTestProject 47 | 48 | 49 | 50 | DynamicLibrary 51 | true 52 | v143 53 | Unicode 54 | false 55 | 56 | 57 | DynamicLibrary 58 | false 59 | v143 60 | true 61 | Unicode 62 | false 63 | 64 | 65 | DynamicLibrary 66 | true 67 | v143 68 | Unicode 69 | false 70 | 71 | 72 | DynamicLibrary 73 | false 74 | v143 75 | true 76 | Unicode 77 | false 78 | 79 | 80 | DynamicLibrary 81 | true 82 | v143 83 | false 84 | Unicode 85 | false 86 | 87 | 88 | DynamicLibrary 89 | false 90 | v143 91 | true 92 | Unicode 93 | false 94 | 95 | 96 | DynamicLibrary 97 | true 98 | v143 99 | false 100 | Unicode 101 | false 102 | 103 | 104 | DynamicLibrary 105 | false 106 | v143 107 | true 108 | Unicode 109 | false 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | true 143 | $(PlatformShortName)\$(Configuration)\ 144 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 145 | 146 | 147 | false 148 | $(PlatformShortName)\$(Configuration)\ 149 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 150 | 151 | 152 | true 153 | $(PlatformShortName)\$(Configuration)\ 154 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 155 | 156 | 157 | false 158 | $(PlatformShortName)\$(Configuration)\ 159 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 160 | 161 | 162 | true 163 | $(PlatformShortName)\$(Configuration)\ 164 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 165 | 166 | 167 | false 168 | $(PlatformShortName)\$(Configuration)\ 169 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 170 | 171 | 172 | true 173 | $(PlatformShortName)\$(Configuration)\ 174 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 175 | 176 | 177 | false 178 | $(PlatformShortName)\$(Configuration)\ 179 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 180 | 181 | 182 | Debug 183 | true 184 | 185 | 186 | Release 187 | true 188 | 189 | 190 | Debug 191 | true 192 | 193 | 194 | Release 195 | true 196 | 197 | 198 | Debug 199 | true 200 | 201 | 202 | Release 203 | true 204 | 205 | 206 | Debug 207 | true 208 | 209 | 210 | Release 211 | true 212 | 213 | 214 | 215 | Level3 216 | true 217 | %(AdditionalIncludeDirectories) 218 | WIN32;_DEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 219 | true 220 | stdcpplatest 221 | /utf-8 /D WCH_Framework=L\"x86\" %(AdditionalOptions) 222 | MultiThreadedDebug 223 | 224 | 225 | Windows 226 | %(AdditionalLibraryDirectories) 227 | 228 | 229 | 230 | 231 | Level3 232 | true 233 | true 234 | true 235 | %(AdditionalIncludeDirectories) 236 | WIN32;NDEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 237 | true 238 | stdcpplatest 239 | /utf-8 /D WCH_Framework=L\"x86\" %(AdditionalOptions) 240 | MultiThreaded 241 | 242 | 243 | Windows 244 | true 245 | true 246 | %(AdditionalLibraryDirectories) 247 | UseFastLinkTimeCodeGeneration 248 | 249 | 250 | 251 | 252 | Level3 253 | true 254 | %(AdditionalIncludeDirectories) 255 | _DEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 256 | true 257 | stdcpplatest 258 | /utf-8 /D WCH_Framework=L\"x64\" %(AdditionalOptions) 259 | MultiThreadedDebug 260 | 261 | 262 | Windows 263 | %(AdditionalLibraryDirectories) 264 | 265 | 266 | 267 | 268 | Level3 269 | true 270 | true 271 | true 272 | %(AdditionalIncludeDirectories) 273 | NDEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 274 | true 275 | stdcpplatest 276 | /utf-8 /D WCH_Framework=L\"x64\" %(AdditionalOptions) 277 | MultiThreaded 278 | 279 | 280 | Windows 281 | true 282 | true 283 | %(AdditionalLibraryDirectories) 284 | UseFastLinkTimeCodeGeneration 285 | 286 | 287 | 288 | 289 | Level3 290 | true 291 | %(AdditionalIncludeDirectories) 292 | _DEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 293 | true 294 | stdcpplatest 295 | /utf-8 /D WCH_Framework=L\"ARM\" %(AdditionalOptions) 296 | MultiThreadedDebug 297 | 298 | 299 | Windows 300 | %(AdditionalLibraryDirectories) 301 | 302 | 303 | 304 | 305 | Level3 306 | true 307 | true 308 | true 309 | %(AdditionalIncludeDirectories) 310 | NDEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 311 | true 312 | stdcpplatest 313 | /utf-8 /D WCH_Framework=L\"ARM\" %(AdditionalOptions) 314 | MultiThreaded 315 | 316 | 317 | Windows 318 | true 319 | true 320 | %(AdditionalLibraryDirectories) 321 | UseFastLinkTimeCodeGeneration 322 | 323 | 324 | 325 | 326 | Level3 327 | true 328 | %(AdditionalIncludeDirectories) 329 | _DEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 330 | true 331 | stdcpplatest 332 | /utf-8 /D WCH_Framework=L\"ARM64\" %(AdditionalOptions) 333 | MultiThreadedDebug 334 | 335 | 336 | Windows 337 | %(AdditionalLibraryDirectories) 338 | 339 | 340 | 341 | 342 | Level3 343 | true 344 | true 345 | true 346 | %(AdditionalIncludeDirectories) 347 | NDEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 348 | true 349 | stdcpplatest 350 | /utf-8 /D WCH_Framework=L\"ARM64\" %(AdditionalOptions) 351 | MultiThreaded 352 | 353 | 354 | Windows 355 | true 356 | true 357 | %(AdditionalLibraryDirectories) 358 | UseFastLinkTimeCodeGeneration 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | -------------------------------------------------------------------------------- /UnitTest/UnitTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 9 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 10 | 11 | 12 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 13 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 14 | 15 | 16 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 17 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UnitTest/UnitTest.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WCH.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper Main File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: jsh-jsh ren-yc 6 | */ 7 | #include "version.hpp" 8 | #include "shasum.hpp" 9 | #include "./modules/file-process.hpp" 10 | #include "./modules/init.hpp" 11 | #include "./modules/commands.hpp" 12 | #include "./modules/functions.hpp" 13 | #include "./modules/apis.hpp" 14 | #include "./modules/basic.hpp" 15 | 16 | extern const vector WCH_list_weekday; 17 | extern const map> WCH_choice_settings; 18 | extern const map WCH_MIME_list; 19 | extern const map> WCH_support_command; 20 | extern const set> WCH_support_settings; 21 | extern const wstring WCH_progress_bar_str; 22 | extern const wstring WCH_path_data; 23 | extern const wstring WCH_path_temp; 24 | extern vector WCH_list_command; 25 | extern set> WCH_list_clock; 26 | extern set WCH_list_task; 27 | extern set> WCH_list_work; 28 | extern wstring WCH_version; 29 | extern wstring WCH_path_exec; 30 | extern wstring WCH_title_window; 31 | extern HWND WCH_handle_window; 32 | extern HWND WCH_handle_tray; 33 | extern HMENU WCH_handle_menu; 34 | extern NOTIFYICONDATAW WCH_NID; 35 | extern ATL::CComPtr WCH_TBL; 36 | extern Json::Value WCH_Settings; 37 | extern Json::Value WCH_Language; 38 | extern int32_t WCH_num_clock; 39 | extern int32_t WCH_num_task; 40 | extern int32_t WCH_num_work; 41 | extern int32_t WCH_progress_bar_duration; 42 | extern bool WCH_cmd_line; 43 | extern bool WCH_is_focus; 44 | extern bool WCH_is_countdown; 45 | extern bool WCH_program_end; 46 | extern bool WCH_pre_start; 47 | extern ifstream fin; 48 | extern wifstream wfin; 49 | extern ofstream fout; 50 | extern wofstream wfout; 51 | extern Json::Reader JSON_Reader; 52 | extern Json::StreamWriterBuilder JSON_SWB; 53 | extern unique_ptr JSON_SW; 54 | extern shared_ptr LOG_sink; 55 | extern shared_ptr LOG_logger; 56 | 57 | int32_t wmain(int32_t _argc, wchar_t* _argv[]) { 58 | WCH_Init(); 59 | if (_argc > 1) { 60 | SPDLOG_WARN(format(L"Number of redundant command line arguments: {}.", _argc - 1)); 61 | } 62 | WCH_path_exec = _argv[0]; 63 | while (true) { 64 | if (WCH_cmd_line) { 65 | WCH_CL_Init(); 66 | if (WCH_support_command.find(WCH_list_command[0]) != WCH_support_command.end()) { 67 | WCH_support_command.find(WCH_list_command[0])->second(); 68 | } else { 69 | WCH_InputCommandIncorrect(); 70 | } 71 | wcout << endl; 72 | } else { 73 | WCH_Sleep(1000); 74 | } 75 | } 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /WCH.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/class-tools/Web-Class-Helper/3073f972e38aa8feae0764f94d96d70261b044d5/WCH.ico -------------------------------------------------------------------------------- /WCH.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /WCH.rc: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper Resource File 2.1.2 3 | This source code file isn't under any license. 4 | Generator: Visual Studio 2022 5 | */ 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | #include "winres.h" 8 | #undef APSTUDIO_READONLY_SYMBOLS 9 | #if !defined(AFX_RESOURCE_DLL) 10 | #pragma code_page(65001) 11 | IDI_ICON ICON "WCH.ico" 12 | #endif 13 | -------------------------------------------------------------------------------- /WCH.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Web Class Helper Visual Studio Solution File 2.1.2 3 | # This source code file isn't under any license. 4 | # Generator: Visual Studio 2022 5 | VisualStudioVersion = 17.1.32421.90 6 | MinimumVisualStudioVersion = 10.0.40219.1 7 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WCH", "WCH.vcxproj", "{FE012BA5-908D-4839-B9DB-69B5B0F9106C}" 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{386F008D-1D4D-4237-9721-846B013DFC35}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|ARM = Debug|ARM 14 | Debug|ARM64 = Debug|ARM64 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|ARM = Release|ARM 18 | Release|ARM64 = Release|ARM64 19 | Release|x64 = Release|x64 20 | Release|x86 = Release|x86 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Debug|ARM.ActiveCfg = Debug|ARM 24 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Debug|ARM.Build.0 = Debug|ARM 25 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Debug|ARM64.ActiveCfg = Debug|ARM64 26 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Debug|ARM64.Build.0 = Debug|ARM64 27 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Debug|x64.ActiveCfg = Debug|x64 28 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Debug|x64.Build.0 = Debug|x64 29 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Debug|x86.ActiveCfg = Debug|Win32 30 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Debug|x86.Build.0 = Debug|Win32 31 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Release|ARM.ActiveCfg = Release|ARM 32 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Release|ARM.Build.0 = Release|ARM 33 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Release|ARM64.ActiveCfg = Release|ARM64 34 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Release|ARM64.Build.0 = Release|ARM64 35 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Release|x64.ActiveCfg = Release|x64 36 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Release|x64.Build.0 = Release|x64 37 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Release|x86.ActiveCfg = Release|Win32 38 | {FE012BA5-908D-4839-B9DB-69B5B0F9106C}.Release|x86.Build.0 = Release|Win32 39 | {386F008D-1D4D-4237-9721-846B013DFC35}.Debug|ARM.ActiveCfg = Debug|ARM 40 | {386F008D-1D4D-4237-9721-846B013DFC35}.Debug|ARM.Build.0 = Debug|ARM 41 | {386F008D-1D4D-4237-9721-846B013DFC35}.Debug|ARM64.ActiveCfg = Debug|ARM64 42 | {386F008D-1D4D-4237-9721-846B013DFC35}.Debug|ARM64.Build.0 = Debug|ARM64 43 | {386F008D-1D4D-4237-9721-846B013DFC35}.Debug|x64.ActiveCfg = Debug|x64 44 | {386F008D-1D4D-4237-9721-846B013DFC35}.Debug|x64.Build.0 = Debug|x64 45 | {386F008D-1D4D-4237-9721-846B013DFC35}.Debug|x86.ActiveCfg = Debug|Win32 46 | {386F008D-1D4D-4237-9721-846B013DFC35}.Debug|x86.Build.0 = Debug|Win32 47 | {386F008D-1D4D-4237-9721-846B013DFC35}.Release|ARM.ActiveCfg = Release|ARM 48 | {386F008D-1D4D-4237-9721-846B013DFC35}.Release|ARM.Build.0 = Release|ARM 49 | {386F008D-1D4D-4237-9721-846B013DFC35}.Release|ARM64.ActiveCfg = Release|ARM64 50 | {386F008D-1D4D-4237-9721-846B013DFC35}.Release|ARM64.Build.0 = Release|ARM64 51 | {386F008D-1D4D-4237-9721-846B013DFC35}.Release|x64.ActiveCfg = Release|x64 52 | {386F008D-1D4D-4237-9721-846B013DFC35}.Release|x64.Build.0 = Release|x64 53 | {386F008D-1D4D-4237-9721-846B013DFC35}.Release|x86.ActiveCfg = Release|Win32 54 | {386F008D-1D4D-4237-9721-846B013DFC35}.Release|x86.Build.0 = Release|Win32 55 | EndGlobalSection 56 | GlobalSection(SolutionProperties) = preSolution 57 | HideSolutionNode = FALSE 58 | EndGlobalSection 59 | GlobalSection(ExtensibilityGlobals) = postSolution 60 | SolutionGuid = {504FC256-BB0D-4BEF-A0D4-914324F2F955} 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /WCH.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Debug 9 | Win32 10 | 11 | 12 | Release 13 | Win32 14 | 15 | 16 | Debug 17 | x64 18 | 19 | 20 | Release 21 | x64 22 | 23 | 24 | Debug 25 | ARM 26 | 27 | 28 | Release 29 | ARM 30 | 31 | 32 | Debug 33 | ARM64 34 | 35 | 36 | Release 37 | ARM64 38 | 39 | 40 | 41 | 16.0 42 | Win32Proj 43 | {fe012ba5-908d-4839-b9db-69b5b0f9106c} 44 | WCH 45 | 10.0 46 | 47 | 48 | 49 | Application 50 | true 51 | v143 52 | Unicode 53 | false 54 | false 55 | 56 | 57 | Application 58 | false 59 | v143 60 | true 61 | Unicode 62 | false 63 | false 64 | 65 | 66 | Application 67 | true 68 | v143 69 | Unicode 70 | false 71 | false 72 | 73 | 74 | Application 75 | false 76 | v143 77 | true 78 | Unicode 79 | false 80 | false 81 | 82 | 83 | Application 84 | true 85 | v143 86 | Unicode 87 | false 88 | false 89 | 90 | 91 | Application 92 | false 93 | v143 94 | true 95 | Unicode 96 | false 97 | false 98 | 99 | 100 | Application 101 | true 102 | v143 103 | Unicode 104 | false 105 | false 106 | 107 | 108 | Application 109 | false 110 | v143 111 | true 112 | Unicode 113 | false 114 | false 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | false 148 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 149 | $(PlatformShortName)\$(Configuration)\ 150 | 151 | 152 | false 153 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 154 | $(PlatformShortName)\$(Configuration)\ 155 | 156 | 157 | false 158 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 159 | $(PlatformShortName)\$(Configuration)\ 160 | 161 | 162 | false 163 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 164 | $(PlatformShortName)\$(Configuration)\ 165 | 166 | 167 | false 168 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 169 | $(PlatformShortName)\$(Configuration)\ 170 | 171 | 172 | false 173 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 174 | $(PlatformShortName)\$(Configuration)\ 175 | 176 | 177 | false 178 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 179 | $(PlatformShortName)\$(Configuration)\ 180 | 181 | 182 | false 183 | $(SolutionDir)$(PlatformShortName)\$(Configuration)\ 184 | $(PlatformShortName)\$(Configuration)\ 185 | 186 | 187 | true 188 | 189 | 190 | true 191 | 192 | 193 | true 194 | 195 | 196 | true 197 | 198 | 199 | true 200 | 201 | 202 | true 203 | 204 | 205 | true 206 | 207 | 208 | true 209 | 210 | 211 | 212 | Level3 213 | true 214 | WIN32;_DEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 215 | true 216 | stdcpplatest 217 | /utf-8 /D WCH_Framework=L\"x86\" %(AdditionalOptions) 218 | %(AdditionalIncludeDirectories) 219 | ProgramDatabase 220 | $(OutDir)$(TargetName).pdb 221 | MultiThreadedDebug 222 | 223 | 224 | Console 225 | true 226 | %(AdditionalLibraryDirectories) 227 | $(CoreLibraryDependencies);%(AdditionalDependencies) 228 | 229 | 230 | WCH.manifest %(AdditionalManifestFiles) 231 | 232 | 233 | powershell -File .\scripts\shasum.ps1 234 | 235 | 236 | 237 | 238 | Level3 239 | true 240 | true 241 | true 242 | WIN32;NDEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 243 | true 244 | stdcpplatest 245 | /utf-8 /D WCH_Framework=L\"x86\" %(AdditionalOptions) 246 | %(AdditionalIncludeDirectories) 247 | $(OutDir)$(TargetName).pdb 248 | MultiThreaded 249 | 250 | 251 | Console 252 | true 253 | true 254 | true 255 | %(AdditionalLibraryDirectories) 256 | $(CoreLibraryDependencies);%(AdditionalDependencies) 257 | 258 | 259 | WCH.manifest %(AdditionalManifestFiles) 260 | 261 | 262 | powershell -File .\scripts\shasum.ps1 263 | 264 | 265 | 266 | 267 | Level3 268 | true 269 | _DEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 270 | true 271 | stdcpplatest 272 | /utf-8 /D WCH_Framework=L\"x64\" %(AdditionalOptions) 273 | %(AdditionalIncludeDirectories) 274 | ProgramDatabase 275 | $(OutDir)$(TargetName).pdb 276 | MultiThreadedDebug 277 | 278 | 279 | Console 280 | true 281 | %(AdditionalLibraryDirectories) 282 | $(CoreLibraryDependencies);%(AdditionalDependencies) 283 | 284 | 285 | WCH.manifest %(AdditionalManifestFiles) 286 | 287 | 288 | 289 | 290 | 291 | 292 | powershell -File .\scripts\shasum.ps1 293 | 294 | 295 | 296 | 297 | Level3 298 | true 299 | true 300 | true 301 | NDEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 302 | true 303 | stdcpplatest 304 | /utf-8 /D WCH_Framework=L\"x64\" %(AdditionalOptions) 305 | %(AdditionalIncludeDirectories) 306 | $(OutDir)$(TargetName).pdb 307 | MultiThreaded 308 | 309 | 310 | Console 311 | true 312 | true 313 | true 314 | %(AdditionalLibraryDirectories) 315 | $(CoreLibraryDependencies);%(AdditionalDependencies) 316 | 317 | 318 | WCH.manifest %(AdditionalManifestFiles) 319 | 320 | 321 | powershell -File .\scripts\shasum.ps1 322 | 323 | 324 | 325 | 326 | Level3 327 | true 328 | _DEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 329 | true 330 | stdcpplatest 331 | /utf-8 /D WCH_Framework=L\"ARM\" %(AdditionalOptions) 332 | %(AdditionalIncludeDirectories) 333 | ProgramDatabase 334 | $(OutDir)$(TargetName).pdb 335 | MultiThreadedDebug 336 | 337 | 338 | Console 339 | true 340 | %(AdditionalLibraryDirectories) 341 | $(CoreLibraryDependencies);%(AdditionalDependencies) 342 | 343 | 344 | WCH.manifest %(AdditionalManifestFiles) 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | powershell -File .\scripts\shasum.ps1 354 | 355 | 356 | 357 | 358 | Level3 359 | true 360 | true 361 | true 362 | NDEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 363 | true 364 | stdcpplatest 365 | /utf-8 /D WCH_Framework=L\"ARM\" %(AdditionalOptions) 366 | %(AdditionalIncludeDirectories) 367 | $(OutDir)$(TargetName).pdb 368 | MultiThreaded 369 | 370 | 371 | Console 372 | true 373 | true 374 | true 375 | %(AdditionalLibraryDirectories) 376 | $(CoreLibraryDependencies);%(AdditionalDependencies) 377 | 378 | 379 | WCH.manifest %(AdditionalManifestFiles) 380 | 381 | 382 | powershell -File .\scripts\shasum.ps1 383 | 384 | 385 | 386 | 387 | Level3 388 | true 389 | _DEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 390 | true 391 | stdcpplatest 392 | /utf-8 /D WCH_Framework=L\"ARM64\" %(AdditionalOptions) 393 | %(AdditionalIncludeDirectories) 394 | ProgramDatabase 395 | $(OutDir)$(TargetName).pdb 396 | MultiThreadedDebug 397 | 398 | 399 | Console 400 | true 401 | %(AdditionalLibraryDirectories) 402 | $(CoreLibraryDependencies);%(AdditionalDependencies) 403 | 404 | 405 | WCH.manifest %(AdditionalManifestFiles) 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | powershell -File .\scripts\shasum.ps1 415 | 416 | 417 | 418 | 419 | Level3 420 | true 421 | true 422 | true 423 | NDEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DISABLE_VECTOR_ANNOTATION;%(PreprocessorDefinitions) 424 | true 425 | stdcpplatest 426 | /utf-8 /D WCH_Framework=L\"ARM64\" %(AdditionalOptions) 427 | %(AdditionalIncludeDirectories) 428 | $(OutDir)$(TargetName).pdb 429 | MultiThreaded 430 | 431 | 432 | Console 433 | true 434 | true 435 | true 436 | %(AdditionalLibraryDirectories) 437 | $(CoreLibraryDependencies);%(AdditionalDependencies) 438 | 439 | 440 | WCH.manifest %(AdditionalManifestFiles) 441 | 442 | 443 | powershell -File .\scripts\shasum.ps1 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | Document 465 | 466 | 467 | Document 468 | 469 | 470 | Document 471 | $(OutDir)\resources\en-US 472 | $(OutDir)\resources\en-US 473 | $(OutDir)\resources\en-US 474 | $(OutDir)\resources\en-US 475 | $(OutDir)\resources\en-US 476 | $(OutDir)\resources\en-US 477 | $(OutDir)\resources\en-US 478 | $(OutDir)\resources\en-US 479 | 480 | 481 | Document 482 | $(OutDir)\resources\en-US 483 | $(OutDir)\resources\en-US 484 | $(OutDir)\resources\en-US 485 | $(OutDir)\resources\en-US 486 | $(OutDir)\resources\en-US 487 | $(OutDir)\resources\en-US 488 | $(OutDir)\resources\en-US 489 | $(OutDir)\resources\en-US 490 | 491 | 492 | Document 493 | $(OutDir)\resources\en-US 494 | $(OutDir)\resources\en-US 495 | $(OutDir)\resources\en-US 496 | $(OutDir)\resources\en-US 497 | $(OutDir)\resources\en-US 498 | $(OutDir)\resources\en-US 499 | $(OutDir)\resources\en-US 500 | $(OutDir)\resources\en-US 501 | 502 | 503 | Document 504 | $(OutDir)\resources\zh-CN 505 | $(OutDir)\resources\zh-CN 506 | $(OutDir)\resources\zh-CN 507 | $(OutDir)\resources\zh-CN 508 | $(OutDir)\resources\zh-CN 509 | $(OutDir)\resources\zh-CN 510 | $(OutDir)\resources\zh-CN 511 | $(OutDir)\resources\zh-CN 512 | 513 | 514 | Document 515 | $(OutDir)\resources\zh-CN 516 | $(OutDir)\resources\zh-CN 517 | $(OutDir)\resources\zh-CN 518 | $(OutDir)\resources\zh-CN 519 | $(OutDir)\resources\zh-CN 520 | $(OutDir)\resources\zh-CN 521 | $(OutDir)\resources\zh-CN 522 | $(OutDir)\resources\zh-CN 523 | 524 | 525 | Document 526 | $(OutDir)\resources\zh-CN 527 | $(OutDir)\resources\zh-CN 528 | $(OutDir)\resources\zh-CN 529 | $(OutDir)\resources\zh-CN 530 | $(OutDir)\resources\zh-CN 531 | $(OutDir)\resources\zh-CN 532 | $(OutDir)\resources\zh-CN 533 | $(OutDir)\resources\zh-CN 534 | 535 | 536 | 537 | 538 | -------------------------------------------------------------------------------- /WCH.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 9 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 10 | 11 | 12 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 13 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 14 | 15 | 16 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 17 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | 52 | 53 | Resource Files 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /WCH.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | target: 50% 6 | threshold: 100% 7 | base: auto 8 | patch: 9 | default: 10 | target: 50% 11 | threshold: 100% 12 | base: auto 13 | if_ci_failed: error 14 | only_pulls: true 15 | comment: 16 | layout: "reach, diff, flags, files, header, footer" 17 | behavior: new 18 | require_changes: false 19 | require_head: no 20 | require_base: no 21 | -------------------------------------------------------------------------------- /modules/apis.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper APIs Module Header File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: jsh-jsh ren-yc 6 | */ 7 | #ifndef APIS_H 8 | #define APIS_H 9 | #include "file-process.hpp" 10 | #include "init.hpp" 11 | #include "commands.hpp" 12 | #include "functions.hpp" 13 | #include "basic.hpp" 14 | 15 | extern const vector WCH_list_weekday; 16 | extern const map> WCH_choice_settings; 17 | extern const map WCH_MIME_list; 18 | extern const map> WCH_support_command; 19 | extern const set> WCH_support_settings; 20 | extern const wstring WCH_progress_bar_str; 21 | extern const wstring WCH_path_data; 22 | extern const wstring WCH_path_temp; 23 | extern vector WCH_list_command; 24 | extern set> WCH_list_clock; 25 | extern set WCH_list_task; 26 | extern set> WCH_list_work; 27 | extern wstring WCH_version; 28 | extern wstring WCH_path_exec; 29 | extern wstring WCH_title_window; 30 | extern HWND WCH_handle_window; 31 | extern HWND WCH_handle_tray; 32 | extern HMENU WCH_handle_menu; 33 | extern NOTIFYICONDATAW WCH_NID; 34 | extern ATL::CComPtr WCH_TBL; 35 | extern Json::Value WCH_Settings; 36 | extern Json::Value WCH_Language; 37 | extern int32_t WCH_num_clock; 38 | extern int32_t WCH_num_task; 39 | extern int32_t WCH_num_work; 40 | extern int32_t WCH_progress_bar_duration; 41 | extern bool WCH_cmd_line; 42 | extern bool WCH_is_focus; 43 | extern bool WCH_is_countdown; 44 | extern bool WCH_program_end; 45 | extern bool WCH_pre_start; 46 | extern ifstream fin; 47 | extern wifstream wfin; 48 | extern ofstream fout; 49 | extern wofstream wfout; 50 | extern Json::Reader JSON_Reader; 51 | extern Json::StreamWriterBuilder JSON_SWB; 52 | extern unique_ptr JSON_SW; 53 | extern shared_ptr LOG_sink; 54 | extern shared_ptr LOG_logger; 55 | 56 | void WCH_Sleep(int32_t _ms) { 57 | // Sleep. 58 | while (_ms > 0 && !WCH_program_end) { 59 | sleep_for(milliseconds(100)); 60 | _ms -= 100; 61 | } 62 | } 63 | 64 | void WCH_PrintColor(uint16_t _mode) { 65 | // Change console text color. 66 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), _mode); 67 | } 68 | 69 | void WCH_PrintChar(size_t _times, wchar_t _c) { 70 | // Print characters. 71 | while (_times > 0 && !WCH_program_end) { 72 | _times--; 73 | wcout << _c; 74 | } 75 | } 76 | 77 | size_t WCH_NewlineCount(const wstring& _in) { 78 | // Count newline characters in a wide string. 79 | size_t _cnt = 0; 80 | for (size_t i = 0; i < _in.size(); i++) { 81 | if (_in[i] == L'\n') { 82 | _cnt++; 83 | } 84 | } 85 | return _cnt; 86 | } 87 | 88 | void WCH_ClearConsole() { 89 | // Clear console. 90 | CONSOLE_SCREEN_BUFFER_INFO _csbi = {}; 91 | COORD _crd = {0, 0}; 92 | DWORD _nocw = 0; 93 | GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &_csbi); 94 | FillConsoleOutputCharacterW(GetStdHandle(STD_OUTPUT_HANDLE), L' ', _csbi.dwSize.X * _csbi.dwSize.Y, _crd, &_nocw); 95 | GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &_csbi); 96 | FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), _csbi.wAttributes, _csbi.dwSize.X * _csbi.dwSize.Y, _crd, &_nocw); 97 | SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), _crd); 98 | } 99 | 100 | wstring StrToWstr(const string& str) { 101 | // Convert multiple byte string to wide string. 102 | wstring result; 103 | int32_t len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int32_t)str.size(), NULL, 0); 104 | wchar_t* buffer = new wchar_t[(size_t)len + 1]; 105 | MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int32_t)str.size(), buffer, len); 106 | buffer[len] = '\0'; 107 | result.append(buffer); 108 | delete[] buffer; 109 | return result; 110 | } 111 | 112 | string WstrToStr(const wstring& wstr) { 113 | // Convert wide string to multiple byte string. 114 | string result; 115 | int32_t len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int32_t)wstr.size(), NULL, 0, NULL, NULL); 116 | char* buffer = new char[(size_t)len + 1]; 117 | WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int32_t)wstr.size(), buffer, len, NULL, NULL); 118 | buffer[len] = '\0'; 119 | result.append(buffer); 120 | delete[] buffer; 121 | return result; 122 | } 123 | 124 | string UrlEncode(const string& _in) { 125 | // Get URL encode result. 126 | string _res = ""; 127 | for (size_t i = 0; i < _in.size(); i++) { 128 | if (isalnum((uint8_t)_in[i]) || _in[i] == '-' || _in[i] == '_' || _in[i] == '.' || _in[i] == '~') { 129 | _res += _in[i]; 130 | } else if (_in[i] == ' ') { 131 | _res += "+"; 132 | } else { 133 | char _tmp1 = (uint8_t)_in[i] >> 4; 134 | char _tmp2 = (uint8_t)_in[i] % 16; 135 | _res += '%'; 136 | _res += _tmp1 > 9 ? _tmp1 + 55 : _tmp1 + 48; 137 | _res += _tmp2 > 9 ? _tmp2 + 55 : _tmp2 + 48; 138 | } 139 | } 140 | return _res; 141 | } 142 | 143 | vector WCH_split(const wstring& _input) { 144 | // Split CLI string. 145 | vector _res; 146 | wstring _tmp, _in; 147 | bool _flag = false; 148 | wchar_t last_ch; 149 | for (size_t i = 0; i < _input.size(); i++) { 150 | if (_input[i] == L'"') { 151 | _flag = true; 152 | _in.push_back(_input[i]); 153 | } else if (_flag) { 154 | if (_input[i] == L'"') { 155 | _flag = false; 156 | } 157 | _in.push_back(_input[i]); 158 | } else if (_input[i] != L' ') { 159 | _in.push_back(_input[i]); 160 | } else { 161 | if (_in.empty()) { 162 | last_ch = L' '; 163 | } else { 164 | last_ch = _in.back(); 165 | } 166 | if (last_ch != L' ') { 167 | _in.push_back(_input[i]); 168 | } 169 | } 170 | } 171 | _flag = false; 172 | for (size_t i = 0; i < _in.size(); i++) { 173 | if (_in[i] == L' ' && !_flag && i != 0) { 174 | if (_in[i - 1] != L'"') { 175 | _res.push_back(_tmp); 176 | _tmp = L""; 177 | } 178 | } else if (_in[i] == L'"') { 179 | if (_flag) { 180 | _res.push_back(_tmp); 181 | _tmp = L""; 182 | _flag = false; 183 | } else { 184 | _flag = true; 185 | } 186 | } else { 187 | _tmp.push_back(_in[i]); 188 | } 189 | } 190 | if (_tmp != L"") { 191 | _res.push_back(_tmp); 192 | } 193 | if (_flag || find(_res.begin(), _res.end(), L"") != _res.end()) { 194 | _res.clear(); 195 | _res.push_back(L"Incorrect"); 196 | } 197 | if (_res.size() != 0) { 198 | if (_res.size() != 1) { 199 | wstring _debug = format(L"Input command array: \"{}\", ", _res[0]); 200 | for (size_t i = 1; i < _res.size() - 1; i++) { 201 | _debug.append(format(L"\"{}\", ", _res[i])); 202 | } 203 | _debug.append(format(L"\"{}\"", _res[_res.size() - 1])); 204 | SPDLOG_INFO(_debug); 205 | } else { 206 | SPDLOG_INFO(format(L"Input command array: \"{}\"", _res[0])); 207 | } 208 | } 209 | return _res; 210 | } 211 | 212 | WCH_Time WCH_GetTime() { 213 | // Get current time and return a WCH_Time object. 214 | WCH_Time NowTime; 215 | time_t rawtime; 216 | struct tm ptminfo; 217 | time(&rawtime); 218 | localtime_s(&ptminfo, &rawtime); 219 | NowTime.Year = ptminfo.tm_year + 1900; 220 | NowTime.Month = ptminfo.tm_mon + 1; 221 | NowTime.Day = ptminfo.tm_mday; 222 | NowTime.Hour = ptminfo.tm_hour; 223 | NowTime.Minute = ptminfo.tm_min; 224 | NowTime.Second = ptminfo.tm_sec; 225 | return NowTime; 226 | } 227 | 228 | wstring WCH_GetCompileTime() { 229 | // Get program compile time. 230 | wstring spi = StrToWstr(__DATE__); 231 | map mon; 232 | mon[L"Jan"] = 1; 233 | mon[L"Feb"] = 2; 234 | mon[L"Mar"] = 3; 235 | mon[L"Apr"] = 4; 236 | mon[L"May"] = 5; 237 | mon[L"Jun"] = 6; 238 | mon[L"Jul"] = 7; 239 | mon[L"Aug"] = 8; 240 | mon[L"Sep"] = 9; 241 | mon[L"Oct"] = 10; 242 | mon[L"Nov"] = 11; 243 | mon[L"Dec"] = 12; 244 | return format(L"{}/{:02}/{:02} {}", spi.substr(7, 4), mon[spi.substr(0, 3)], stoi(spi[4] == L' ' ? spi.substr(5, 1) : spi.substr(4, 2)), StrToWstr(__TIME__)); 245 | } 246 | 247 | wstring WCH_GetExecDir() { 248 | // Get program executable directory. 249 | wstring _res = _wpgmptr; 250 | size_t _pos = 0; 251 | for (size_t i = 0; i < _res.size(); i++) { 252 | if (_res[i] == L'\\') { 253 | _pos = i; 254 | } 255 | } 256 | return _res.substr(0, _pos); 257 | } 258 | 259 | wstring WCH_GetUniIdent() { 260 | // Get unique identification. (Public IP) 261 | wstring FilePath = WCH_path_temp + L"\\WCH_IDENT.tmp"; 262 | wstring _in, _res; 263 | URLDownloadToFileW(NULL, L"https://api.ipify.org", FilePath.c_str(), 0, NULL); 264 | wfin.open(FilePath); 265 | wfin >> _in; 266 | wfin.close(); 267 | DeleteFileW(FilePath.c_str()); 268 | for (size_t i = 0; i < _in.size(); i++) { 269 | if (_in[i] != L'.') { 270 | _res.push_back(_in[i]); 271 | } 272 | } 273 | return L"11111" + to_wstring(stoll(_res) % 99991); 274 | } 275 | 276 | size_t WCH_GetWstrDisplaySize(const wstring& _in) { 277 | // Get display length of wide string. 278 | size_t _size = 0; 279 | for (size_t i = 0; i < _in.size(); i++) { 280 | if (iswascii(_in[i])) { 281 | _size++; 282 | } else { 283 | _size += 2; 284 | } 285 | } 286 | return _size; 287 | } 288 | 289 | tuple WCH_GetSystemVersion() { 290 | // Get system version. 291 | uint32_t _version = 0; 292 | #pragma warning(suppress : 4996 28159) 293 | _version = GetVersion(); 294 | return make_tuple((uint32_t)(LOBYTE(LOWORD(_version))), (uint32_t)(HIBYTE(LOWORD(_version))), (uint32_t)(HIWORD(_version))); 295 | } 296 | 297 | wstring WCH_GetSystemArchitecture() { 298 | // Get system architecture. 299 | SYSTEM_INFO _sysinfo = {}; 300 | GetNativeSystemInfo(&_sysinfo); 301 | switch (_sysinfo.wProcessorArchitecture) { 302 | case PROCESSOR_ARCHITECTURE_INTEL: 303 | return L"x86"; 304 | case PROCESSOR_ARCHITECTURE_AMD64: 305 | return L"x64"; 306 | case PROCESSOR_ARCHITECTURE_ARM: 307 | return L"ARM"; 308 | case PROCESSOR_ARCHITECTURE_ARM64: 309 | return L"ARM64"; 310 | case PROCESSOR_ARCHITECTURE_IA64: 311 | return L"IA64"; 312 | case PROCESSOR_ARCHITECTURE_UNKNOWN: 313 | return L"Unknown"; 314 | default: 315 | return L"Unknown"; 316 | } 317 | } 318 | 319 | wstring WCH_GetFileHash(const wstring& FilePath) { 320 | // Get SHA512 hash of file. 321 | FILE* FileHandle = _wfopen(FilePath.c_str(), L"rb"); 322 | if (FileHandle == nullptr) { 323 | return L""; 324 | } 325 | unsigned char buf[4096] = {}; 326 | unsigned char digest[64] = {}; 327 | SHA512_CTX hashContext = {}; 328 | size_t readBytes = 0; 329 | wstring res; 330 | #pragma warning(push) 331 | #pragma warning(disable : 4996) 332 | SHA512_Init(&hashContext); 333 | while ((readBytes = fread(buf, 1, 4096, FileHandle)) != 0) { 334 | SHA512_Update(&hashContext, buf, readBytes); 335 | } 336 | fclose(FileHandle); 337 | SHA512_Final(digest, &hashContext); 338 | #pragma warning(pop) 339 | for (size_t i = 0; i < 64; i++) { 340 | res += format(L"{:02X}", digest[i]); 341 | } 342 | return res; 343 | } 344 | 345 | bool WCH_CheckFileHash(const wstring& FilePath, const wstring& ExpectedHash) { 346 | // Check whether the SHA512 hash of file is valid. 347 | wstring ActualHash = WCH_GetFileHash(FilePath); 348 | if (ActualHash != ExpectedHash) { 349 | SPDLOG_CRITICAL(format(L"Actual SHA512 hash: \"{}\"; expected SHA512 hash: \"{}\"", ActualHash, ExpectedHash)); 350 | return false; 351 | } else { 352 | SPDLOG_INFO(format(L"SHA512 hash: \"{}\"", ExpectedHash)); 353 | return true; 354 | } 355 | } 356 | 357 | void WCH_SetWindowStatus(bool flag) { 358 | // Set the window status by Windows API. 359 | ShowWindow(WCH_handle_window, (flag ? SW_SHOWNORMAL : SW_HIDE)); 360 | WCH_cmd_line = flag; 361 | SPDLOG_INFO(format(L"\"CONSOLE\" argument \"STATUS\" was set to {}", (flag ? L"\"SHOW\"" : L"\"HIDE\""))); 362 | } 363 | 364 | void WCH_SetTrayStatus(bool flag) { 365 | // Set the tray status by Windows API. 366 | ShowWindow(FindWindowW(L"Shell_trayWnd", NULL), (flag ? SW_SHOWNORMAL : SW_HIDE)); 367 | SPDLOG_INFO(format(L"\"TRAY\" argument \"STATUS\" was set to {}", (flag ? L"\"SHOW\"" : L"\"HIDE\""))); 368 | } 369 | 370 | void WCH_ShowTaskBarError() { 371 | // Show error on task bar icon. 372 | WCH_TBL->SetProgressValue(WCH_handle_window, 100, 100); 373 | WCH_TBL->SetProgressState(WCH_handle_window, TBPF_ERROR); 374 | WCH_Sleep(1000); 375 | WCH_TBL->SetProgressState(WCH_handle_window, TBPF_NOPROGRESS); 376 | } 377 | 378 | void WCH_InputCommandIncorrect() { 379 | // Print text for incorrect inputs. 380 | SPDLOG_WARN(L"Your input code is incorrect, please check and try again"); 381 | wcout << StrToWstr(WCH_Language["InputCommandIncorrect"].asString()) << endl; 382 | thread T(WCH_ShowTaskBarError); 383 | T.detach(); 384 | } 385 | 386 | void WCH_FileProcessingFailed() { 387 | // Print text for failed file processings. 388 | SPDLOG_ERROR(L"File processing failed. Please try reinstalling this program"); 389 | wcout << StrToWstr(WCH_Language["FileProcessingFailed"].asString()) << endl; 390 | thread T(WCH_ShowTaskBarError); 391 | T.detach(); 392 | } 393 | 394 | void WCH_NetworkError() { 395 | // Print text for network errors. 396 | SPDLOG_ERROR(L"An network error occurred, please check your network connection and try to update this program"); 397 | wcout << StrToWstr(WCH_Language["NetworkError"].asString()) << endl; 398 | thread T(WCH_ShowTaskBarError); 399 | T.detach(); 400 | } 401 | 402 | void WCH_CheckHotkey() { 403 | // Check when hot key is pressed. 404 | if (!WCH_program_end) { 405 | if (WCH_is_focus) { 406 | if (StrToWstr(WCH_Settings["FocusEndPrompt"].asString()) == L"True") { 407 | if (MessageBoxW(NULL, StrToWstr(WCH_Settings["FocusEndContent"].asString()).c_str(), L"WCH WARN", MB_ICONWARNING | MB_YESNO | MB_TOPMOST) == IDNO) { 408 | return; 409 | } 410 | } 411 | WCH_is_focus = false; 412 | WCH_SetTrayStatus(true); 413 | } 414 | if (WCH_is_countdown) { 415 | WCH_is_countdown = false; 416 | } 417 | WCH_SetWindowStatus(true); 418 | } 419 | } 420 | 421 | void WCH_PutPicture() { 422 | // Press PrintScreen. (Keyboard) 423 | keybd_event(VK_SNAPSHOT, 0, 0, 0); 424 | keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0); 425 | SPDLOG_INFO(L"Copying screenshot to clipboard"); 426 | } 427 | 428 | void WCH_SaveImg() { 429 | // Save screenshot to file. 430 | WCH_Time now = WCH_GetTime(); 431 | wstring SavePathDir = StrToWstr(WCH_Settings["ScreenshotSavePath"].asString()); 432 | wstring SavePath = format(L"{}{:04}{:02}{:02}{:02}{:02}{:02}{}", SavePathDir, now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, WCH_MIME_list.find(StrToWstr(WCH_Settings["ScreenshotSaveMIME"].asString()))->second); 433 | if (_waccess(SavePathDir.c_str(), 0) != 0) { 434 | CreateDirectoryW(SavePathDir.c_str(), NULL); 435 | } 436 | HDC hdcScreen = ::GetDC(NULL); 437 | double dDpi = (double)GetDeviceCaps(GetDC(GetDesktopWindow()), DESKTOPHORZRES) / GetSystemMetrics(SM_CXSCREEN); 438 | int32_t nWidth = (int32_t)round(GetDeviceCaps(hdcScreen, HORZRES) * dDpi); 439 | int32_t nHeight = (int32_t)round(GetDeviceCaps(hdcScreen, VERTRES) * dDpi); 440 | HDC hMemDC; 441 | HBITMAP hBitmap, hOldBitmap; 442 | hMemDC = CreateCompatibleDC(hdcScreen); 443 | hBitmap = CreateCompatibleBitmap(hdcScreen, nWidth, nHeight); 444 | hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); 445 | BitBlt(hMemDC, 0, 0, nWidth, nHeight, hdcScreen, 0, 0, SRCCOPY); 446 | GdiplusWrapper gdiplus = {}; 447 | gdiplus.SaveImage(hBitmap, SavePath.c_str(), StrToWstr(WCH_Settings["ScreenshotSaveMIME"].asString()).c_str()); 448 | DeleteDC(hdcScreen); 449 | DeleteDC(hMemDC); 450 | DeleteObject(hBitmap); 451 | SPDLOG_INFO(format(L"Saving image to \"{}\"", SavePath)); 452 | if (StrToWstr(WCH_Settings["ScreenshotOpen"].asString()) == L"True") { 453 | _wsystem(SavePath.c_str()); 454 | } 455 | } 456 | 457 | void WCH_CheckAndDeleteFile(const wstring& _filename) { 458 | // Delete a file if it exists. 459 | if (_waccess(_filename.c_str(), 0) != -1) { 460 | DeleteFileW(_filename.c_str()); 461 | } 462 | } 463 | 464 | bool WCH_FileIsBlank(const wstring& _filename) { 465 | // Check if a file is blank. 466 | if (_waccess(_filename.c_str(), 0) != -1) { 467 | wfin.open(_filename, ios::in); 468 | wstring _line; 469 | while (getline(wfin, _line)) { 470 | if (_line.size() != 0) { 471 | wfin.close(); 472 | return false; 473 | } 474 | } 475 | wfin.close(); 476 | } 477 | return true; 478 | } 479 | 480 | bool WCH_TaskKill(const wstring& name) { 481 | // Kill a task by system command. 482 | wstring FilePathNormal = WCH_path_temp + L"\\WCH_SYSTEM_NORMAL.tmp"; 483 | wstring FilePathError = WCH_path_temp + L"\\WCH_SYSTEM_ERROR.tmp"; 484 | _wsystem(format(L"TASKKILL /F /IM {} > \"{}\" 2> \"{}\"", name, FilePathNormal, FilePathError).c_str()); 485 | bool _res = (!WCH_FileIsBlank(FilePathNormal) && WCH_FileIsBlank(FilePathError)); 486 | DeleteFileW(FilePathNormal.c_str()); 487 | DeleteFileW(FilePathError.c_str()); 488 | return _res; 489 | } 490 | 491 | WCH_Version WCH_GetVersion(wstring _in) { 492 | // Get version from string. 493 | WCH_Version _res; 494 | size_t _pos = _in.find(L"."); 495 | if (_pos != wstring::npos) { 496 | _res.X = stoi(_in.substr(0, _pos)); 497 | _in = _in.substr(_pos + 1); 498 | } 499 | _pos = _in.find(L"."); 500 | if (_pos != wstring::npos) { 501 | _res.Y = stoi(_in.substr(0, _pos)); 502 | _in = _in.substr(_pos + 1); 503 | } 504 | _res.Z = stoi(_in); 505 | return _res; 506 | } 507 | 508 | size_t WCH_GetNumDigits(size_t _n) { 509 | // Get digits of a number. 510 | size_t _cnt = 1; 511 | while ((_n /= 10) != 0) { 512 | _cnt++; 513 | } 514 | return _cnt; 515 | } 516 | 517 | pair WCH_CheckConfigValid(const wstring& Key, const wstring& Value) { 518 | // Check if the settings key and the value of it match. 519 | wstring KeyType = L"String"; 520 | bool flag = false; 521 | if (Value == L"True" || Value == L"False") { 522 | KeyType = L"Boolean"; 523 | } 524 | if (Value.size() < 10) { 525 | for (size_t i = 0; i < Value.size(); i++) { 526 | if (!iswdigit(Value[i])) { 527 | break; 528 | } 529 | if (Value.size() == i + 1) { 530 | KeyType = L"Number"; 531 | } 532 | } 533 | } 534 | for (auto it = WCH_support_settings.begin(); it != WCH_support_settings.end(); it++) { 535 | if (Key == get<0>(*it)) { 536 | if (KeyType != get<1>(*it)) { 537 | return make_pair(false, KeyType); 538 | } else { 539 | flag = true; 540 | break; 541 | } 542 | } 543 | } 544 | if (!flag) { 545 | return make_pair(false, KeyType); 546 | } 547 | if (Key == L"ScreenshotSavePath" && Value[Value.size() - 1] != L'\\') { 548 | return make_pair(false, KeyType); 549 | } 550 | if (WCH_choice_settings.find(Key) != WCH_choice_settings.end()) { 551 | if (WCH_choice_settings.find(Key)->second.find(Value) == WCH_choice_settings.find(Key)->second.end()) { 552 | return make_pair(false, KeyType); 553 | } 554 | } 555 | return make_pair(true, KeyType); 556 | } 557 | 558 | void WCH_PrintProgressBar(int32_t _sur, int32_t _n, bool _flag) { 559 | // Print a progress bar. 560 | wstring _ETAStr = format(L"{:02}:{:02}:{:02}", (int32_t)(_sur / 3600), (int32_t)((_sur % 3600) / 60), (int32_t)(_sur % 60)); 561 | if (_flag) { 562 | wcout << "\r"; 563 | } 564 | WCH_PrintColor(0x0A); 565 | for (int32_t i = 0; i < _n / 2; i++) { 566 | wcout << WCH_progress_bar_str; 567 | } 568 | WCH_PrintColor(0x0C); 569 | for (int32_t i = _n / 2; i < 50; i++) { 570 | wcout << WCH_progress_bar_str; 571 | } 572 | WCH_PrintColor(0x02); 573 | wcout << L" " << _n << L"%"; 574 | WCH_PrintColor(0x07); 575 | wcout << L" ETA "; 576 | WCH_PrintColor(0x09); 577 | wcout << _ETAStr; 578 | WCH_PrintColor(0x07); 579 | } 580 | 581 | void WCH_ProgressBar() { 582 | // Progress bar. 583 | bool _cd = WCH_is_countdown; 584 | double _pro = 100.0 / WCH_progress_bar_duration; 585 | WCH_PrintProgressBar(WCH_progress_bar_duration, 0, false); 586 | WCH_TBL->SetProgressState(WCH_handle_window, TBPF_NORMAL); 587 | WCH_TBL->SetProgressValue(WCH_handle_window, 0, 100); 588 | for (int32_t i = WCH_progress_bar_duration - 1; i > 0 && !WCH_program_end && !(_cd ^ WCH_is_countdown); i--) { 589 | WCH_Sleep(1000); 590 | WCH_PrintProgressBar(i, (int32_t)((WCH_progress_bar_duration - i) * _pro), true); 591 | WCH_TBL->SetProgressValue(WCH_handle_window, (uint64_t)(((uint64_t)WCH_progress_bar_duration - (uint64_t)i) * _pro), 100); 592 | } 593 | WCH_Sleep(1000); 594 | WCH_PrintProgressBar(0, 100, true); 595 | WCH_TBL->SetProgressState(WCH_handle_window, TBPF_NOPROGRESS); 596 | wcout << endl; 597 | } 598 | 599 | LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { 600 | // Window processing module. 601 | switch (message) { 602 | case WM_HOTKEY: 603 | SPDLOG_DEBUG(format(L"Entering \"WndProc()\": \"WM_HOTKEY\" & \"wParam = {}\" & \"lParam = {}\"", wParam, lParam)); 604 | if (wParam == WCH_HOTKEY_SHOW) { 605 | WCH_CheckHotkey(); 606 | } 607 | break; 608 | case WM_CREATE: 609 | SPDLOG_DEBUG(L"Entering \"WndProc()\": \"WM_CREATE\""); 610 | WCH_NID.cbSize = sizeof(WCH_NID); 611 | WCH_NID.hWnd = hWnd; 612 | WCH_NID.uID = 0; 613 | WCH_NID.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 614 | WCH_NID.uCallbackMessage = WM_USER; 615 | WCH_NID.hIcon = (HICON)LoadImageW(NULL, (WCH_GetExecDir() + L"\\WCH.ico").c_str(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); 616 | wcscpy(WCH_NID.szTip, WCH_title_window.c_str()); 617 | Shell_NotifyIconW(NIM_ADD, &WCH_NID); 618 | WCH_handle_menu = CreatePopupMenu(); 619 | AppendMenuW(WCH_handle_menu, MF_STRING, WCH_MENU_SHOW, L"Ctrl + Down"); 620 | AppendMenuW(WCH_handle_menu, MF_SEPARATOR, 0, NULL); 621 | AppendMenuW(WCH_handle_menu, MF_STRING, WCH_MENU_EXIT, StrToWstr(WCH_Language["Exit"].asString()).c_str()); 622 | break; 623 | case WM_USER: 624 | if (lParam == WM_LBUTTONDOWN) { 625 | SPDLOG_DEBUG(L"Entering \"WndProc()\": \"WM_USER\" & \"WM_LBUTTONDOWN\""); 626 | WCH_CheckHotkey(); 627 | } else if (lParam == WM_RBUTTONDOWN) { 628 | POINT pt; 629 | int32_t xx; 630 | GetCursorPos(&pt); 631 | SetForegroundWindow(hWnd); 632 | xx = TrackPopupMenu(WCH_handle_menu, TPM_RETURNCMD, pt.x, pt.y, NULL, hWnd, NULL); 633 | SPDLOG_DEBUG(format(L"Entering \"WndProc()\": \"WM_USER\" & \"WM_RBUTTONDOWN\" & \"xx = {}\"", to_wstring(xx))); 634 | if (xx == WCH_MENU_SHOW) { 635 | SPDLOG_DEBUG(L"Entering \"WndProc()\": \"WM_USER\" & \"WM_RBUTTONDOWN\" & \"WCH_MENU_SHOW\""); 636 | WCH_CheckHotkey(); 637 | } else if (xx == WCH_MENU_EXIT) { 638 | SPDLOG_DEBUG(L"Entering \"WndProc()\": \"WM_USER\" & \"WM_RBUTTONDOWN\" & \"WCH_MENU_EXIT\""); 639 | raise(SIGBREAK); 640 | } else if (xx == 0) { 641 | PostMessageW(hWnd, WM_LBUTTONDOWN, NULL, NULL); 642 | } 643 | } 644 | break; 645 | case WM_DESTROY: 646 | SPDLOG_DEBUG(L"Entering \"WndProc()\": \"WM_DESTROY\""); 647 | Shell_NotifyIconW(NIM_DELETE, &WCH_NID); 648 | PostQuitMessage(0); 649 | break; 650 | default: 651 | if (message == RegisterWindowMessageW(L"TaskbarCreated")) { 652 | SendMessageW(hWnd, WM_CREATE, wParam, lParam); 653 | } 654 | break; 655 | } 656 | return DefWindowProcW(hWnd, message, wParam, lParam); 657 | } 658 | 659 | void WCH_ShowBugMessagebox(int32_t errorcode, const wstring& errormsg) { 660 | // Show messagebox to inform a bug to user. 661 | wcout << L"\a"; 662 | WCH_TBL->SetProgressState(WCH_handle_window, TBPF_INDETERMINATE); 663 | if (MessageBoxW(NULL, (StrToWstr(WCH_Language["BugMessagebox1"].asString()) + to_wstring(errorcode) + L" " + errormsg + StrToWstr(WCH_Language["BugMessagebox2"].asString())).c_str(), L"WCH ERROR", MB_ICONERROR | MB_YESNO) == IDYES) { 664 | _wsystem(L"START https://github.com/class-tools/Web-Class-Helper/issues/new/choose"); 665 | } 666 | WCH_TBL->SetProgressState(WCH_handle_window, TBPF_NOPROGRESS); 667 | } 668 | 669 | void WCH_signalHandler() { 670 | // Signal handler. 671 | signal(SIGINT, []([[maybe_unused]] int32_t signum) { 672 | WCH_list_command.clear(); 673 | WCH_list_command.push_back(L"exit"); 674 | wcout << endl; 675 | exit(0); 676 | }); 677 | signal(SIGBREAK, []([[maybe_unused]] int32_t signum) { 678 | WCH_list_command.clear(); 679 | WCH_list_command.push_back(L"exit"); 680 | wcout << endl; 681 | exit(0); 682 | }); 683 | signal(SIGABRT, [](int32_t signum) { 684 | WCH_cmd_line = false; 685 | WCH_program_end = true; 686 | WCH_PrintColor(0x07); 687 | wcout << endl; 688 | SPDLOG_CRITICAL(format(L"Signal {} detected (Program aborted)", signum)); 689 | Sleep(500); 690 | WCH_SetWindowStatus(false); 691 | WCH_ShowBugMessagebox(signum, L"Program aborted"); 692 | exit(signum); 693 | }); 694 | signal(SIGFPE, [](int32_t signum) { 695 | WCH_cmd_line = false; 696 | WCH_program_end = true; 697 | WCH_PrintColor(0x07); 698 | wcout << endl; 699 | SPDLOG_CRITICAL(format(L"Signal {} detected (Operation overflow)", signum)); 700 | Sleep(500); 701 | WCH_SetWindowStatus(false); 702 | WCH_ShowBugMessagebox(signum, L"Operation overflow"); 703 | exit(signum); 704 | }); 705 | signal(SIGILL, [](int32_t signum) { 706 | WCH_cmd_line = false; 707 | WCH_program_end = true; 708 | WCH_PrintColor(0x07); 709 | wcout << endl; 710 | SPDLOG_CRITICAL(format(L"Signal {} detected (Illegal instruction)", signum)); 711 | Sleep(500); 712 | WCH_SetWindowStatus(false); 713 | WCH_ShowBugMessagebox(signum, L"Illegal instruction"); 714 | exit(signum); 715 | }); 716 | signal(SIGSEGV, [](int32_t signum) { 717 | WCH_cmd_line = false; 718 | WCH_program_end = true; 719 | WCH_PrintColor(0x07); 720 | wcout << endl; 721 | SPDLOG_CRITICAL(format(L"Signal {} detected (Access to illegal memory)", signum)); 722 | Sleep(500); 723 | WCH_SetWindowStatus(false); 724 | WCH_ShowBugMessagebox(signum, L"Access to illegal memory"); 725 | exit(signum); 726 | }); 727 | } 728 | 729 | #endif 730 | -------------------------------------------------------------------------------- /modules/basic.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper Basic Module Header File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: jsh-jsh ren-yc 6 | */ 7 | #ifndef BASIC_H 8 | #define BASIC_H 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include 81 | #include 82 | #include 83 | #include 84 | #include 85 | #include 86 | #include 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | #include 101 | #include 102 | #include 103 | #include 104 | #include 105 | #include 106 | #include 107 | #include 108 | #include 109 | #include 110 | #include 111 | #include 112 | #include 113 | #include 114 | #include 115 | #include 116 | 117 | #pragma warning(push) 118 | #pragma warning(disable : 26437 26451 26495 26498 26800) 119 | #define SPDLOG_WCHAR_TO_UTF8_SUPPORT 120 | #define SPDLOG_WCHAR_FILENAMES 121 | #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG 122 | #include 123 | #include 124 | #include 125 | #include 126 | #pragma warning(pop) 127 | 128 | #pragma comment(lib, "winmm.lib") 129 | #pragma comment(lib, "gdiplus.lib") 130 | #pragma comment(lib, "urlmon.lib") 131 | #pragma comment(lib, "ole32.lib") 132 | 133 | #define WCH_HOTKEY_SHOW 121 134 | #define WCH_MENU_SHOW 11461 135 | #define WCH_MENU_EXIT 11462 136 | 137 | using std::ignore; 138 | using std::cin; 139 | using std::wcin; 140 | using std::cout; 141 | using std::wcout; 142 | using std::cerr; 143 | using std::wcerr; 144 | using std::endl; 145 | using std::format; 146 | using std::vformat; 147 | using std::getline; 148 | using std::find; 149 | using std::to_string; 150 | using std::to_wstring; 151 | using std::string; 152 | using std::string_view; 153 | using std::wstring; 154 | using std::wstring_view; 155 | using std::stringstream; 156 | using std::wstringstream; 157 | using std::ifstream; 158 | using std::wifstream; 159 | using std::ofstream; 160 | using std::wofstream; 161 | using std::unique_ptr; 162 | using std::shared_ptr; 163 | using std::locale; 164 | using std::array; 165 | using std::map; 166 | using std::set; 167 | using std::vector; 168 | using std::tuple; 169 | using std::function; 170 | using std::pair; 171 | using std::thread; 172 | using std::runtime_error; 173 | using std::exception; 174 | using std::ios; 175 | using std::random_device; 176 | using std::mt19937; 177 | using std::chrono::milliseconds; 178 | using std::make_pair; 179 | using std::make_tuple; 180 | using std::make_shared; 181 | using std::get; 182 | using std::this_thread::sleep_for; 183 | 184 | class GdiplusWrapper { 185 | public: 186 | GdiplusWrapper() { 187 | Gdiplus::GdiplusStartupInput gdiplusStartupInput; 188 | GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 189 | } 190 | int32_t GetEncoderClsid(const wchar_t* format, CLSID* pClsid) { 191 | UINT num = 0; 192 | UINT size = 0; 193 | UINT ret = -1; 194 | Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; 195 | Gdiplus::GetImageEncodersSize(&num, &size); 196 | if (size == 0) { 197 | return -1; 198 | } 199 | pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size)); 200 | if (pImageCodecInfo == NULL) { 201 | return -1; 202 | } 203 | Gdiplus::GetImageEncoders(num, size, pImageCodecInfo); 204 | for (UINT j = 0; j < num; j++) { 205 | #pragma warning(suppress : 6385) 206 | if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) { 207 | *pClsid = pImageCodecInfo[j].Clsid; 208 | ret = j; 209 | } 210 | } 211 | free(pImageCodecInfo); 212 | return ret; 213 | } 214 | void SaveImage(HBITMAP hBitmap, const wchar_t* filename, const wchar_t* format) { 215 | CLSID pngClsid; 216 | Gdiplus::Bitmap bitmap(hBitmap, NULL); 217 | GetEncoderClsid(format, &pngClsid); 218 | bitmap.Save(filename, &pngClsid); 219 | } 220 | private: 221 | ULONG_PTR gdiplusToken; 222 | }; 223 | 224 | struct WCH_Time { 225 | int32_t Year = 0; 226 | int32_t Month = 0; 227 | int32_t Day = 0; 228 | int32_t Hour = 0; 229 | int32_t Minute = 0; 230 | int32_t Second = 0; 231 | int32_t WeekDay = 0; 232 | }; 233 | 234 | struct WCH_Data_Body { 235 | int32_t H = 0; 236 | int32_t M = 0; 237 | }; 238 | 239 | struct WCH_Version { 240 | int32_t X = 0; 241 | int32_t Y = 0; 242 | int32_t Z = 0; 243 | bool operator==(const WCH_Version& _in) { 244 | return (X == _in.X && Y == _in.Y && Z == _in.Z); 245 | } 246 | bool operator<(const WCH_Version& _in) { 247 | if (X < _in.X) { 248 | return true; 249 | } else if (X > _in.X) { 250 | return false; 251 | } else { 252 | if (Y < _in.Y) { 253 | return true; 254 | } else if (Y > _in.Y) { 255 | return false; 256 | } else { 257 | if (Z < _in.Z) { 258 | return true; 259 | } else { 260 | return false; 261 | } 262 | } 263 | } 264 | } 265 | }; 266 | 267 | void WCH_clock(); 268 | void WCH_task(); 269 | void WCH_work(); 270 | void WCH_help(); 271 | void WCH_open(); 272 | void WCH_ow(); 273 | void WCH_hide(); 274 | void WCH_game(); 275 | void WCH_time(); 276 | void WCH_prtscn(); 277 | void WCH_trans(); 278 | void WCH_fate(); 279 | void WCH_focus(); 280 | void WCH_countdown(); 281 | void WCH_update(); 282 | void WCH_license(); 283 | void WCH_clear(); 284 | void WCH_config(); 285 | void WCH_develop(); 286 | void WCH_sysinfo(); 287 | void WCH_exit(); 288 | void WCH_restart(); 289 | 290 | const vector WCH_list_weekday = {L"Sunday", L"Monday", L"Tuesday", L"Wednesday", L"Thursday", L"Friday", L"Saturday"}; 291 | const map> WCH_choice_settings = { 292 | make_pair(L"Language", []() { 293 | set _tmp = {L"en-US", L"zh-CN"}; 294 | return _tmp; 295 | }()), 296 | make_pair(L"ScreenshotSaveMIME", []() { 297 | set _tmp = {L"image/bmp", L"image/gif", L"image/jpeg", L"image/png", L"image/tiff"}; 298 | return _tmp; 299 | }()), 300 | }; 301 | const map WCH_MIME_list = { 302 | make_pair(L"image/bmp", L".bmp"), 303 | make_pair(L"image/gif", L".gif"), 304 | make_pair(L"image/jpeg", L".jpg"), 305 | make_pair(L"image/png", L".png"), 306 | make_pair(L"image/tiff", L".tif")}; 307 | const map> WCH_support_command = { 308 | make_pair(L"clock", WCH_clock), 309 | make_pair(L"task", WCH_task), 310 | make_pair(L"work", WCH_work), 311 | make_pair(L"help", WCH_help), 312 | make_pair(L"open", WCH_open), 313 | make_pair(L"ow", WCH_ow), 314 | make_pair(L"hide", WCH_hide), 315 | make_pair(L"game", WCH_game), 316 | make_pair(L"time", WCH_time), 317 | make_pair(L"prtscn", WCH_prtscn), 318 | make_pair(L"trans", WCH_trans), 319 | make_pair(L"fate", WCH_fate), 320 | make_pair(L"focus", WCH_focus), 321 | make_pair(L"countdown", WCH_countdown), 322 | make_pair(L"update", WCH_update), 323 | make_pair(L"license", WCH_license), 324 | make_pair(L"clear", WCH_clear), 325 | make_pair(L"config", WCH_config), 326 | make_pair(L"develop", WCH_develop), 327 | make_pair(L"sysinfo", WCH_sysinfo), 328 | make_pair(L"exit", WCH_exit), 329 | make_pair(L"restart", WCH_restart)}; 330 | const set> WCH_support_settings = { 331 | make_tuple(L"CommandPrompt", L"String", L">>>", false), 332 | make_tuple(L"CountDownSoundPrompt", L"Boolean", L"False", false), 333 | make_tuple(L"FocusEndContent", L"String", L"Disable focus?", false), 334 | make_tuple(L"FocusEndPrompt", L"Boolean", L"False", false), 335 | make_tuple(L"FocusKillInterval", L"Number", L"60000", false), 336 | make_tuple(L"Language", L"String", L"en-US", true), 337 | make_tuple(L"ScreenshotOpen", L"Boolean", L"False", false), 338 | make_tuple(L"ScreenshotSaveMIME", L"String", L"image/png", false), 339 | make_tuple(L"ScreenshotSavePath", L"String", format(L"{}\\Pictures\\", _wgetenv(L"USERPROFILE")), false)}; 340 | const wstring WCH_progress_bar_str = IsWindows10OrGreater() ? L"━" : L"-"; 341 | const wstring WCH_path_data = format(L"{}\\AppData\\Local\\WCH", _wgetenv(L"USERPROFILE")); 342 | const wstring WCH_path_temp = format(L"{}\\AppData\\Local\\Temp\\WCH", _wgetenv(L"USERPROFILE")); 343 | vector WCH_list_command; 344 | set> WCH_list_clock; 345 | set WCH_list_task; 346 | set> WCH_list_work; 347 | wstring WCH_version; 348 | wstring WCH_path_exec; 349 | wstring WCH_title_window; 350 | HWND WCH_handle_window; 351 | HWND WCH_handle_tray; 352 | HMENU WCH_handle_menu; 353 | NOTIFYICONDATAW WCH_NID; 354 | ATL::CComPtr WCH_TBL; 355 | Json::Value WCH_Settings; 356 | Json::Value WCH_Language; 357 | int32_t WCH_num_clock; 358 | int32_t WCH_num_task; 359 | int32_t WCH_num_work; 360 | int32_t WCH_progress_bar_duration; 361 | bool WCH_cmd_line = true; 362 | bool WCH_is_focus; 363 | bool WCH_is_countdown; 364 | bool WCH_program_end; 365 | bool WCH_pre_start = true; 366 | ifstream fin; 367 | wifstream wfin; 368 | ofstream fout; 369 | wofstream wfout; 370 | Json::Reader JSON_Reader; 371 | Json::StreamWriterBuilder JSON_SWB; 372 | unique_ptr JSON_SW(JSON_SWB.newStreamWriter()); 373 | shared_ptr LOG_sink; 374 | shared_ptr LOG_logger; 375 | 376 | #endif 377 | -------------------------------------------------------------------------------- /modules/file-process.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper File Processing Module Header File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: jsh-jsh ren-yc 6 | */ 7 | #ifndef FILE_PROCESS_H 8 | #define FILE_PROCESS_H 9 | #include "init.hpp" 10 | #include "commands.hpp" 11 | #include "functions.hpp" 12 | #include "apis.hpp" 13 | #include "basic.hpp" 14 | 15 | extern const vector WCH_list_weekday; 16 | extern const map> WCH_choice_settings; 17 | extern const map WCH_MIME_list; 18 | extern const map> WCH_support_command; 19 | extern const set> WCH_support_settings; 20 | extern const wstring WCH_progress_bar_str; 21 | extern const wstring WCH_path_data; 22 | extern const wstring WCH_path_temp; 23 | extern vector WCH_list_command; 24 | extern set> WCH_list_clock; 25 | extern set WCH_list_task; 26 | extern set> WCH_list_work; 27 | extern wstring WCH_version; 28 | extern wstring WCH_path_exec; 29 | extern wstring WCH_title_window; 30 | extern HWND WCH_handle_window; 31 | extern HWND WCH_handle_tray; 32 | extern HMENU WCH_handle_menu; 33 | extern NOTIFYICONDATAW WCH_NID; 34 | extern ATL::CComPtr WCH_TBL; 35 | extern Json::Value WCH_Settings; 36 | extern Json::Value WCH_Language; 37 | extern int32_t WCH_num_clock; 38 | extern int32_t WCH_num_task; 39 | extern int32_t WCH_num_work; 40 | extern int32_t WCH_progress_bar_duration; 41 | extern bool WCH_cmd_line; 42 | extern bool WCH_is_focus; 43 | extern bool WCH_is_countdown; 44 | extern bool WCH_program_end; 45 | extern bool WCH_pre_start; 46 | extern ifstream fin; 47 | extern wifstream wfin; 48 | extern ofstream fout; 49 | extern wofstream wfout; 50 | extern Json::Reader JSON_Reader; 51 | extern Json::StreamWriterBuilder JSON_SWB; 52 | extern unique_ptr JSON_SW; 53 | extern shared_ptr LOG_sink; 54 | extern shared_ptr LOG_logger; 55 | 56 | void WCH_read_clock() { 57 | // Read clock data. 58 | WCH_Time q = WCH_GetTime(); 59 | wstring NowWeekDay = WCH_list_weekday[(q.Day + 2 * q.Month + 3 * (q.Month + 1) / 5 + q.Year + q.Year / 4 - q.Year / 100 + q.Year / 400 + 1) % 7]; 60 | wstring FilePath = WCH_path_data + L"\\data\\clock.json"; 61 | Json::Value val; 62 | fin.open(FilePath); 63 | if (!fin.is_open()) { 64 | return; 65 | } 66 | if (JSON_Reader.parse(fin, val)) { 67 | try { 68 | SPDLOG_INFO(format(L"Reading file \"{}\"", FilePath)); 69 | WCH_num_clock = val[WstrToStr(NowWeekDay)].size(); 70 | for (int32_t i = 0; i < WCH_num_clock; i++) { 71 | WCH_list_clock.insert(make_tuple(val[WstrToStr(NowWeekDay)][i][0].asInt(), val[WstrToStr(NowWeekDay)][i][1].asInt(), StrToWstr(val[WstrToStr(NowWeekDay)][i][2].asString()))); 72 | } 73 | } catch (...) { 74 | goto ERR; 75 | } 76 | } else { 77 | ERR: 78 | SPDLOG_WARN(format(L"Data in file \"{}\" corrupted", FilePath)); 79 | } 80 | fin.close(); 81 | } 82 | 83 | void WCH_read_task() { 84 | // Read task data. 85 | wstring FilePath = WCH_path_data + L"\\data\\task.json"; 86 | Json::Value val; 87 | fin.open(FilePath); 88 | if (!fin.is_open()) { 89 | return; 90 | } 91 | if (JSON_Reader.parse(fin, val)) { 92 | try { 93 | SPDLOG_INFO(format(L"Reading file \"{}\"", FilePath)); 94 | WCH_num_task = val.size(); 95 | for (int32_t i = 0; i < WCH_num_task; i++) { 96 | WCH_list_task.insert(StrToWstr(val[i].asString())); 97 | } 98 | } catch (...) { 99 | goto ERR; 100 | } 101 | } else { 102 | ERR: 103 | SPDLOG_WARN(format(L"Data in file \"{}\" corrupted", FilePath)); 104 | } 105 | fin.close(); 106 | } 107 | 108 | void WCH_read_work() { 109 | // Read work data. 110 | wstring FilePath = WCH_path_data + L"\\data\\work.json"; 111 | Json::Value val; 112 | fin.open(FilePath); 113 | if (!fin.is_open()) { 114 | return; 115 | } 116 | if (JSON_Reader.parse(fin, val)) { 117 | try { 118 | SPDLOG_INFO(format(L"Reading file \"{}\"", FilePath)); 119 | WCH_num_work = val.size(); 120 | for (int32_t i = 0; i < WCH_num_work; i++) { 121 | WCH_list_work.insert(make_pair(StrToWstr(val[i][0].asString()), StrToWstr(val[i][1].asString()))); 122 | } 123 | } catch (...) { 124 | goto ERR; 125 | } 126 | } else { 127 | ERR: 128 | SPDLOG_WARN(format(L"Data in file \"{}\" corrupted", FilePath)); 129 | } 130 | fin.close(); 131 | } 132 | 133 | void WCH_read_settings() { 134 | // Read settings data. 135 | wstring FilePath = WCH_path_data + L"\\settings.json"; 136 | fin.open(FilePath); 137 | if (!fin.is_open()) { 138 | goto ERR; 139 | } 140 | if (JSON_Reader.parse(fin, WCH_Settings)) { 141 | try { 142 | if (!WCH_pre_start) { 143 | SPDLOG_INFO(format(L"Reading file \"{}\"", FilePath)); 144 | } 145 | if (!WCH_Settings.isMember("StartTime")) { 146 | throw runtime_error(""); 147 | } 148 | for (auto it = WCH_support_settings.begin(); it != WCH_support_settings.end(); it++) { 149 | if (!WCH_Settings.isMember(WstrToStr(get<0>(*it)))) { 150 | throw runtime_error(""); 151 | } else if (!WCH_CheckConfigValid(get<0>(*it), StrToWstr(WCH_Settings[WstrToStr(get<0>(*it))].asString())).first) { 152 | throw runtime_error(""); 153 | } 154 | } 155 | if (WCH_Settings.size() != WCH_support_settings.size() + 1) { 156 | throw runtime_error(""); 157 | } 158 | } catch (...) { 159 | goto ERR; 160 | } 161 | } else { 162 | ERR: 163 | WCH_Settings.clear(); 164 | WCH_Settings["StartTime"] = "00000000000000"; 165 | for (auto it = WCH_support_settings.begin(); it != WCH_support_settings.end(); it++) { 166 | WCH_Settings[WstrToStr(get<0>(*it))] = WstrToStr(get<2>(*it)); 167 | } 168 | if (!WCH_pre_start) { 169 | SPDLOG_WARN(format(L"Data in file \"{}\" corrupted", FilePath)); 170 | } 171 | } 172 | fin.close(); 173 | } 174 | 175 | void WCH_read_language() { 176 | // Read language data. 177 | wstring FilePath = WCH_GetExecDir() + L"\\resources\\" + StrToWstr(WCH_Settings["Language"].asString()) + L"\\interactive.json"; 178 | if (!WCH_CheckFileHash(FilePath, StrToWstr(WCH_Settings["Language"].asString()) == L"en-US" ? SHASUM_enUS_interactive : SHASUM_zhCN_interactive)) { 179 | SPDLOG_CRITICAL(format(L"Data in file \"{}\" corrupted", FilePath)); 180 | WCH_FileProcessingFailed(); 181 | raise(SIGBREAK); 182 | } 183 | fin.open(FilePath); 184 | ignore = JSON_Reader.parse(fin, WCH_Language); 185 | fin.close(); 186 | } 187 | 188 | void WCH_read() { 189 | // Read data. 190 | WCH_cmd_line = false; 191 | WCH_read_clock(); 192 | WCH_read_task(); 193 | WCH_read_work(); 194 | WCH_read_settings(); 195 | WCH_read_language(); 196 | WCH_cmd_line = true; 197 | } 198 | 199 | void WCH_save_clock() { 200 | // Save clock data. 201 | WCH_Time q = WCH_GetTime(); 202 | wstring NowWeekDay = WCH_list_weekday[(q.Day + 2 * q.Month + 3 * (q.Month + 1) / 5 + q.Year + q.Year / 4 - q.Year / 100 + q.Year / 400 + 1) % 7]; 203 | wstring FilePath = WCH_path_data + L"\\data\\clock.json"; 204 | Json::Value val; 205 | fin.open(FilePath); 206 | if (fin.is_open()) { 207 | JSON_Reader.parse(fin, val); 208 | } 209 | fin.close(); 210 | val[WstrToStr(NowWeekDay)].clear(); 211 | for (auto it = WCH_list_clock.begin(); it != WCH_list_clock.end(); it++) { 212 | Json::Value sval; 213 | sval.append(get<0>(*it)); 214 | sval.append(get<1>(*it)); 215 | sval.append(WstrToStr(get<2>(*it))); 216 | val[WstrToStr(NowWeekDay)].append(sval); 217 | } 218 | if (val[WstrToStr(NowWeekDay)].size() == 0) { 219 | val.removeMember(WstrToStr(NowWeekDay)); 220 | } 221 | if (val.size() != 0) { 222 | SPDLOG_INFO(format(L"Writing file \"{}\"", FilePath)); 223 | fout.open(FilePath); 224 | JSON_SW->write(val, &fout); 225 | fout.close(); 226 | } else { 227 | if (_waccess(FilePath.c_str(), 0) != -1) { 228 | SPDLOG_INFO(format(L"Deleting file \"{}\"", FilePath)); 229 | DeleteFileW(FilePath.c_str()); 230 | } 231 | } 232 | } 233 | 234 | void WCH_save_task() { 235 | // Save task list data. 236 | wstring FilePath = WCH_path_data + L"\\data\\task.json"; 237 | Json::Value val; 238 | if (WCH_num_task == 0) { 239 | if (_waccess(FilePath.c_str(), 0) != -1) { 240 | SPDLOG_INFO(format(L"Deleting file \"{}\"", FilePath)); 241 | DeleteFileW(FilePath.c_str()); 242 | } 243 | return; 244 | } 245 | SPDLOG_INFO(format(L"Writing file \"{}\"", FilePath)); 246 | for (auto it = WCH_list_task.begin(); it != WCH_list_task.end(); it++) { 247 | val.append(WstrToStr(*it)); 248 | } 249 | fout.open(FilePath); 250 | JSON_SW->write(val, &fout); 251 | fout.close(); 252 | } 253 | 254 | void WCH_save_work() { 255 | // Save task list data. 256 | wstring FilePath = WCH_path_data + L"\\data\\work.json"; 257 | Json::Value val; 258 | if (WCH_num_work == 0) { 259 | if (_waccess(FilePath.c_str(), 0) != -1) { 260 | SPDLOG_INFO(format(L"Deleting file \"{}\"", FilePath)); 261 | DeleteFileW(FilePath.c_str()); 262 | } 263 | return; 264 | } 265 | SPDLOG_INFO(format(L"Writing file \"{}\"", FilePath)); 266 | for (auto it = WCH_list_work.begin(); it != WCH_list_work.end(); it++) { 267 | Json::Value sval; 268 | sval.append(WstrToStr(it->first)); 269 | sval.append(WstrToStr(it->second)); 270 | val.append(sval); 271 | } 272 | fout.open(FilePath); 273 | JSON_SW->write(val, &fout); 274 | fout.close(); 275 | } 276 | 277 | void WCH_save_settings() { 278 | // Save settings data. 279 | wstring FilePath = WCH_path_data + L"\\settings.json"; 280 | if (!WCH_pre_start) { 281 | SPDLOG_INFO(format(L"Writing file \"{}\"", FilePath)); 282 | } 283 | fout.open(FilePath); 284 | JSON_SW->write(WCH_Settings, &fout); 285 | fout.close(); 286 | } 287 | 288 | void WCH_save() { 289 | // Save data. 290 | WCH_save_clock(); 291 | WCH_save_task(); 292 | WCH_save_work(); 293 | WCH_save_settings(); 294 | } 295 | 296 | #endif 297 | -------------------------------------------------------------------------------- /modules/functions.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper Functions Module Header File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: jsh-jsh ren-yc 6 | */ 7 | #ifndef FUNCTIONS_H 8 | #define FUNCTIONS_H 9 | #include "file-process.hpp" 10 | #include "init.hpp" 11 | #include "commands.hpp" 12 | #include "apis.hpp" 13 | #include "basic.hpp" 14 | 15 | extern const vector WCH_list_weekday; 16 | extern const map> WCH_choice_settings; 17 | extern const map WCH_MIME_list; 18 | extern const map> WCH_support_command; 19 | extern const set> WCH_support_settings; 20 | extern const wstring WCH_progress_bar_str; 21 | extern const wstring WCH_path_data; 22 | extern const wstring WCH_path_temp; 23 | extern vector WCH_list_command; 24 | extern set> WCH_list_clock; 25 | extern set WCH_list_task; 26 | extern set> WCH_list_work; 27 | extern wstring WCH_version; 28 | extern wstring WCH_path_exec; 29 | extern wstring WCH_title_window; 30 | extern HWND WCH_handle_window; 31 | extern HWND WCH_handle_tray; 32 | extern HMENU WCH_handle_menu; 33 | extern NOTIFYICONDATAW WCH_NID; 34 | extern ATL::CComPtr WCH_TBL; 35 | extern Json::Value WCH_Settings; 36 | extern Json::Value WCH_Language; 37 | extern int32_t WCH_num_clock; 38 | extern int32_t WCH_num_task; 39 | extern int32_t WCH_num_work; 40 | extern int32_t WCH_progress_bar_duration; 41 | extern bool WCH_cmd_line; 42 | extern bool WCH_is_focus; 43 | extern bool WCH_is_countdown; 44 | extern bool WCH_program_end; 45 | extern bool WCH_pre_start; 46 | extern ifstream fin; 47 | extern wifstream wfin; 48 | extern ofstream fout; 49 | extern wofstream wfout; 50 | extern Json::Reader JSON_Reader; 51 | extern Json::StreamWriterBuilder JSON_SWB; 52 | extern unique_ptr JSON_SW; 53 | extern shared_ptr LOG_sink; 54 | extern shared_ptr LOG_logger; 55 | 56 | void WCH_check_clock_loop() { 57 | // Check if the time equals to the clock. (Another thread) 58 | WCH_Sleep((60 - WCH_GetTime().Second) * 1000); 59 | while (!WCH_program_end) { 60 | WCH_Time NOW = WCH_GetTime(); 61 | for (auto it = WCH_list_clock.begin(); it != WCH_list_clock.end(); it++) { 62 | if (get<0>(*it) == NOW.Hour && get<1>(*it) == NOW.Minute && get<2>(*it).size() > 0) { 63 | if (StrToWstr(WCH_Settings["CountDownSoundPrompt"].asString()) == L"True") { 64 | wcout << L"\a"; 65 | } 66 | bool _tmp = WCH_cmd_line; 67 | if (_tmp) { 68 | WCH_SetWindowStatus(false); 69 | } 70 | MessageBoxW(NULL, (get<2>(*it)).c_str(), L"WCH CLOCK", MB_OK | MB_TOPMOST); 71 | if (!WCH_is_focus || _tmp) { 72 | WCH_SetWindowStatus(true); 73 | } 74 | } 75 | } 76 | WCH_Sleep(60000); 77 | } 78 | } 79 | 80 | void WCH_message_loop() { 81 | // Message loop. 82 | MSG msg = {}; 83 | WNDCLASS wndclass = {}; 84 | wndclass.style = CS_HREDRAW | CS_VREDRAW; 85 | wndclass.lpfnWndProc = WndProc; 86 | wndclass.cbClsExtra = 0; 87 | wndclass.cbWndExtra = 0; 88 | wndclass.hInstance = NULL; 89 | wndclass.hIcon = LoadIconW(NULL, IDI_APPLICATION); 90 | wndclass.hCursor = LoadCursorW(NULL, IDC_ARROW); 91 | wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 92 | wndclass.lpszMenuName = NULL; 93 | wndclass.lpszClassName = WCH_title_window.c_str(); 94 | RegisterClassW(&wndclass); 95 | WCH_handle_tray = CreateWindowExW(WS_EX_TOOLWINDOW, WCH_title_window.c_str(), WCH_title_window.c_str(), WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); 96 | ShowWindow(WCH_handle_tray, SW_HIDE); 97 | UpdateWindow(WCH_handle_tray); 98 | RegisterHotKey(WCH_handle_tray, WCH_HOTKEY_SHOW, MOD_CONTROL, VK_DOWN); 99 | while (GetMessageW(&msg, NULL, 0, 0)) { 100 | TranslateMessage(&msg); 101 | DispatchMessageW(&msg); 102 | } 103 | } 104 | 105 | void WCH_check_task_loop() { 106 | // Check if the running task is in the task list. (Another thread) 107 | while (WCH_is_focus && !WCH_program_end) { 108 | for (auto it = WCH_list_task.begin(); it != WCH_list_task.end(); it++) { 109 | if (WCH_TaskKill(*it)) { 110 | SPDLOG_INFO(format(L"Successfully killed \"{}\"", *it)); 111 | } else { 112 | SPDLOG_INFO(format(L"Failed to kill \"{}\"", *it)); 113 | } 114 | } 115 | WCH_Sleep(stoi(StrToWstr(WCH_Settings["FocusKillInterval"].asString()))); 116 | } 117 | } 118 | 119 | void WCH_CL_Init() { 120 | // Initialize the command line. 121 | BEGIN: 122 | wstring _in; 123 | wcout << StrToWstr(WCH_Settings["CommandPrompt"].asString()) << L" "; 124 | getline(wcin, _in); 125 | if (wcin.eof()) { 126 | raise(SIGINT); 127 | } 128 | WCH_list_command = WCH_split(_in); 129 | if (WCH_list_command.size() == 0) { 130 | wcout << endl; 131 | goto BEGIN; 132 | } 133 | transform(WCH_list_command[0].begin(), WCH_list_command[0].end(), WCH_list_command[0].begin(), ::towlower); 134 | } 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /modules/init.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper Initialization Module Header File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: jsh-jsh ren-yc hjl2011 6 | */ 7 | #ifndef INIT_H 8 | #define INIT_H 9 | #include "functions.hpp" 10 | #include "file-process.hpp" 11 | #include "commands.hpp" 12 | #include "apis.hpp" 13 | #include "basic.hpp" 14 | 15 | extern const vector WCH_list_weekday; 16 | extern const map> WCH_choice_settings; 17 | extern const map WCH_MIME_list; 18 | extern const map> WCH_support_command; 19 | extern const set> WCH_support_settings; 20 | extern const wstring WCH_progress_bar_str; 21 | extern const wstring WCH_path_data; 22 | extern const wstring WCH_path_temp; 23 | extern vector WCH_list_command; 24 | extern set> WCH_list_clock; 25 | extern set WCH_list_task; 26 | extern set> WCH_list_work; 27 | extern wstring WCH_version; 28 | extern wstring WCH_path_exec; 29 | extern wstring WCH_title_window; 30 | extern HWND WCH_handle_window; 31 | extern HWND WCH_handle_tray; 32 | extern HMENU WCH_handle_menu; 33 | extern NOTIFYICONDATAW WCH_NID; 34 | extern ATL::CComPtr WCH_TBL; 35 | extern Json::Value WCH_Settings; 36 | extern Json::Value WCH_Language; 37 | extern int32_t WCH_num_clock; 38 | extern int32_t WCH_num_task; 39 | extern int32_t WCH_num_work; 40 | extern int32_t WCH_progress_bar_duration; 41 | extern bool WCH_cmd_line; 42 | extern bool WCH_is_focus; 43 | extern bool WCH_is_countdown; 44 | extern bool WCH_program_end; 45 | extern bool WCH_pre_start; 46 | extern ifstream fin; 47 | extern wifstream wfin; 48 | extern ofstream fout; 49 | extern wofstream wfout; 50 | extern Json::Reader JSON_Reader; 51 | extern Json::StreamWriterBuilder JSON_SWB; 52 | extern unique_ptr JSON_SW; 53 | extern shared_ptr LOG_sink; 54 | extern shared_ptr LOG_logger; 55 | 56 | void WCH_read(); 57 | void WCH_read_settings(); 58 | void WCH_save_settings(); 59 | 60 | void WCH_Init_Dir() { 61 | // Initialization for directory. 62 | if (_waccess(WCH_path_data.c_str(), 0) != 0) { 63 | CreateDirectoryW(WCH_path_data.c_str(), NULL); 64 | } 65 | if (_waccess((WCH_path_data + L"\\data").c_str(), 0) != 0) { 66 | CreateDirectoryW((WCH_path_data + L"\\data").c_str(), NULL); 67 | } 68 | if (_waccess((WCH_path_data + L"\\logs").c_str(), 0) != 0) { 69 | CreateDirectoryW((WCH_path_data + L"\\logs").c_str(), NULL); 70 | } 71 | if (_waccess(WCH_path_temp.c_str(), 0) != 0) { 72 | CreateDirectoryW(WCH_path_temp.c_str(), NULL); 73 | } 74 | } 75 | 76 | void WCH_Init_Bind() { 77 | // Initialization for bind. 78 | atexit(WCH_exit); 79 | WCH_signalHandler(); 80 | ignore = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 81 | ignore = WCH_TBL.CoCreateInstance(CLSID_TaskbarList); 82 | JSON_SWB.settings_ = []() { 83 | Json::Value def; 84 | Json::StreamWriterBuilder::setDefaults(&def); 85 | def["emitUTF8"] = true; 86 | return def; 87 | }(); 88 | WCH_handle_window = GetConsoleWindow(); 89 | ignore = _setmode(_fileno(stdin), _O_WTEXT); 90 | ignore = _setmode(_fileno(stdout), _O_WTEXT); 91 | wfin.imbue(locale(".UTF-8", LC_CTYPE)); 92 | wfout.imbue(locale(".UTF-8", LC_CTYPE)); 93 | _wsystem(L"CHCP 65001 > NUL"); 94 | } 95 | 96 | void WCH_Init_Log() { 97 | // Initialization for log. 98 | WCH_Time now = WCH_GetTime(); 99 | WCH_read_settings(); 100 | if (_waccess((WCH_path_data + L"\\logs\\latest.log").c_str(), 0) != -1) { 101 | ignore = _wrename((WCH_path_data + L"\\logs\\latest.log").c_str(), (WCH_path_data + L"\\logs\\" + StrToWstr(WCH_Settings["StartTime"].asString()) + L".log").c_str()); 102 | } 103 | WCH_Settings["StartTime"] = WstrToStr(format(L"{:04}{:02}{:02}{:02}{:02}{:02}", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second)); 104 | LOG_sink = make_shared(WCH_path_data + L"\\logs\\latest.log"); 105 | LOG_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%f] [%l] [%s:%# %!] [Process %P] [Thread %t]: %v."); 106 | LOG_logger = make_shared("WCH", LOG_sink); 107 | LOG_logger->flush_on(spdlog::level::debug); 108 | spdlog::register_logger(LOG_logger); 109 | #ifdef _DEBUG 110 | spdlog::set_level(spdlog::level::debug); 111 | #else 112 | spdlog::set_level(spdlog::level::info); 113 | #endif 114 | spdlog::set_default_logger(LOG_logger); 115 | WCH_save_settings(); 116 | WCH_pre_start = false; 117 | WCH_version = WCH_VER_MAIN; 118 | #if WCH_VER_TYPE != 0 119 | #if WCH_VER_TYPE == 1 120 | WCH_version.append(L" Alpha"); 121 | #elif WCH_VER_TYPE == 2 122 | WCH_version.append(L" Beta"); 123 | #elif WCH_VER_TYPE == 3 124 | WCH_version.append(L" Rc"); 125 | #endif 126 | WCH_version.append(format(L" {}", WCH_VER_BUILD)); 127 | #endif 128 | WCH_version.append(format(L" ({})", WCH_Framework)); 129 | SPDLOG_INFO(format(L"Starting \"Web Class Helper {}\"", WCH_version)); 130 | } 131 | 132 | void WCH_Init_Var() { 133 | // Initialization for variable. 134 | WCH_title_window = format(L"{} {}", StrToWstr(WCH_Language["ProgramName"].asString()), WCH_version); 135 | #if WCH_VER_TYPE != 0 136 | WCH_SetWindowStatus(false); 137 | if (MessageBoxW(NULL, (StrToWstr(WCH_Language["PreviewWarning"].asString()) + WCH_GetCompileTime()).c_str(), L"WCH WARN", MB_ICONWARNING | MB_YESNO | MB_TOPMOST) == IDNO) { 138 | WCH_CheckAndDeleteFile(WCH_path_data + L"\\logs\\latest.log"); 139 | _exit(0); 140 | } 141 | WCH_SetWindowStatus(true); 142 | #endif 143 | } 144 | 145 | void WCH_Init_Win() { 146 | // Initialization for window. 147 | SetConsoleTitleW(WCH_title_window.c_str()); 148 | WCH_TBL->SetProgressState(WCH_handle_window, TBPF_NOPROGRESS); 149 | SetWindowLongPtrW(WCH_handle_window, GWL_STYLE, GetWindowLongPtrW(WCH_handle_window, GWL_STYLE) & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX); 150 | } 151 | 152 | void WCH_Init_Loop() { 153 | // Initialization for multiple thread loop. 154 | thread T1(WCH_check_clock_loop); 155 | T1.detach(); 156 | thread T2(WCH_message_loop); 157 | T2.detach(); 158 | wcout << StrToWstr(WCH_Language["DataReading"].asString()) << endl; 159 | WCH_progress_bar_duration = 3; 160 | thread T3(WCH_ProgressBar); 161 | T3.detach(); 162 | WCH_Sleep(4000); 163 | _wsystem(L"CLS"); 164 | } 165 | 166 | void WCH_Init() { 167 | // Initialize the whole program. 168 | _wsystem(L"CLS"); 169 | WCH_Init_Dir(); 170 | WCH_Init_Bind(); 171 | WCH_Init_Log(); 172 | WCH_read(); 173 | WCH_Init_Var(); 174 | WCH_Init_Win(); 175 | WCH_Init_Loop(); 176 | wcout << WCH_title_window << endl; 177 | wcout << StrToWstr(WCH_Language["Start"].asString()) << endl; 178 | wcout << endl; 179 | } 180 | 181 | #endif 182 | -------------------------------------------------------------------------------- /resources/en-US/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "Title": ["Key Name", "Value Type", "Description", "Default Value", "Require Restart", "Current Value", "Possible Values"], 3 | "Content": [ 4 | "Prompt when inputting command", 5 | "Make a sound prompt when count down ends", 6 | "Prompt content when trying to disable focus", 7 | "Enable prompt when trying to disable focus", 8 | "Process killing interval, in milliseconds", 9 | "Program language", 10 | "Open screenshot after saving", 11 | "Screenshot image save format (MIME)", 12 | "Screenshot image save path" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /resources/en-US/help.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": [ 3 | "Commands:", 4 | " CLOCK ADD [hour] [minute] [name] (Add clock at [hour]:[minute])", 5 | " CLOCK DELETE [hour] [minute] [name] (Delete clock at [hour]:[minute])", 6 | " CLOCK LIST (List all clocks)", 7 | " CLOCK CLEAR (Clear clock list)", 8 | "", 9 | " TASK ADD [process name] (Add task [process name] to kill when focus is enabled)", 10 | " TASK DELETE [process name] (Delete task [process name] to kill when focus is enabled)", 11 | " TASK LIST (List all tasks)", 12 | " TASK CLEAR (Clear task list)", 13 | "", 14 | " WORK ADD [name] [tag] (Add [name] with [tag] to work plan, [tag] is optional)", 15 | " WORK DELETE [name] [tag] (Delete work plan item [name] with [tag], [tag] is optional)", 16 | " WORK LIST (List all items in work plan)", 17 | " WORK CLEAR (Clear work list)", 18 | "", 19 | " HELP (Get help output)", 20 | "", 21 | " OPEN CODE (Jump to program main page in default browser) **Need Internet**", 22 | " OPEN SCREENSHOT (Open screenshot save folder)", 23 | " OPEN RELEASES (Jump to program releases page in default browser) **Need Internet**", 24 | " OPEN WIKI (Jump to program wiki page in default browser) **Need Internet**", 25 | "", 26 | " OW (Get a random sentence) **Need Internet**", 27 | "", 28 | " HIDE (Hide console window)", 29 | "", 30 | " GAME (Guessing game)", 31 | "", 32 | " TIME (Get time at once)", 33 | "", 34 | " PRTSCN (Make a screenshot and save)", 35 | "", 36 | " TRANS [info] (Translate a sentence between English / Chinese) **Need Internet**", 37 | "", 38 | " FATE (Get fate) **Need Internet**", 39 | "", 40 | " FOCUS (Enable focus mode)", 41 | "", 42 | " COUNTDOWN [h] [m] [s] (Start a count down timer which lasts [h] hour(s) [m] minute(s) [s] second(s))", 43 | "", 44 | " UPDATE (Check update for this program) **Need Internet**", 45 | "", 46 | " LICENSE (Print license information)", 47 | "", 48 | " CLEAR (Clear console window information)", 49 | "", 50 | " CONFIG SET [Key] [Value] (Set a value of settings)", 51 | " CONFIG LIST (List all values of settings)", 52 | " CONFIG WIZARD (Start wizard to config settings)", 53 | " CONFIG RESET (Reset configuration to default)", 54 | "", 55 | " DEVELOP OPENDATA (Open data folder in AppData)", 56 | " DEVELOP OPENTEMP (Open temp folder in AppData)", 57 | "", 58 | " SYSINFO (Get system information)", 59 | "", 60 | " EXIT (Exit this program and save data)", 61 | "", 62 | " RESTART (Restart this program and save data)", 63 | "", 64 | "", 65 | "Notice:", 66 | " If you want to get the full information of [command], please input \"HELP [command]\"." 67 | ], 68 | "clear": [ 69 | "Clear console window information.", 70 | "", 71 | "Usage:", 72 | "", 73 | "CLEAR", 74 | "", 75 | "This command has no parameters." 76 | ], 77 | "clock": [ 78 | "Modify clock list.", 79 | "", 80 | "Usage:", 81 | "", 82 | "CLOCK ADD [hour] [minute] [name]", 83 | "CLOCK DELETE [hour] [minute] [name]", 84 | "CLOCK CLEAR", 85 | "CLOCK LIST", 86 | "", 87 | "\"CLOCK CLEAR\" and \"CLOCK LIST\" has no parameters.", 88 | "", 89 | "If [name] has Spaces, please add double quotation marks.", 90 | "", 91 | "You can add a zero in front of [hour] / [minute] if it is less than 10. (Not required)", 92 | "", 93 | "These two commands are same:", 94 | "", 95 | "CLOCK ADD 1 1 \"something a\"", 96 | "CLOCK ADD 01 01 \"something a\"" 97 | ], 98 | "config": [ 99 | "Modify values of keys in settings.", 100 | "", 101 | "Usage:", 102 | "", 103 | "CONFIG SET [Key] [Value]", 104 | "CONFIG LIST", 105 | "CONFIG WIZARD", 106 | "CONFIG RESET", 107 | "", 108 | "[Value] is the value of settings [Key], it can be Boolean (\"True\" / \"False\") / String / Number (Must be less than 1000000000).", 109 | "", 110 | "\"CONFIG LIST\", \"CONFIG WIZARD\" and \"CONFIG RESET\" have no parameters.", 111 | "", 112 | "List of possible values of [Key]:", 113 | "" 114 | ], 115 | "countdown": [ 116 | "Start a count down timer, press Ctrl + Down to break.", 117 | "", 118 | "Usage:", 119 | "", 120 | "COUNTDOWN [h] [m] [s]", 121 | "", 122 | "You can add a zero in front of [h] / [m] / [s] if it is less than 10. (Not required)", 123 | "", 124 | "These two commands are same:", 125 | "", 126 | "COUNTDOWN 1 1 1", 127 | "COUNTDOWN 01 01 01" 128 | ], 129 | "develop": [ 130 | "Development commands.", 131 | "", 132 | "Usage:", 133 | "", 134 | "DEVELOP OPENDATA", 135 | "DEVELOP OPENTEMP", 136 | "", 137 | "These commands have no parameters." 138 | ], 139 | "exit": [ 140 | "Exit this program. (Save data)", 141 | "", 142 | "Usage:", 143 | "", 144 | "EXIT", 145 | "", 146 | "This command has no parameters." 147 | ], 148 | "fate": [ 149 | "Get fate. (**Need Internet**)", 150 | "", 151 | "Usage:", 152 | "", 153 | "FATE", 154 | "", 155 | "This command has no parameters." 156 | ], 157 | "focus": [ 158 | "Enable focus mode, press Ctrl + Down to disable.", 159 | "", 160 | "Usage:", 161 | "", 162 | "FOCUS", 163 | "", 164 | "This command has no parameters." 165 | ], 166 | "game": [ 167 | "Start a guessing game.", 168 | "", 169 | "Usage:", 170 | "", 171 | "GAME", 172 | "", 173 | "This command has no parameters." 174 | ], 175 | "help": [ 176 | "Print help information.", 177 | "", 178 | "Usage:", 179 | "", 180 | "HELP", 181 | "HELP [command name]", 182 | "", 183 | "Command name is just a word, not full command like this:", 184 | "", 185 | "HELP CLOCK ADD 1 1 something", 186 | "", 187 | "This is correct:", 188 | "", 189 | "HELP CLOCK" 190 | ], 191 | "hide": [ 192 | "Hide the main console window, press Ctrl + Down to recover.", 193 | "", 194 | "Usage:", 195 | "", 196 | "HIDE", 197 | "", 198 | "This command has no parameters." 199 | ], 200 | "license": [ 201 | "Print license of this program.", 202 | "", 203 | "Usage:", 204 | "", 205 | "LICENSE", 206 | "", 207 | "This command has no parameters." 208 | ], 209 | "open": [ 210 | "Open something (**Partial Need Internet**).", 211 | "", 212 | "Usage:", 213 | "", 214 | "OPEN CODE", 215 | "OPEN SCREENSHOT", 216 | "OPEN RELEASES", 217 | "OPEN WIKI", 218 | "", 219 | "These commands have no parameters." 220 | ], 221 | "ow": [ 222 | "Print a random sentence. (**Need Internet**)", 223 | "", 224 | "Usage:", 225 | "", 226 | "OW", 227 | "", 228 | "This command has no parameters." 229 | ], 230 | "prtscn": [ 231 | "Copy and save screenshot into `ScreenshotSavePath`.", 232 | "", 233 | "Usage:", 234 | "", 235 | "PRTSCN", 236 | "", 237 | "This command has no parameters." 238 | ], 239 | "restart": [ 240 | "Restart this program. (Save data)", 241 | "", 242 | "Usage:", 243 | "", 244 | "RESTART", 245 | "", 246 | "This command has no parameters." 247 | ], 248 | "sysinfo": [ 249 | "Get system information.", 250 | "", 251 | "Usage:", 252 | "", 253 | "SYSINFO", 254 | "", 255 | "This command has no parameters." 256 | ], 257 | "task": [ 258 | "Modify task list.", 259 | "", 260 | "Usage:", 261 | "", 262 | "TASK ADD [process name]", 263 | "TASK DELETE [process name]", 264 | "TASK CLEAR", 265 | "TASK LIST", 266 | "", 267 | "\"TASK CLEAR\" and \"TASK LIST\" has no parameters.", 268 | "", 269 | "Please add double quotation mark when [process name] has Spaces:", 270 | "", 271 | "TASK ADD explorer 1.exe", 272 | "", 273 | "This is correct:", 274 | "", 275 | "TASK ADD \"explorer 1.exe\"" 276 | ], 277 | "time": [ 278 | "Get current time.", 279 | "", 280 | "Usage:", 281 | "", 282 | "TIME", 283 | "", 284 | "This command has no parameters." 285 | ], 286 | "trans": [ 287 | "Get Chinese-English translate result. (**Need Internet**)", 288 | "", 289 | "Usage:", 290 | "", 291 | "TRANS [info]", 292 | "", 293 | "Please add double quotation mark when [info] has Spaces:", 294 | "", 295 | "TRANS Hello world!", 296 | "", 297 | "This is correct:", 298 | "", 299 | "TRANS \"Hello world!\"" 300 | ], 301 | "update": [ 302 | "Check program version and jump to release page if there is a new version. (**Need Internet**)", 303 | "", 304 | "Usage:", 305 | "", 306 | "UPDATE", 307 | "", 308 | "This command has no parameters." 309 | ], 310 | "work": [ 311 | "Modify work list.", 312 | "", 313 | "Usage:", 314 | "", 315 | "WORK ADD [name] [tag]", 316 | "WORK ADD [name]", 317 | "WORK DELETE [name] [tag]", 318 | "WORK DELETE [name]", 319 | "WORK CLEAR", 320 | "WORK LIST", 321 | "", 322 | "\"WORK CLEAR\" and \"WORK LIST\" has no parameters.", 323 | "", 324 | "Please add double quotation mark when [name] / [tag] has Spaces:", 325 | "", 326 | "WORK ADD Do something Tag A", 327 | "", 328 | "This is correct:", 329 | "", 330 | "WORK ADD \"Do something\" \"Tag A\"" 331 | ] 332 | } 333 | -------------------------------------------------------------------------------- /resources/en-US/interactive.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProgramName": "Web Class Helper", 3 | "Start": "Copyright (c) 2022 - 2023 Class Tools Develop Team.\nType \"help\", \"update\" or \"license\" for more information.", 4 | "Exit": "Exit", 5 | "PreviewWarning": "This version of the program is only used for testing.\nAre you sure you want to start the program?\nCompile time: ", 6 | "InputCommandIncorrect": "Your input command is incorrect, please check and try again.", 7 | "FileProcessingFailed": "File processing failed, please try reinstalling this program.", 8 | "NetworkError": "An network error occurred, please check your network connection and try to update this program.", 9 | "OpenScreenshotSaveFolder": "Opening screenshot save folder...", 10 | "OSVersion": "OS version", 11 | "OSArchitecture": "OS architecture", 12 | "ProgramArchitecture": "Program architecture", 13 | "JumpCode": "Jumping to main page...", 14 | "JumpReleases": "Jumping to releases page...", 15 | "JumpWiki": "Jumping to wiki page...", 16 | "CheckUpdate": "Checking update...", 17 | "FindUpdate": "Program version is less than latest formal released version, jumping to releases page...", 18 | "NoUpdate": "Program version equals or is greater than latest formal released version.", 19 | "ConfigWizardPrompt": "Please enter the new value corresponding to this key. If left blank, the current value will be used:", 20 | "Yes": "Yes", 21 | "No": "No", 22 | "Key": "Key", 23 | "Value": "Value", 24 | "Hour": "Hour", 25 | "Minute": "Minute", 26 | "Name": "Name", 27 | "ProcessName": "Process Name", 28 | "Tag": "Tag", 29 | "Unclassified": "Unclassified", 30 | "InputNumber": "Please input your number (1 ~ 10000): ", 31 | "NumberOutOfRange": "Number out of range.", 32 | "NumberSmaller": "The answer is smaller.", 33 | "NumberBigger": "The answer is bigger.", 34 | "NumberAnswer": "The number is", 35 | "NumberWin": ". You WIN!", 36 | "NumberLose": ".", 37 | "Prtscn": "The picture is in the clipboard and be saved.", 38 | "CountDown": "Starting count down timer...", 39 | "Focus": "Are you sure to enable focus?\nIf you want to disable it, press Ctrl + Down.", 40 | "DataReading": "Reading data...", 41 | "WillRestart": "The program will restart now to make language settings go into effect...", 42 | "BugMessagebox1": "Oops! An error occurred.\nPlease inform our developers with the error message by opening a new Issue in our GitHub Repository.\nError message: ", 43 | "BugMessagebox2": "\nWould you like to visit the Issues page now?" 44 | } 45 | -------------------------------------------------------------------------------- /resources/zh-CN/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "Title": ["键值名称", "值的类别", "描述", "默认值", "需要重启程序", "当前值", "可能值"], 3 | "Content": [ 4 | "输入命令时的提示符", 5 | "在倒计时结束后声音提示", 6 | "用户尝试禁用专注模式时的提示内容", 7 | "启用在用户尝试禁用专注模式时的提示", 8 | "专注模式结束进程模块间隔, 单位为毫秒", 9 | "程序语言", 10 | "截图后打开", 11 | "截图保存格式 (MIME)", 12 | "截图保存路径" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /resources/zh-CN/help.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": [ 3 | "命令:", 4 | " CLOCK ADD [hour] [minute] [name] (添加在 [hour]:[minute] 的闹钟)", 5 | " CLOCK DELETE [hour] [minute] [name] (删除在 [hour]:[minute] 的闹钟)", 6 | " CLOCK LIST (列出所有闹钟)", 7 | " CLOCK CLEAR (清空闹钟列表)", 8 | "", 9 | " TASK ADD [process name] (加入进程 [process name] 用于在启用专注模式时结束)", 10 | " TASK DELETE [process name] (删除进程 [process name] 用于在启用专注模式时结束)", 11 | " TASK LIST (列出所有进程)", 12 | " TASK CLEAR (清空进程列表)", 13 | "", 14 | " WORK ADD [name] [tag] (添加附带 [tag] 的项 [name] 到工作计划, [tag] 参数可选)", 15 | " WORK DELETE [name] [tag] (删除附带 [tag] 的项 [name] 到工作计划, [tag] 参数可选)", 16 | " WORK LIST (列出所有工作计划)", 17 | " WORK CLEAR (清空工作计划)", 18 | "", 19 | " HELP (获取帮助输出)", 20 | "", 21 | " OPEN CODE (在默认浏览器中打开程序主页) **需要网络**", 22 | " OPEN SCREENSHOT (打开截图保存文件夹)", 23 | " OPEN RELEASES (在默认浏览器中打开发布页面) **需要网络**", 24 | " OPEN WIKI (在默认浏览器中打开维基页面) **需要网络**", 25 | "", 26 | " OW (获取随机句子) **需要网络**", 27 | "", 28 | " HIDE (隐藏控制台窗口)", 29 | "", 30 | " GAME (猜数游戏)", 31 | "", 32 | " TIME (获取当前时间)", 33 | "", 34 | " PRTSCN (截图并保存)", 35 | "", 36 | " TRANS [info] (中英翻译) **需要网络**", 37 | "", 38 | " FATE (获取运势) **需要网络**", 39 | "", 40 | " FOCUS (启用专注模式)", 41 | "", 42 | " COUNTDOWN [h] [m] [s] (启动一个时长为 [h] 时 [m] 分 [s] 秒的倒计时)", 43 | "", 44 | " UPDATE (检查更新) **需要网络**", 45 | "", 46 | " LICENSE (输出许可证信息)", 47 | "", 48 | " CLEAR (清空控制台信息)", 49 | "", 50 | " CONFIG SET [Key] [Value] (设置一个键值对应的值)", 51 | " CONFIG LIST (列出设置的所有键值和值)", 52 | " CONFIG WIZARD (启动设置向导)", 53 | " CONFIG RESET (重置设置到默认值)", 54 | "", 55 | " DEVELOP OPENDATA (打开在 AppData 中的数据文件夹)", 56 | " DEVELOP OPENTEMP (打开在 AppData 中的临时文件夹)", 57 | "", 58 | " SYSINFO (获取系统信息)", 59 | "", 60 | " EXIT (退出程序并保存数据)", 61 | "", 62 | " RESTART (重启程序并保存数据)", 63 | "", 64 | "", 65 | "提示:", 66 | " 如果你想获取 [command] 命令的完整信息, 请输入 \"HELP [command]\"." 67 | ], 68 | "clear": [ 69 | "清空控制台信息.", 70 | "", 71 | "用法:", 72 | "", 73 | "CLEAR", 74 | "", 75 | "这个命令没有参数." 76 | ], 77 | "clock": [ 78 | "修改闹钟列表.", 79 | "", 80 | "用法:", 81 | "", 82 | "CLOCK ADD [hour] [minute] [name]", 83 | "CLOCK DELETE [hour] [minute] [name]", 84 | "CLOCK CLEAR", 85 | "CLOCK LIST", 86 | "", 87 | "\"CLOCK CLEAR\" 和 \"CLOCK LIST\" 没有参数.", 88 | "", 89 | "如果 [name] 中有空格, 请加入双引号.", 90 | "", 91 | "若 [hour] / [minute] 小于 10 可以在其前面加一个 0 (可选).", 92 | "", 93 | "这两个命令是相同的:", 94 | "", 95 | "CLOCK ADD 1 1 \"something a\"", 96 | "CLOCK ADD 01 01 \"something a\"" 97 | ], 98 | "config": [ 99 | "修改设置中键值对应的值.", 100 | "", 101 | "用法:", 102 | "", 103 | "CONFIG SET [Key] [Value]", 104 | "CONFIG LIST", 105 | "CONFIG WIZARD", 106 | "CONFIG RESET", 107 | "", 108 | "[Value] 是设置中键值 [Key] 的值, 它可以是 Boolean (\"True\" / \"False\") / String / Number (必须小于 1000000000).", 109 | "", 110 | "\"CONFIG LIST\", \"CONFIG WIZARD\" 和 \"CONFIG RESET\" 没有参数.", 111 | "", 112 | "[Key] 的可能的值列表:", 113 | "" 114 | ], 115 | "countdown": [ 116 | "启动倒计时, 按下 Ctrl + Down 终止.", 117 | "", 118 | "用法:", 119 | "", 120 | "COUNTDOWN [h] [m] [s]", 121 | "", 122 | "若 [h] / [m] / [s] 小于 10 可以在其前面加一个 0 (可选).", 123 | "", 124 | "这两个命令是相同的:", 125 | "", 126 | "COUNTDOWN 1 1 1", 127 | "COUNTDOWN 01 01 01" 128 | ], 129 | "develop": [ 130 | "开发命令.", 131 | "", 132 | "用法:", 133 | "", 134 | "DEVELOP OPENDATA", 135 | "DEVELOP OPENTEMP", 136 | "", 137 | "这些命令没有参数." 138 | ], 139 | "exit": [ 140 | "退出程序 (保存数据).", 141 | "", 142 | "用法:", 143 | "", 144 | "EXIT", 145 | "", 146 | "这个命令没有参数." 147 | ], 148 | "fate": [ 149 | "获取运势 (**需要网络**).", 150 | "", 151 | "用法:", 152 | "", 153 | "FATE", 154 | "", 155 | "这个命令没有参数." 156 | ], 157 | "focus": [ 158 | "启用专注模式, 按下 Ctrl + Down 禁用.", 159 | "", 160 | "用法:", 161 | "", 162 | "FOCUS", 163 | "", 164 | "这个命令没有参数." 165 | ], 166 | "game": [ 167 | "启动猜数游戏.", 168 | "", 169 | "用法:", 170 | "", 171 | "GAME", 172 | "", 173 | "这个命令没有参数." 174 | ], 175 | "help": [ 176 | "输出帮助信息.", 177 | "", 178 | "用法:", 179 | "", 180 | "HELP", 181 | "HELP [command name]", 182 | "", 183 | "命令名称只是一个词, 不是像这样的完整命令:", 184 | "", 185 | "HELP CLOCK ADD 1 1 something", 186 | "", 187 | "这是正确的:", 188 | "", 189 | "HELP CLOCK" 190 | ], 191 | "hide": [ 192 | "隐藏控制台窗口, 按下 Ctrl + Down 恢复.", 193 | "", 194 | "用法:", 195 | "", 196 | "HIDE", 197 | "", 198 | "这个命令没有参数." 199 | ], 200 | "license": [ 201 | "输出程序的许可证信息.", 202 | "", 203 | "用法:", 204 | "", 205 | "LICENSE", 206 | "", 207 | "这个命令没有参数." 208 | ], 209 | "open": [ 210 | "打开 (**部分需要网络**).", 211 | "", 212 | "用法:", 213 | "", 214 | "OPEN CODE", 215 | "OPEN SCREENSHOT", 216 | "OPEN RELEASES", 217 | "OPEN WIKI", 218 | "", 219 | "这些命令没有参数." 220 | ], 221 | "ow": [ 222 | "输出随机句子 (**需要网络**).", 223 | "", 224 | "用法:", 225 | "", 226 | "OW", 227 | "", 228 | "这个命令没有参数." 229 | ], 230 | "prtscn": [ 231 | "复制截图并保存到 `ScreenshotSavePath`.", 232 | "", 233 | "用法:", 234 | "", 235 | "PRTSCN", 236 | "", 237 | "这个命令没有参数." 238 | ], 239 | "restart": [ 240 | "重启程序 (保存数据).", 241 | "", 242 | "用法:", 243 | "", 244 | "RESTART", 245 | "", 246 | "这个命令没有参数." 247 | ], 248 | "sysinfo": [ 249 | "获取系统信息.", 250 | "", 251 | "用法:", 252 | "", 253 | "SYSINFO", 254 | "", 255 | "这个命令没有参数." 256 | ], 257 | "task": [ 258 | "修改进程列表.", 259 | "", 260 | "用法:", 261 | "", 262 | "TASK ADD [process name]", 263 | "TASK DELETE [process name]", 264 | "TASK CLEAR", 265 | "TASK LIST", 266 | "", 267 | "\"TASK CLEAR\" 和 \"TASK LIST\" 没有参数.", 268 | "", 269 | "如果 [process name] 中有空格, 请加入双引号:", 270 | "", 271 | "TASK ADD explorer 1.exe", 272 | "", 273 | "这是正确的:", 274 | "", 275 | "TASK ADD \"explorer 1.exe\"" 276 | ], 277 | "time": [ 278 | "获取当前时间.", 279 | "", 280 | "用法:", 281 | "", 282 | "TIME", 283 | "", 284 | "这个命令没有参数." 285 | ], 286 | "trans": [ 287 | "获取中英翻译结果 (**需要网络**).", 288 | "", 289 | "用法:", 290 | "", 291 | "TRANS [info]", 292 | "", 293 | "如果 [info] 中有空格, 请加入双引号:", 294 | "", 295 | "TRANS Hello world!", 296 | "", 297 | "这是正确的:", 298 | "", 299 | "TRANS \"Hello world!\"" 300 | ], 301 | "update": [ 302 | "检查更新, 若有更新则跳转到发布页面 (**需要网络**).", 303 | "", 304 | "用法:", 305 | "", 306 | "UPDATE", 307 | "", 308 | "这个命令没有参数." 309 | ], 310 | "work": [ 311 | "修改工作计划.", 312 | "", 313 | "用法:", 314 | "", 315 | "WORK ADD [name] [tag]", 316 | "WORK ADD [name]", 317 | "WORK DELETE [name] [tag]", 318 | "WORK DELETE [name]", 319 | "WORK CLEAR", 320 | "WORK LIST", 321 | "", 322 | "\"WORK CLEAR\" 和 \"WORK LIST\" 没有参数.", 323 | "", 324 | "如果 [name] / [tag] 中有空格, 请加入双引号:", 325 | "", 326 | "WORK ADD Do something Tag A", 327 | "", 328 | "这是正确的:", 329 | "", 330 | "WORK ADD \"Do something\" \"Tag A\"" 331 | ] 332 | } 333 | -------------------------------------------------------------------------------- /resources/zh-CN/interactive.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProgramName": "网课助手", 3 | "Start": "版权所有 (c) 2022 - 2023 课堂工具开发团队.\n键入 \"help\", \"update\" 或 \"license\" 获取更多信息.", 4 | "Exit": "退出", 5 | "PreviewWarning": "此版本的程序仅可用于测试.\n是否仍然要启动程序?\n编译时间: ", 6 | "InputCommandIncorrect": "你的输入信息有误, 请检查后重试.", 7 | "FileProcessingFailed": "文件操作失败, 请尝试重新安装此程序.", 8 | "NetworkError": "网络异常, 请检查网络连接并尝试更新此程序.", 9 | "OpenScreenshotSaveFolder": "正在打开截图保存文件夹...", 10 | "OSVersion": "操作系统版本", 11 | "OSArchitecture": "操作系统架构", 12 | "ProgramArchitecture": "程序架构", 13 | "JumpCode": "正在跳转至程序主页...", 14 | "JumpReleases": "正在跳转至发布页面...", 15 | "JumpWiki": "正在跳转至维基页面...", 16 | "CheckUpdate": "正在检查更新...", 17 | "FindUpdate": "当前程序版本低于最新正式版本, 正在跳转至发布页面...", 18 | "NoUpdate": "当前程序版本大于或等于最新正式版本.", 19 | "ConfigWizardPrompt": "请输入此键值所对应的新值, 留空则不变:", 20 | "Yes": "是", 21 | "No": "否", 22 | "Key": "键值", 23 | "Value": "值", 24 | "Hour": "小时", 25 | "Minute": "分钟", 26 | "Name": "名称", 27 | "ProcessName": "进程名称", 28 | "Tag": "标签", 29 | "Unclassified": "未分类", 30 | "InputNumber": "请输入你的数字 (1 ~ 10000): ", 31 | "NumberOutOfRange": "数字超出范围.", 32 | "NumberSmaller": "答案更小.", 33 | "NumberBigger": "答案更大.", 34 | "NumberAnswer": "答案是", 35 | "NumberWin": ". 你赢了!", 36 | "NumberLose": ".", 37 | "Prtscn": "截图已复制到剪贴板并保存.", 38 | "CountDown": "正在启动倒计时...", 39 | "Focus": "确定启用专注模式?\n如果你想禁用它, 按下 Ctrl + Down.", 40 | "DataReading": "正在读取数据...", 41 | "WillRestart": "程序将立即重启以使语言设置生效...", 42 | "BugMessagebox1": "哎呀! 发生了一个错误.\n请通过在我们的 GitHub 存储库中新建一个 Issue 并附带此错误代码来告知我们的开发者.\n错误代码: ", 43 | "BugMessagebox2": "\n您想现在访问 Issue 界面吗?" 44 | } 45 | -------------------------------------------------------------------------------- /scripts/build.ps1: -------------------------------------------------------------------------------- 1 | # Web Class Helper Building Script 2.1.2 2 | # This source code file is under MIT License. 3 | # Copyright (c) 2022 - 2023 Class Tools Develop Team 4 | # Contributors: ren-yc 5 | $msbuild_path = (& (${env:ProgramFiles(x86)} + "\Microsoft Visual Studio\Installer\vswhere.exe") -latest -nologo -property installationPath -format value) + "\Msbuild\Current\Bin\MSBuild.exe" 6 | $configarray = "x86", "x64", "ARM", "ARM64" 7 | if ($args[1] -eq $null) { 8 | foreach ($config in $configarray) { 9 | & $msbuild_path -m /t:Build ("/p:Configuration=" + $args[0]) ("/p:Platform=" + $config) ".\WCH.sln" 10 | } 11 | } else { 12 | & $msbuild_path -m /t:Build ("/p:Configuration=" + $args[0]) ("/p:Platform=" + $args[1]) ".\WCH.sln" 13 | } 14 | -------------------------------------------------------------------------------- /scripts/copy-internal.ps1: -------------------------------------------------------------------------------- 1 | # Web Class Helper Resource File Copying (Internal) Script 2.1.2 2 | # This source code file is under MIT License. 3 | # Copyright (c) 2022 - 2023 Class Tools Develop Team 4 | # Contributors: ren-yc 5 | $itemarray = ".\resources", ".\CONTRIBUTING.md", ".\CONTRIBUTING.zh-CN.md", ".\LICENSE", ".\README.md", ".\README.zh-CN.md", ".\SECURITY.md", ".\SECURITY.zh-CN.md", ".\WCH.ico" 6 | New-Item -Path ($env:USERPROFILE + "\Downloads") -Name ("WCH_" + $args[0] + "_all") -ItemType "directory" > $null 7 | foreach ($item in $itemarray) { 8 | Copy-Item -Path $item -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_all") -Recurse 9 | } 10 | Copy-Item -Path ".\x64\Release\WCH.exe" -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_all\WCH_x64.exe") -Recurse 11 | Copy-Item -Path ".\x86\Release\WCH.exe" -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_all\WCH_x86.exe") -Recurse 12 | Copy-Item -Path ".\ARM\Release\WCH.exe" -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_all\WCH_ARM.exe") -Recurse 13 | Copy-Item -Path ".\ARM64\Release\WCH.exe" -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_all\WCH_ARM64.exe") -Recurse 14 | -------------------------------------------------------------------------------- /scripts/copy-public.ps1: -------------------------------------------------------------------------------- 1 | # Web Class Helper Resource File Copying (Public) Script 2.1.2 2 | # This source code file is under MIT License. 3 | # Copyright (c) 2022 - 2023 Class Tools Develop Team 4 | # Contributors: ren-yc 5 | $itemarray = ".\resources", ".\CONTRIBUTING.md", ".\CONTRIBUTING.zh-CN.md", ".\LICENSE", ".\README.md", ".\README.zh-CN.md", ".\SECURITY.md", ".\SECURITY.zh-CN.md", ".\WCH.ico" 6 | New-Item -Path ($env:USERPROFILE + "\Downloads") -Name ("WCH_" + $args[0] + "_x64") -ItemType "directory" > $null 7 | foreach ($item in $itemarray + ".\x64\Release\WCH.exe") { 8 | Copy-Item -Path $item -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_x64") -Recurse 9 | } 10 | New-Item -Path ($env:USERPROFILE + "\Downloads") -Name ("WCH_" + $args[0] + "_x86") -ItemType "directory" > $null 11 | foreach ($item in $itemarray + ".\x86\Release\WCH.exe") { 12 | Copy-Item -Path $item -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_x86") -Recurse 13 | } 14 | New-Item -Path ($env:USERPROFILE + "\Downloads") -Name ("WCH_" + $args[0] + "_ARM") -ItemType "directory" > $null 15 | foreach ($item in $itemarray + ".\ARM\Release\WCH.exe") { 16 | Copy-Item -Path $item -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_ARM") -Recurse 17 | } 18 | New-Item -Path ($env:USERPROFILE + "\Downloads") -Name ("WCH_" + $args[0] + "_ARM64") -ItemType "directory" > $null 19 | foreach ($item in $itemarray + ".\ARM64\Release\WCH.exe") { 20 | Copy-Item -Path $item -Destination ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_ARM64") -Recurse 21 | } 22 | -------------------------------------------------------------------------------- /scripts/shasum.ps1: -------------------------------------------------------------------------------- 1 | # Web Class Helper SHA Verification Script 2.1.2 2 | # This source code file is under MIT License. 3 | # Copyright (c) 2022 - 2023 Class Tools Develop Team 4 | # Contributors: ren-yc 5 | pwsh -? > $null 6 | if ($LastExitCode -eq 0) { 7 | $env:PSModulePath = "$PSHOME/Modules" 8 | } 9 | $languages = "enUS", "zhCN" 10 | $langfull = @{enUS = "en-US"; zhCN = "zh-CN"} 11 | $types = "config", "help", "interactive" 12 | $content = Get-Content .\shasum.hpp -Encoding ASCII 13 | foreach ($itemlang in $languages) { 14 | foreach ($itemtype in $types) { 15 | $content = $content -replace ("#define SHASUM_" + $itemlang + "_$itemtype L`"([^`"]*)`""), ("#define SHASUM_" + $itemlang + "_$itemtype L`"" + (Get-FileHash (".\resources\" + $langfull[$itemlang] + "\" + $itemtype + ".json") -Algorithm SHA512).Hash + "`"") 16 | } 17 | } 18 | $content | Out-File .\shasum.hpp -Encoding ASCII 19 | -------------------------------------------------------------------------------- /scripts/sign.ps1: -------------------------------------------------------------------------------- 1 | # Web Class Helper OpenPGP Signature Script 2.1.2 2 | # This source code file is under MIT License. 3 | # Copyright (c) 2022 - 2023 Class Tools Develop Team 4 | # Contributors: ren-yc 5 | gpg -o ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_x64.zip.sig") -ab ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_x64.zip") 6 | gpg -o ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_x86.zip.sig") -ab ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_x86.zip") 7 | gpg -o ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_ARM.zip.sig") -ab ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_ARM.zip") 8 | gpg -o ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_ARM64.zip.sig") -ab ($env:USERPROFILE + "\Downloads\WCH_" + $args[0] + "_ARM64.zip") 9 | -------------------------------------------------------------------------------- /shasum.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper SHA Verification File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: ren-yc 6 | */ 7 | #define SHASUM_enUS_config L"C42C627152AAF392A480572357DAA62B04533906CB47123A2E076B2AC62AAB20A5FC7CD8E3616AB3E40A6F279065E8D51179F743A1DAB96EAAC521111D936099" 8 | #define SHASUM_enUS_help L"CE0ABDB590585B052B2DEBA7827D63D26D978BACE1162570A70E1FDD2E84960566233A09AAF604ADC4987C69FF35EDF244333FD176599FB6C20DACAC2F2C91AE" 9 | #define SHASUM_enUS_interactive L"C5851E96D1D283DA73F7E28796274703C9A6CA86D73D17D8EE8B24F40AEF1A412AD0513135400B897691A74B6D3DFF512DC47620DBBEED88BECF0826F3F27B52" 10 | #define SHASUM_zhCN_config L"072A83B88FE99DB13D7AA679932A37EBEAB86A0CA010974E8A9EDF1187119820107E34455BE19112CB404B96BBAD4601EEFCAF47A63A172A254FD2227108EEAD" 11 | #define SHASUM_zhCN_help L"2A9E7ADC425CDA95E7F8EB677064CE57885069BC0B58FE1077EB2AB7646AFEE7DE657D15242566204829090DE0D51E46572AD0FE25135B0038FB5727B4CA2506" 12 | #define SHASUM_zhCN_interactive L"A488B8585B8C585F1F2B573A72CD22BA9BFB1F8E3575B699EEEA350FB6FF000A178E000F5D7184FC486C62A44769E5CB3B8A3FDA5470C7FAEDE160039FF3275D" 13 | -------------------------------------------------------------------------------- /version.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Web Class Helper Version File 2.1.2 3 | This source code file is under MIT License. 4 | Copyright (c) 2022 - 2023 Class Tools Develop Team 5 | Contributors: ren-yc 6 | */ 7 | #define WCH_VER_MAIN L"2.1.2" 8 | #define WCH_VER_TYPE 1 9 | #if WCH_VER_TYPE != 0 10 | #define WCH_VER_BUILD 6 11 | #endif 12 | -------------------------------------------------------------------------------- /wiki/Brief.md: -------------------------------------------------------------------------------- 1 | Web Class Helper 网课助手——一个在网课期间的命令行小工具。 2 | 3 | 作者:Class Tools Develop Team - ren-yc (Yuchen Ren) & jsh-jsh (jinshuhang)。 4 | 5 | 本项目使用 [MIT 许可证](https://github.com/class-tools/Web-Class-Helper/blob/master/LICENSE)。 6 | -------------------------------------------------------------------------------- /wiki/Build.md: -------------------------------------------------------------------------------- 1 | **此页面适合开发人员 / 贡献者阅读。** 2 | 3 | ### 环境 4 | 5 | * Windows 10 / 11 6 | 7 | * Visual Studio 2022 8 | 9 | * PowerShell 10 | 11 | * vcpkg 12 | 13 | ### 依赖 14 | 15 | vcpkg 依赖库安装流程如下: 16 | 17 | ``` 18 | vcpkg install jsoncpp:${arch}-windows-static openssl:${arch}-windows-static spdlog:${arch}-windows-static 19 | vcpkg integrate install 20 | ``` 21 | 22 | 其中 `${arch}` 为构建的程序架构,可为 `x64` / `x86` / `ARM` / `ARM64`。 23 | 24 | ### 配置 25 | 26 | 打开项目根目录下的 `WCH.sln` 文件进入 Visual Studio 后,选择工具顶栏的 `Release` / `Debug` 和 `x64` / `x86` / `ARM` / `ARM64` 选项,再点击右侧的 `开始执行 (不调试)` 开始构建。 27 | 28 | 也可使用 [`scripts/build.ps1`](https://github.com/class-tools/Web-Class-Helper/blob/master/scripts/build.ps1) 自动化构建,具体方法见 [脚本](./Scripts)。 29 | 30 | ### 运行 31 | 32 | 构建完毕会自动运行可执行文件,之后还可直接双击运行构建目录中的可执行文件(**程序运行不受运行目录影响,但程序所在目录下必须有所需的依赖文件**)。 33 | 34 | ### 调试 35 | 36 | 在相应位置标记断点后选择 Visual Studio 工具顶栏的调试器即可。 37 | 38 | 39 | ### 问题 40 | 41 | 若在构建过程中出现 PowerShell 脚本返回值不为零的情况,请尝试以管理员身份运行 PowerShell 并执行下列命令: 42 | 43 | ``` 44 | Set-ExecutionPolicy RemoteSigned 45 | ``` 46 | 47 | _**若有任何问题欢迎与项目维护人员联系!**_ 48 | -------------------------------------------------------------------------------- /wiki/Contact.md: -------------------------------------------------------------------------------- 1 | 你可以发送邮件至以下邮箱地址: 2 | 3 | 项目负责人(暂不参与开发) [oierjsh@outlook.com](mailto:oierjsh@outlook.com), 4 | 5 | 项目维护者 [ldfx_ryc@163.com](mailto:ldfx_ryc@163.com)。 6 | -------------------------------------------------------------------------------- /wiki/Contribution.md: -------------------------------------------------------------------------------- 1 | 欢迎贡献! 2 | 3 | **我们强烈建议您尽量不在 C++ 项目中使用可被 C++ 风格函数替代的 C 语言风格函数,避免造成相关问题。** 4 | 5 | **我们强烈推荐使用最新 C++ 20 标准中的更佳特性替换支持不全面的旧版函数(如使用 C++ 20 的 `format()` 替换 C 风格 `sprintf()`)。** 6 | 7 | 若有任何疑问欢迎 [联系我们](./Contact)。 8 | 9 | **提交需使用我们的 [提交格式](https://github.com/class-tools/CTGitCommitMsgStd)。** 10 | 11 | **代码风格需遵循项目根目录下的 `.clang-format` 文件中的 Clang Format 设置,可通过启用相关 GitHub Action 检查。** 12 | 13 | 在进行修改之后,你可以创建一个 Pull Request 来对本项目贡献。 14 | 15 | **在 Pull Request 中,我们会运行相关的 CI 工作流(含 CodeQL 代码漏洞静态扫描工具、Codecov 代码 API 测试覆盖率检测),以检查代码。** 16 | -------------------------------------------------------------------------------- /wiki/Directories.md: -------------------------------------------------------------------------------- 1 | ### 资源文件 2 | 3 | `resources` 文件夹包含若干个以语言代码为名称的子文件夹。 4 | 5 | 每个子文件夹下包含 3 个 Json 格式的 `.json` 依赖文件,分别保存着配置、帮助、交互的信息数据,请勿更改。 6 | 7 | ### 运行时生成 8 | 9 | **所有运行时生成的数据文件均在 `%USERPROFILE%/AppData/Local/WCH` 目录下。** 10 | 11 | `settings.json` 是程序的配置文件(若无则按默认配置生成)。 12 | 13 | `data` 文件夹下最多包含 3 个 Json 格式的 `.json` 数据文件,分别保存着闹钟列表、进程列表、工作计划的相关信息,请勿随意更改。 14 | 15 | `logs` 文件夹下用于存放 `.log` 日志文件,保存着每一次程序运行的详细信息,您在报告错误时可以向我们发送该次运行日志文件。 16 | 17 | ### 目录结构 18 | 19 | ``` 20 | AppData/ 21 | - Local/ 22 | - - WCH/ 23 | - - - data/ 24 | - - - - clock.json 25 | - - - - task.json 26 | - - - - work.json 27 | - - - logs/ 28 | - - - - *.log 29 | - - - settings.json 30 | WCHExecDir/ 31 | - resources/ 32 | - - en-US/ 33 | - - - config.json 34 | - - - help.json 35 | - - - interactive.json 36 | - - zh-CN/ 37 | - - - config.json 38 | - - - help.json 39 | - - - interactive.json 40 | - CONTRIBUTING.md 41 | - CONTRIBUTING.zh-CN.md 42 | - LICENSE 43 | - README.md 44 | - README.zh-CN.md 45 | - SECURITY.md 46 | - SECURITY.zh-CN.md 47 | - WCH.exe 48 | - WCH.ico 49 | ``` 50 | -------------------------------------------------------------------------------- /wiki/FAQ.md: -------------------------------------------------------------------------------- 1 | Q: 为什么需联网命令无任何输出? 2 | 3 | A: 可能是由于是网络不稳定,或暂时无法连接到目标服务器。 4 | 5 | Q: 为什么 `update` 命令总是获取最新版本号失败? 6 | 7 | A: 可能是因为您的计算机访问 GitHub Pages 服务器不稳定,请稍后再试。 8 | 9 | Q: 为什么程序启动运行或执行 `help` 命令时闪退? 10 | 11 | A: 可能是由于程序的权限不足以在程序所在目录下的 `resources` 目录读取文件,可通过修改目录权限设置解决;也可能是资源文件损坏,请尝试重新安装程序。 12 | -------------------------------------------------------------------------------- /wiki/Home.md: -------------------------------------------------------------------------------- 1 | 欢迎来到 Web Class Helper 的 Wiki! 2 | 3 | 这个 Wiki 仅支持一个语言:zh-CN。 4 | -------------------------------------------------------------------------------- /wiki/Installation.md: -------------------------------------------------------------------------------- 1 | **本程序仅支持 Windows 系统。** 2 | 3 | 直接解压缩 `.zip` 压缩文件到合适的目录下即可开始使用 Web Class Helper。 4 | 5 | 可使用 `.sig` 文件验证 `.zip` 压缩文件的完整性。 6 | 7 | **请确保使用目录的权限已经赋予主程序读写权限。** 8 | -------------------------------------------------------------------------------- /wiki/Scripts.md: -------------------------------------------------------------------------------- 1 | [**`scripts/build.ps1`**](https://github.com/class-tools/Web-Class-Helper/blob/master/scripts/build.ps1) 2 | 3 | ``` 4 | Usage: build.ps1 mode [arch] 5 | 6 | Arguments: 7 | mode Build mode (Debug / Release). 8 | arch Build architecture (x86 / x64 / ARM / ARM64), build all when not specified. 9 | ``` 10 | 11 | # 12 | 13 | [**`scripts/copy-internal.ps1`**](https://github.com/class-tools/Web-Class-Helper/blob/master/scripts/copy-internal.ps1) 14 | 15 | ``` 16 | Usage: copy-internal.ps1 ver 17 | 18 | Arguments: 19 | ver Release version, use as directory name. 20 | ``` 21 | 22 | # 23 | 24 | [**`scripts/copy-public.ps1`**](https://github.com/class-tools/Web-Class-Helper/blob/master/scripts/copy-public.ps1) 25 | 26 | ``` 27 | Usage: copy-public.ps1 ver 28 | 29 | Arguments: 30 | ver Release version, use as directory name. 31 | ``` 32 | 33 | # 34 | 35 | [**`scripts/shasum.ps1`**](https://github.com/class-tools/Web-Class-Helper/blob/master/scripts/shasum.ps1) 36 | 37 | ``` 38 | Usage: shasum.ps1 39 | ``` 40 | 41 | # 42 | 43 | [**`scripts/sign.ps1`**](https://github.com/class-tools/Web-Class-Helper/blob/master/scripts/sign.ps1) 44 | 45 | ``` 46 | Usage: sign.ps1 ver 47 | 48 | Arguments: 49 | ver Release version, use as file name. 50 | ``` 51 | -------------------------------------------------------------------------------- /wiki/Use.md: -------------------------------------------------------------------------------- 1 | **建议安装应用 Windows Terminal 以获得更好的终端交互体验 (同时部分仅在控制台主机 `conhost.exe` 中出现的漏洞不会被修复)。** 2 | 3 | **本程序中宽字符 (含中文) 可作为参数输入。** 4 | 5 | 具体信息请在程序中输入 `help` 获取所有命令列表或使用 `help [command]` 获取某一命令的具体信息。 6 | 7 | 关于脚本的使用帮助请至 [脚本](./Scripts)。 8 | 9 | **_请注意,本团队不对程序内使用的外部 API (`ow` 和 `fate`) 所提供的内容负责。_** 10 | -------------------------------------------------------------------------------- /wiki/_Footer.md: -------------------------------------------------------------------------------- 1 | **Class Tools Develop Team 现已建立官方 QQ 讨论群。** 2 | 3 | 若您想加入我们团队的官方 QQ 讨论群,请访问 [加入群聊](https://jq.qq.com/?_wv=1027&k=PYH4ldDF)。 4 | -------------------------------------------------------------------------------- /wiki/_Sidebar.md: -------------------------------------------------------------------------------- 1 | ## 开始 2 | 3 | * [简介](./Brief) 4 | 5 | * [安装](./Installation) 6 | 7 | * [目录结构](./Directories) 8 | 9 | * [使用方法](./Use) 10 | 11 | * [构建](./Build) 12 | 13 | * [脚本](./Scripts) 14 | 15 | ## 交流 16 | 17 | * [常见问题](./FAQ) 18 | 19 | * [联系我们](./Contact) 20 | 21 | * [贡献](./Contribution) 22 | --------------------------------------------------------------------------------