Compare commits

...

1063 Commits

Author SHA1 Message Date
fc31b528da
Merge pull request #253 from gnh1201/dev
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
Merge pull request #252 from gnh1201/master
2025-05-12 02:31:38 +09:00
718dd77c1b
Merge pull request #252 from gnh1201/master
Update commit history to the dev branch
2025-05-12 02:30:34 +09:00
e1cb460649
Merge pull request #248 from baramofme/master
Fix Gemini llm call
2025-05-12 02:25:56 +09:00
Jihoon Yi
99dc2d321c
Merge branch 'gnh1201:master' into master 2025-05-11 14:28:09 +09:00
0ccddd4e75
Merge pull request #249 from gnh1201/dev
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
Improve the concept to access a blob sources
2025-05-11 01:30:30 +09:00
5087359ac3 Revert "Replace the keyword void to Task for async method"
This reverts commit 0ad978bb6b.
2025-05-11 01:21:08 +09:00
1ab70d7cd7 Revert "Update CDN servers list"
This reverts commit 0438ee9a50.
2025-05-11 01:05:09 +09:00
0438ee9a50 Update CDN servers list 2025-05-10 21:31:49 +09:00
Jihoon Yi
90ea515f41
Update winservice.js
fix wrong typo
2025-05-10 20:51:17 +09:00
Jihoon Yi
2bff4df4be
Update security.js
fix wrong typo
2025-05-10 20:50:24 +09:00
Jihoon Yi
10606532cb
Update testloader.js
Add missing closing brackets in test_implementsobject
2025-05-10 18:38:45 +09:00
0ad978bb6b Replace the keyword void to Task for async method 2025-05-10 16:53:47 +09:00
Jihoon Yi
452675273b
Update language-inference-engine.js 2025-05-10 16:36:53 +09:00
Jihoon Yi
d8a29eaeee
Update language-inference-engine.js
- Add response type check before parsing
- Wrap JSON.parse in a try/catch to handle potential malformed responses.
- Use “system” role for the initial bias message on gemini model object's wrap
2025-05-10 16:30:46 +09:00
Jihoon Yi
b1078cd36c
Add missing model selection in honoai_gemini.ai.js
Add missing model selection
2025-05-10 16:22:08 +09:00
a001471451 Improve the concept to access a blob sources 2025-05-10 16:07:36 +09:00
Jihoon Yi
bcdfef3f6f
Create honoai_gemini.ai.js
Add honoi ai call with gemini
2025-05-10 15:54:04 +09:00
Jihoon Yi
ef23e41e3a
Update language-inference-engine.js
Fix gemini call broken
2025-05-10 15:50:55 +09:00
5f10d50a3c
Create clean_chrome_pup.bat
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
2025-05-08 22:31:55 +09:00
aee5fb22d0
Merge pull request #245 from gnh1201/dev
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
Add JavaScript CDN servers
2025-05-05 23:44:59 +09:00
14c8b12df7 Add a CDN servers 2025-05-05 23:32:41 +09:00
deed89560b Update ResourceServer.cs 2025-05-05 23:22:02 +09:00
eb32437f96 Update ResourceServer.cs 2025-05-05 21:34:50 +09:00
c95b7a373b Update ResourceServer.cs 2025-05-05 21:33:06 +09:00
302e7ce4fc Add an available CDN servers 2025-05-05 19:13:41 +09:00
a5fc5de78f Update ResourceServer.cs 2025-05-05 17:47:50 +09:00
d362d852ad Add JavaScript CDN servers 2025-05-05 17:38:48 +09:00
2a3f9fb4fa
Update README.md
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
2025-05-01 14:32:48 +09:00
944751121c
Merge pull request #243 from gnh1201/dev
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
Add the example to use function calling on LLM
2025-04-27 13:14:27 +09:00
fb420d1116 Add the example to use function calling on LLM 2025-04-27 13:09:03 +09:00
26af578178
Merge pull request #242 from gnh1201/dev
Set throttle to the prompt context
2025-04-27 11:43:52 +09:00
245dd85341 Update editor.html 2025-04-27 11:39:43 +09:00
fb6596fe64 Update editor.html 2025-04-27 11:10:00 +09:00
a42180d244 Set throttle to the prompt context 2025-04-27 10:50:52 +09:00
73b24f9a56
Merge pull request #240 from gnh1201/dev
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
Fix bug when use DevTools CORS policy (WebSocket error)
2025-04-22 21:31:37 +09:00
eae2795bbf Update Program.cs 2025-04-22 21:27:23 +09:00
98e73b2372 Fix bug when use the devtools protocol with the remote allow origins (Fix WebSocket error) 2025-04-22 21:26:42 +09:00
2225ab9011
Merge pull request #239 from gnh1201/dev
Improve WelsonJS Editor with React framework
2025-04-18 19:51:56 +09:00
4c0895850b Update the integrity attributes 2025-04-18 19:48:41 +09:00
ea412908ef Update editor.html 2025-04-18 19:31:23 +09:00
05ea48a0be some updates 2025-04-18 19:22:25 +09:00
243ff95198 Migrate to React framework 2025-04-18 01:06:27 +09:00
8341394912
Merge pull request #238 from gnh1201/dev
Forward Whois and DNS query data to LLM services
2025-04-12 14:34:59 +09:00
e5a89c9182 Forward Whois and DNS query data to LLM services
Forward Whois and DNS query data to LLM services (e.g. Server configuration assistant)
2025-04-12 14:24:59 +09:00
df5b8cd9f0
Merge pull request #237 from gnh1201/dev
Add support the Azure AI, Optimize the HTTPClient object uses.
2025-04-11 14:19:55 +09:00
e7b6a87175 Reduce code complexity 2025-04-11 14:15:03 +09:00
5b2863058a Add support the Azure AI, Optimize the HTTPClient object uses. 2025-04-11 13:44:21 +09:00
cd8844afef
Merge pull request #236 from gnh1201/dev
Update the markdown files
2025-04-10 16:34:47 +09:00
b26d979b8d Update the markdown files 2025-04-10 16:12:43 +09:00
5446a1bee0
Update README.md
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-04-10 15:56:18 +09:00
10101986be
Update README.md
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-04-10 15:56:09 +09:00
47a5f50712
Update README.md
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-04-10 15:56:01 +09:00
86517f313c
Update README.md
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-04-10 15:55:48 +09:00
b6d34404b5 Update README.md 2025-04-10 13:50:37 +09:00
88ac0cd31e Update README.md 2025-04-10 13:41:57 +09:00
3e0fd7c532 Update README.md, SECURITY.MD 2025-04-10 13:39:23 +09:00
22d10cd28b
Merge pull request #235 from gnh1201/dev
Update SECURITY.MD
2025-04-10 13:29:19 +09:00
0e95b72b21 Update SECURITY.MD 2025-04-10 13:23:16 +09:00
426a9d7721
Merge pull request #234 from gnh1201/dev
Update 2025-04-10
2025-04-10 02:29:10 +09:00
d42210f922
Update WelsonJS.Toolkit/WelsonJS.Launcher/Program.cs
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-04-10 02:27:42 +09:00
e853003bda
Merge branch 'master' into dev 2025-04-10 02:26:21 +09:00
8ca4faa88a
Update README.md
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-04-10 02:23:24 +09:00
f84f2195c3 Revert Cache Compression 2025-04-10 02:12:28 +09:00
1742ca385b Update AzureAi.cs 2025-04-10 02:00:18 +09:00
2a9ebaff51 Update AzureAi.cs 2025-04-10 01:48:33 +09:00
916154499c Some updates 2025-04-09 19:58:41 +09:00
53a84b2349 Update README.md 2025-04-07 14:45:25 +09:00
6e3eb5c1d3 Update README.md 2025-04-07 14:44:03 +09:00
4b4754ae16 Update README.md 2025-04-07 14:43:27 +09:00
a273d6aac6 Update README.md 2025-04-07 14:41:56 +09:00
9e1878628b Update README.md 2025-04-07 14:33:47 +09:00
04ce7fdae5 Update README.md, SECURITY.MD 2025-04-07 14:31:11 +09:00
f7de7bd430 Add Cache Compression 2025-04-06 15:23:19 +09:00
ab8a864519
Update README.md 2025-04-05 23:32:10 +09:00
427f8dded0
Update README.md 2025-04-05 23:24:54 +09:00
a96764f725
Update README.md 2025-04-05 23:24:17 +09:00
46d0244c34
Merge pull request #221 from gnh1201/dev
Add the cached blob #220
2025-04-05 20:13:40 +09:00
2cb3c1c331 Add the cached blob 2025-04-05 20:05:23 +09:00
231e6a56bd
Merge pull request #219 from gnh1201/dev
Change the remote blob server to localhost
2025-04-05 17:47:25 +09:00
295ad2fca8 Update ResourceServer.cs 2025-04-05 17:43:34 +09:00
9ecc93a399 Update ResourceServer.cs 2025-04-05 17:42:44 +09:00
2896cc6bf1 Some updates 2025-04-05 17:27:38 +09:00
be37951807 Add the blob server gateway 2025-04-05 17:10:19 +09:00
d38e26ba67
Merge pull request #218 from gnh1201/dev
Refactor an endpoints of the web based editor
2025-04-05 15:24:50 +09:00
dd85e98c9a Some updates 2025-04-05 15:16:15 +09:00
d8fa8779de Refactor an endpoints of the web based editor 2025-04-05 12:53:28 +09:00
f6fd43ae50
Merge pull request #214 from gnh1201/dev
Add Azure AI service (Azure AI Foundry), Add the AppConfig manager
2025-04-02 11:34:00 +09:00
96dbe7b2cd Add Azure AI service (Azure AI Foundry), Add the AppConfig manager 2025-04-02 11:25:23 +09:00
c1fe39d3cc
Merge pull request #213 from gnh1201/dev
Adapt a code review, SRI, CORS, etc.
2025-03-31 17:41:01 +09:00
56ee12741c some updates 2025-03-31 17:09:28 +09:00
4372bdb09d some updates 2025-03-31 16:59:56 +09:00
b21f967a6a Update bootstrap.bat 2025-03-31 16:31:07 +09:00
40b0b704e3 some updates 2025-03-31 15:06:03 +09:00
9a8ee4d7f9 some updates 2025-03-31 14:50:02 +09:00
4f319d474f some updates 2025-03-31 14:18:03 +09:00
93ed60bcf7 some updates 2025-03-31 14:16:35 +09:00
5d717505f4 Edit the codes from code review result 2025-03-30 22:24:35 +09:00
b0e50d33bc Merge branch 'dev' of https://github.com/gnh1201/welsonjs into dev 2025-03-30 21:12:10 +09:00
c0f9816000 Update editor.html 2025-03-30 20:50:54 +09:00
00ea473683 set SRI and CORS policy strictly to editor.html 2025-03-30 20:48:03 +09:00
7e9054fb8f
Merge pull request #203 from gnh1201/dev
Revert "Reduce SAS token period to 2 years"
2025-03-27 18:02:51 +09:00
f29a63027f Revert "Reduce SAS token period to 2 years"
This reverts commit e930cf86fd.
2025-03-27 17:55:13 +09:00
3419e62c6a
Merge pull request #202 from gnh1201/dev
Change the blob download server
2025-03-27 17:50:53 +09:00
e930cf86fd Reduce SAS token period to 2 years 2025-03-27 17:42:58 +09:00
c0a27efd8d Update bootstrap.bat 2025-03-27 17:35:10 +09:00
d42539c0a8
Update README.md 2025-03-26 11:44:37 +09:00
8389f755fd
Merge pull request #200 from gnh1201/dev
Update the assembly info
2025-03-23 16:02:36 +09:00
6d5af6d422 Update the assembly info 2025-03-23 15:55:45 +09:00
7738b3b898
Merge pull request #199 from gnh1201/dev
Add the mutex to avoid redundant
2025-03-23 15:31:28 +09:00
c1052e0147 Code consistency fix, Replace Random to RandomNumberGenerator, Mutex dispose 2025-03-23 15:12:15 +09:00
d3135bef8e Add the mutex to avoid redundant 2025-03-23 14:43:23 +09:00
54af38b6b6 Add TFA (TOTP) endpoint 2025-03-21 23:50:22 +09:00
9d4b7e535c
Merge pull request #198 from gnh1201/dev
Update setup.iss
2025-03-21 19:51:01 +09:00
8190c80f1a Update setup.iss 2025-03-21 19:39:28 +09:00
c887e1914d
Merge pull request #197 from gnh1201/dev
Update in 2025-03-21
2025-03-21 17:25:45 +09:00
394ce1e903 Update in 2025-03-21 2025-03-21 17:18:39 +09:00
d2cba59b6b Update in 2025-03-21
1. Remove PHP asset files. (Moved to github.com/gnh1201/caterpillar)
2. Add `ARM64` architecture support to lib/python3.js and lib/http.js files.
3. Update the installer profile
2025-03-21 12:03:12 +09:00
7a23340623
Merge pull request #196 from gnh1201/dev
Update http.js
2025-03-21 10:47:13 +09:00
5a2a48945b Update http.js 2025-03-21 10:26:54 +09:00
51da417506 Update http.js 2025-03-20 17:03:31 +09:00
a148319b44
Merge pull request #195 from gnh1201/dev
Update setup.iss
2025-03-20 13:24:31 +09:00
340794d14c Update setup.iss 2025-03-20 13:14:01 +09:00
f6b222e469
Merge pull request #194 from gnh1201/dev
Update the installer profile, Dns Query, and namespaces
2025-03-20 11:29:15 +09:00
fb17f37188 Update setup.iss 2025-03-20 11:15:37 +09:00
2450bc0b9c Update ResourceServer.cs 2025-03-20 11:02:33 +09:00
6737b4885b Update DnsQuery.cs 2025-03-20 10:11:29 +09:00
81d6e67f94 Update the namespaces 2025-03-20 09:42:38 +09:00
911be8135c
Merge pull request #193 from gnh1201/dev
Add DNS Query feature
2025-03-19 17:10:42 +09:00
e68c1e5e2f Add DNS Query feature 2025-03-19 17:03:06 +09:00
07e0665275
Merge pull request #192 from gnh1201/dev
Improve initial warming up time, and add WHOIS request feature
2025-03-19 16:02:23 +09:00
4e78905bbc Enhance a performance and security in PR 2025-03-19 15:48:12 +09:00
e2c9169121 Update editor.html, ResourceServer.cs 2025-03-19 14:02:12 +09:00
1f859c75c6 Improve initial start time, and Add WHOIS request 2025-03-19 12:10:00 +09:00
b2fdc38790
Merge pull request #191 from gnh1201/dev
Minor fixes
2025-03-17 17:53:41 +09:00
07991329fc Update editor.html 2025-03-17 17:47:44 +09:00
5cea33ec20
Merge pull request #190 from gnh1201/dev
Minor fixes
2025-03-17 17:40:37 +09:00
01e94830e7 Update editor.html 2025-03-17 17:23:55 +09:00
c8e757487e Update editor.html 2025-03-17 17:19:05 +09:00
9cd4f2d744
Merge pull request #189 from gnh1201/dev
Minor fixes for the context menus
2025-03-17 17:02:32 +09:00
2a2cdf8a4a Update MainForm.cs 2025-03-17 16:49:04 +09:00
4a46d6211c
Merge pull request #188 from gnh1201/dev
One more fixes for #187
2025-03-17 14:01:27 +09:00
98b9019633 Update editor.html 2025-03-17 13:54:38 +09:00
434f5d4a8d Update editor.html 2025-03-17 13:49:23 +09:00
46a3049d62 Update editor.html 2025-03-17 13:29:00 +09:00
be9ed37eea Update editor.html 2025-03-17 13:24:03 +09:00
dd978ab952
Merge pull request #187 from gnh1201/dev
LLM AI based code generation in the code editor
2025-03-17 12:39:46 +09:00
15b2e606b1 Some updates for optimization and security 2025-03-17 11:09:00 +09:00
0cbb22ac26 Add LLM AI code generation 2025-03-16 18:14:02 +09:00
11afb64706
Merge pull request #186 from gnh1201/dev
Update 2025-03-16
2025-03-16 15:50:52 +09:00
240a65e61c Update ResourceServer.cs 2025-03-16 15:37:26 +09:00
2da5051c5b Update ResourceServer.cs 2025-03-16 15:08:20 +09:00
1124dc5bf4 Add a setting to separate web browser user profiles. 2025-03-16 14:28:59 +09:00
b93d16669f Update ExecutablesCollector.cs 2025-03-16 04:33:39 +09:00
5ab1c97b79
Merge pull request #185 from gnh1201/dev
Add the code completion with Monaco Editor #183
2025-03-16 03:44:02 +09:00
0aceb0e86b Update ResourceServer.cs 2025-03-16 03:30:15 +09:00
dc06506276 Add the code completion with Monaco Editor #183
This update supports the ability to auto-completion executable file paths in the code editor through the list of software installed on the local computer.
2025-03-16 03:11:59 +09:00
7947d91c3a
Merge pull request #184 from gnh1201/dev
Add some code for #183 (Auto completion)
2025-03-15 00:55:40 +09:00
1f2a1e79b7 Update ResourceServer.cs 2025-03-15 00:46:07 +09:00
6722704859 Update ResourceServer.cs 2025-03-15 00:37:03 +09:00
96bd29c06a Adopt the comments of the AI reviewers 2025-03-15 00:23:20 +09:00
c6240fb793
Update codeql-analysis.yml 2025-03-15 00:13:02 +09:00
74ca7dcd6c
Update llm-code-review.yml 2025-03-15 00:12:27 +09:00
b1cabe9fbb Add some code for #183 2025-03-15 00:07:28 +09:00
6bb1dcc3f1
Merge pull request #182 from gnh1201/dev
Add the notify (tray) icon to Launcher
2025-03-14 17:59:20 +09:00
b3f75d3c53 Fix status code 2025-03-14 17:55:05 +09:00
4d26f504f8 Merge branch 'dev' of https://github.com/gnh1201/welsonjs into dev 2025-03-14 17:47:15 +09:00
4bc2a95c42 Add the notify (tray) icon to Launcher
Add the notify (tray) icon to Launcher
2025-03-14 17:46:38 +09:00
c382ffbf46
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-03-12 16:12:15 +09:00
6fa4f64e0b
Merge pull request #181 from gnh1201/dev
AI code review workflow test #180
2025-03-12 15:50:25 +09:00
6d601aa79f Update editor.html 2025-03-12 15:47:12 +09:00
4105b567ee Update editor.html 2025-03-12 15:03:43 +09:00
4fbd0970ed
Update llm-code-review.yml
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-03-11 14:54:29 +09:00
be782c1ebd Update codeql-analysis.yml 2025-03-10 10:43:21 +09:00
1982b0fc6b Update README.md 2025-03-10 10:28:08 +09:00
ff88f484f6
Update llm-code-review.yml
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-03-10 10:02:03 +09:00
e5c970bea1
Create llm-code-review.yml 2025-03-10 09:59:56 +09:00
653c44dbf6
Merge pull request #179 from gnh1201/dev
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Add the favicon.ico response when try a request
2025-03-10 00:33:14 +09:00
9213d18c90 Reduce complexity: Splitting the GetResource method into separate methods 2025-03-10 00:16:42 +09:00
7c19dd366f Add the favicon.ico response when try a request 2025-03-09 23:56:38 +09:00
39c1fbb29b
Update README.md 2025-03-09 18:44:03 +09:00
53124007c2
Update editor.html 2025-03-09 18:01:12 +09:00
fdc6062433
Update editor.html 2025-03-09 17:50:17 +09:00
bb3cd40012
Add the Monaco Editor to WelsonJS Launcher #137
Update editor.html
2025-03-09 17:17:54 +09:00
e9c6a493eb Add the Monaco Editor to WelsonJS Launcher #137
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-03-08 22:52:45 +09:00
24ba77d1f6
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-03-04 16:52:10 +09:00
a3c26a202d
Update README.md 2025-03-04 16:50:06 +09:00
e9a6e414c1
Update README.md 2025-03-04 16:49:51 +09:00
aa5f3c9b6c Add discord chat link
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-02-28 10:56:47 +09:00
1cf0a8920a Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-02-26 22:16:24 +09:00
ba35b022c6 Update README.md 2025-02-26 22:15:29 +09:00
f68c7fd7bd Update README.md 2025-02-26 22:10:11 +09:00
e942f0b9e8 Add the global settings form 2025-02-26 22:01:57 +09:00
ac6cdb0d76
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-02-26 13:36:44 +09:00
16723acd97
Update README.md 2025-02-26 13:33:58 +09:00
b31a2d43bb
Update README.md 2025-02-26 13:19:57 +09:00
be6f4b027f
Update README.md 2025-02-26 13:14:18 +09:00
1e93dd22ce
Update README.md 2025-02-26 13:03:04 +09:00
64b2eb0f1b
Update README.md 2025-02-26 13:01:33 +09:00
a80c017206
Update README.md 2025-02-26 12:55:38 +09:00
913eb9f9bf
Update README.md 2025-02-26 12:54:35 +09:00
d9175b83a2
Update README.md 2025-02-26 12:53:06 +09:00
f6d112e38f
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-02-25 15:35:54 +09:00
40129f87e3
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-02-23 17:40:10 +09:00
e375ddf6f5 Add the toolstrip menu "Run as Administrator..." 2025-02-23 15:27:09 +09:00
51110e54b7 allow search an instances in the temporary folder
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-02-23 03:29:51 +09:00
7d2f76e2dd
Merge pull request #174 from eltociear/patch-1
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
docs: update README.md
2025-02-21 10:30:39 +09:00
Ikko Eltociear Ashimine
5590c81be5
docs: update README.md
minor fix
2025-02-21 03:30:08 +09:00
2c25eb2a43
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-02-20 21:49:19 +09:00
ece0054da6 Fix the letter case
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-02-20 14:25:39 +09:00
09e9cccc51 Change the toolkit binary download path 2025-02-20 14:19:54 +09:00
85a315eac7 Remove the detect Windows version because of syntax error 2025-02-20 14:11:22 +09:00
3349255d9a Update the .env file location 2025-02-20 13:54:59 +09:00
c4be361f95 Fix instance data survival time issue
The data in the Temp directory has a short retention period, posing a risk of data loss. Therefore, it has been changed to the AppData directory.
2025-02-20 12:57:53 +09:00
432fd39df2 Update bootstrap.bat
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-02-18 12:53:52 +09:00
b31add8d74 Update language-inference-engine.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-02-15 16:09:39 +09:00
e659c8daf2 Update installService.bat
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-02-11 23:00:27 +09:00
62ab354674 Update installService.bat
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-02-11 17:17:51 +09:00
8285825c8b Update test.html 2025-02-11 17:00:43 +09:00
e1ebb0ac2a Update test-oss-korea-2023.json 2025-02-11 16:53:26 +09:00
1aa575b13c Revert "Update test-oss-korea-2023.json"
This reverts commit 0f2e874a4a.
2025-02-11 16:50:42 +09:00
0f2e874a4a Update test-oss-korea-2023.json 2025-02-11 16:40:20 +09:00
c9578ae9f1 Update test.html 2025-02-11 16:36:53 +09:00
a4a7391de6 Fix test page error 2025-02-11 16:35:29 +09:00
495944a3b6
Update router.js 2025-02-11 16:25:13 +09:00
477848b77f Update InstancesForm.Designer.cs
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-02-09 22:42:16 +09:00
a3289cc81d Fix some bugs 2025-02-09 22:05:43 +09:00
4fd38e75c3 Add the list of instances
This commit allows restoring and rerunning previously deployed instances.
2025-02-09 21:41:21 +09:00
5a09d7a79a Add support the Content-Type based URI router
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Add support the Content-Type based URI router
2025-02-08 21:45:43 +09:00
b912ae0b08 Update apikey.json
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-02-07 23:47:17 +09:00
eacd68ce88 Update language-inference-engine.js 2025-02-07 23:41:11 +09:00
2251494a48 Update language-inference-engine.js
1. Fix mistypos (e.g.., missing return)
2. Add clovastudio LLM
2025-02-07 23:35:25 +09:00
5b092c7f7a Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-02-03 16:42:50 +09:00
4d78bbf31e Update README.md 2025-02-03 16:42:43 +09:00
1c4e607d3d Update README.md 2025-02-03 16:36:03 +09:00
80de6da382 Update README.md 2025-02-03 16:21:51 +09:00
3edff1550c Update README.md 2025-02-03 16:12:21 +09:00
724b89f361 Update README.md 2025-02-03 16:00:03 +09:00
06a09fbc3e
Update language-inference-engine.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-01-31 15:55:41 +09:00
2c2696d75f
Update README.md 2025-01-31 13:12:49 +09:00
36d51749b3
Update README.md 2025-01-31 13:10:07 +09:00
ac84bb222d
Update README.md 2025-01-31 13:03:19 +09:00
7c87f25f25
Update README.md 2025-01-31 13:00:20 +09:00
a2123f8765 Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-01-30 23:39:19 +09:00
2078b45566 Update language-inference-engine.js 2025-01-30 23:33:35 +09:00
a7a00a38d8 Update language-inference-engine.js 2025-01-30 23:28:44 +09:00
a5275388e2 Update language-inference-engine.js 2025-01-30 23:28:28 +09:00
b5704d5746 Update language-inference-engine.js 2025-01-30 23:15:58 +09:00
ee038c6c20 Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-01-30 19:54:10 +09:00
827dea443c Update README.md 2025-01-30 19:53:39 +09:00
3cf7f6c07c Update language-inference-engine.js 2025-01-30 19:47:30 +09:00
408e98e46b Update README.md 2025-01-30 19:14:11 +09:00
2878eac81d Update README.md 2025-01-30 19:06:47 +09:00
60a26b3ad0 Update language-inference-engine.js 2025-01-30 18:59:04 +09:00
4c8a127ad3 Update language-inference-engine.js 2025-01-30 17:12:22 +09:00
3f993975eb Merge branch 'master' of https://github.com/gnh1201/welsonjs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-01-29 18:41:25 +09:00
68e7e4aec0 Update language-inference-engine.js 2025-01-29 18:24:32 +09:00
e7031baf0b
Update test-oss-korea-2023.json 2025-01-29 18:13:46 +09:00
7d3659ebce Update README.md 2025-01-29 18:07:30 +09:00
a1e254ceb0 Update README.md 2025-01-29 18:06:25 +09:00
0f1c2f3e85 Update README.md 2025-01-29 18:05:35 +09:00
6496da9b7e Update language-inference-engine.js 2025-01-29 17:41:29 +09:00
8699d89694 Update language-inference-engine.js 2025-01-29 17:22:55 +09:00
fb947cc777 Update LIE(Language Inference Engine) integraton of the app.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-01-28 09:53:55 +09:00
fe5542a521 Update language-inference-engine.js 2025-01-28 09:46:45 +09:00
47bb893c49 Update language-inference-engine.js 2025-01-28 09:38:23 +09:00
0485412b52 Update apikey.json
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-01-28 00:19:06 +09:00
ab2f3df4ea Update language-inference-engine.js 2025-01-28 00:02:22 +09:00
df92b4c58e Create language-inference-engine.js 2025-01-27 23:48:34 +09:00
88e6bd27b2 Change the script URLs
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-01-22 14:28:02 +09:00
b640786f62 Create hanoi.ai.js 2025-01-22 13:55:45 +09:00
1c3a367b18
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-01-20 12:05:41 +09:00
8a2a4c4760 Update chatgpt.js 2025-01-20 10:18:10 +09:00
e585b3e2d4 Update app.js 2025-01-20 10:11:04 +09:00
94601cbf4f Update app.js 2025-01-20 10:06:21 +09:00
905b56beb2 Allow load script from ChatGPT (LLM based AI) service 2025-01-20 10:04:49 +09:00
1337320803
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-01-17 16:17:45 +09:00
1e3389acf4
Update README.md 2025-01-17 14:13:44 +09:00
74005364e2 Add Grok (x.ai) interface 2025-01-17 14:04:35 +09:00
1cea720a70
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-01-15 17:57:15 +09:00
eeb0d0bc19
Update README.md 2025-01-15 17:56:47 +09:00
9d47a18325
Update testloader.js 2025-01-15 16:18:06 +09:00
81f196eed2
Update test-misc.json 2025-01-15 16:09:37 +09:00
8adaf4bdb9
Update test-misc.json 2025-01-15 16:09:26 +09:00
daf7db76b6
Update ovftool.js 2025-01-15 15:38:25 +09:00
38b03fe026 Update shell.js, ovftool.js 2025-01-15 15:18:36 +09:00
e2582447cc Update shell.js 2025-01-15 14:56:14 +09:00
6babec9d6b Update shell.js 2025-01-15 14:56:01 +09:00
a5dce5b55d Update shell.js 2025-01-15 14:42:58 +09:00
babfbe4e38 Update .gitignore 2025-01-15 14:00:57 +09:00
c9f03a5e23 Update shell.js, ovftool.js 2025-01-15 13:58:54 +09:00
f9f35da4d4 Create ovftool.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-01-13 15:13:25 +09:00
dd3ebc16df Update the credential management 2025-01-13 14:46:48 +09:00
3120a5ea93
Update README.md 2025-01-13 10:59:45 +09:00
8571ec4d00 Update ip-reputation.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2025-01-10 13:29:05 +09:00
1c6d306760 Create lib/ip-reputation.js 2025-01-10 13:28:46 +09:00
9262d83fd5
Update SECURITY.MD 2025-01-09 16:59:31 +09:00
b682f8fc34
Update bootstrap.bat 2025-01-09 16:03:00 +09:00
e1720c5bcf
Update bootstrap.bat 2025-01-09 14:05:48 +09:00
a78581ee69
Update bootstrap.bat 2025-01-09 14:03:13 +09:00
4eb2d4ae06
Update bootstrap.bat 2025-01-09 13:58:48 +09:00
fdd5c74df5
Update README.md 2025-01-09 11:33:35 +09:00
1857712df4
Update README.md 2025-01-09 11:02:08 +09:00
c5ebf36274
Update README.md 2025-01-09 11:01:43 +09:00
8c2d403502
Update README.md 2025-01-08 17:42:29 +09:00
ec92b9605f
Update README.md 2025-01-06 15:06:19 +09:00
c0e8f92e84
Update README.md 2025-01-01 21:19:01 +09:00
fe4d0d562e Add the server-side script files 2025-01-01 21:12:42 +09:00
58e9bdc4ab Add DEFAULT_JSONRPC2_URL variable to lib/jsonrpc2.js 2025-01-01 19:51:11 +09:00
638b172e77 Fix a proxy services and HTTP request issues
1. Separated the data listing available HTTP proxy services into a separate file. (data/available_proxies.json)
2. Excluded the architecture of the user's PC (e.g., 32-bit, 64-bit) from the User-Agent in HTTP requests.
2025-01-01 19:18:40 +09:00
79295de4ce
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-12-30 13:23:16 +09:00
37aa3ea406
Update README.md 2024-12-30 13:22:08 +09:00
1c9e77f890 Create fix_wsh_js_engine_not_found.reg
Fix: Input Error: There is no script engine for file extension ".js".
해결: 입력 오류: 파일 확장자 ".js"에 해당하는 스크립트 엔진이 없습니다.
2024-12-30 13:17:54 +09:00
da153a7900
Update README.md 2024-12-29 06:27:26 +09:00
7903a38f61
Update aviation.js 2024-12-27 15:04:08 +09:00
a99f1c396f
Update testloader.js 2024-12-27 14:55:46 +09:00
5a5526df63
Update anthropic.js 2024-12-27 14:53:17 +09:00
46c5a91032
Update chatgpt.js 2024-12-27 14:52:17 +09:00
e9ba3cff96
Update apikey.json 2024-12-27 14:49:25 +09:00
b4ace286e3
Create apikey.js 2024-12-27 14:49:01 +09:00
7aeb8edfc2
Update apikey.json 2024-12-27 14:34:57 +09:00
31792ebecd
Update apikey.json 2024-12-27 14:33:41 +09:00
7dcd82e7b9
Create apikey.json 2024-12-27 14:33:21 +09:00
fc4d74b7ac
Update std.js 2024-12-27 14:11:15 +09:00
98ff88ffff
Update browser.js 2024-12-27 14:08:56 +09:00
a3fa1a558e Update task-scheduler.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-12-22 03:27:35 +09:00
bf6fa1c044 Create task-scheduler.js 2024-12-22 03:26:41 +09:00
8a185cb048 Add a fast-track consultation channels
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-12-20 17:57:44 +09:00
4d6239b606
Merge pull request #168 from chasca8/master
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Update test-oss-korea-2023.json
2024-12-20 15:39:46 +09:00
78445aa4dc
Merge branch 'master' into master 2024-12-20 15:36:56 +09:00
4a9f5a7fd8
Update data/test-oss-korea-2023.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-20 15:20:37 +09:00
e1d2d3e9ff
Update data/test-oss-korea-2023.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-20 15:20:04 +09:00
7ee1e2b745
Update data/test-oss-korea-2023.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-20 15:19:39 +09:00
Scarlet
442d081f9d
Update test-oss-korea-2023.json 2024-12-18 21:26:03 +09:00
Scarlet
36da5ec3a1
Update virustotal.js 2024-12-18 19:07:17 +09:00
Scarlet
f49ba40cb9
Update test-oss-korea-2023.json 2024-12-18 18:20:48 +09:00
a886363603
Merge pull request #166 from gnh1201/revert-165-master
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Revert "Update test-oss-korea-2023.json"
2024-12-18 14:02:57 +09:00
dee6ed1025
Revert "Update test-oss-korea-2023.json" 2024-12-18 14:02:40 +09:00
d8d67ac4c0
Merge pull request #165 from chasca8/master
Update test-oss-korea-2023.json
2024-12-18 13:58:05 +09:00
Scarlet
b400c8d64d
Update test-oss-korea-2023.json 2024-12-17 20:53:53 +09:00
Scarlet
98e2c6c837
Update test-oss-korea-2023.json 2024-12-17 12:03:26 +09:00
a947432134 Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-12-12 15:30:22 +09:00
1d0f4172fb Update README.md 2024-12-12 15:28:32 +09:00
06972c2bd1 Update README.md 2024-12-12 15:27:45 +09:00
eccd60c340 Update README.md 2024-12-12 15:26:37 +09:00
c1f9249252 Update aviation.js 2024-12-12 14:36:16 +09:00
c14f4358f3 Add aviation.js, Updatre http.js 2024-12-12 14:22:00 +09:00
2dae3a3abb Update http.js 2024-12-12 13:43:41 +09:00
7d6046624c Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-12-11 14:27:28 +09:00
de4016100a Update AnsiX923Padding.cs, PKCS5Padding.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-12-10 18:31:31 +09:00
3ed38eec6a Add error handling flags for AnsiX923Padding, and PKCS5Padding 2024-12-10 17:50:10 +09:00
7ef4437447 Add LEA cryptography algorithm 2024-12-10 16:48:48 +09:00
9c662177ec Update ARIA.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-12-09 17:18:54 +09:00
d6540f1351 Change MD5 to SHA256 in the CreateKey method 2024-12-09 17:17:39 +09:00
1b31859786 Update ARIA.cs 2024-12-09 17:13:58 +09:00
ca857d70eb Update ARIA.cs 2024-12-09 16:55:03 +09:00
eaa52e40a6 Add ARIA cryptography algorithm 2024-12-09 16:50:43 +09:00
5ba8744f6c Update SEED.cs
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-12-06 01:36:31 +09:00
92b3907a8e Clean HIGHT.cs 2024-12-06 00:51:07 +09:00
a95e7e3e0d Update SEED.cs 2024-12-06 00:30:31 +09:00
7a8ef89f09 Update SEED.cs 2024-12-05 18:52:33 +09:00
3b022d68a4 Update SEED.cs 2024-12-05 18:21:21 +09:00
eaa33e3b7b Update SEED.cs 2024-12-05 18:14:24 +09:00
ea78f08710 Update SEED.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-12-05 17:56:11 +09:00
6fa089a854 Update SEED.cs 2024-12-05 17:45:16 +09:00
ba73fddba5 Update SEED.cs 2024-12-05 17:31:21 +09:00
ff0ab03630 Add the SEED cryptography algorithm (Experimental) 2024-12-05 17:24:06 +09:00
7ba17435ac
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-12-04 10:25:20 +09:00
5852e987c6
Update README.md 2024-12-03 19:32:32 +09:00
9b4273e370 Update SECURITY.MD 2024-12-02 19:34:19 +09:00
4e6b9ea086 Update SECURITY.MD 2024-12-02 19:33:10 +09:00
caa56cedb8 Update archive.js 2024-11-29 16:54:53 +09:00
701be4c351 Create archive.js 2024-11-29 16:53:31 +09:00
2ba05aa633 Update lib/punycode.js, lib/totp.js 2024-11-28 21:11:17 +09:00
f00e6eed1e
Update totp.js 2024-11-28 14:13:14 +09:00
81592beb64
Update totp.js 2024-11-28 14:10:28 +09:00
ebdc212afb
Update std.js 2024-11-27 19:26:25 +09:00
b880e7a13d
Update std.js 2024-11-27 19:25:01 +09:00
ce10ac7f7b Update std.js 2024-11-27 16:47:59 +09:00
9012a161c3 Update std.js, README.md, SECURITY.md 2024-11-27 16:45:53 +09:00
9038829f24 Remove the Public API URL
The Public API was proposed for the next version (0.2.7.54), but due to the increased security risks of providing an unauthenticated Public API, the Public API URL is being discontinued.

This service will be available in the future through marketplaces offered by cloud platforms. Additionally, as the server-side script is open-source, you can set it up yourself.

https://github.com/gnh1201/caterpillar
2024-11-27 15:36:35 +09:00
116bd84394
Update totp.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-11-26 02:46:06 +09:00
69d7d3c632
Update totp.js 2024-11-26 02:03:15 +09:00
400e904aa9 Update totp.js 2024-11-26 01:49:36 +09:00
27f4dc2084 Update totp.js 2024-11-26 01:42:39 +09:00
2ac75fd24e Add TOTP library 2024-11-26 01:41:21 +09:00
8ddff1cf94 Add the security notice to LLM integration libraries
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-11-25 20:55:47 +09:00
b1428867dc Update the Punycode Public API client 2024-11-25 16:15:14 +09:00
f2044bcfbf Ready use the JSON-RPC 2.0 based stateless proxy
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-11-24 03:15:37 +09:00
b5bc2bd851 Update jsonrpc2.js 2024-11-24 02:20:44 +09:00
b45a7cdd6c Ready use the JSON-RPC 2.0 based stateless proxy 2024-11-23 21:50:32 +09:00
ac31e5e884 Ready use the JSON-RPC 2.0 based stateless proxy 2024-11-23 21:44:03 +09:00
43b5781cbd Ready use the JSON-RPC 2.0 based stateless proxy 2024-11-23 21:26:04 +09:00
3fa72f86d6 Ready use the JSON-RPC 2.0 based stateless proxy 2024-11-23 21:10:06 +09:00
8942a98431 Update http.js 2024-11-23 19:06:43 +09:00
8bb0f68049 Update the search engines 2024-11-23 18:58:29 +09:00
d3743e206c
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-11-20 19:30:27 +09:00
4fe98d32a1
Update README.md 2024-11-20 18:47:20 +09:00
1fc0597f93
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-11-20 01:17:48 +09:00
0f57fba805 Update std.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-11-19 17:01:56 +09:00
2f74ceb013
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-11-19 15:31:35 +09:00
009b171946
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-11-18 20:03:16 +09:00
895bfe1ac8
Update README.md 2024-11-18 19:59:04 +09:00
3033382f64
Update README.md 2024-11-18 16:43:10 +09:00
fd21f2faae
Update README.md 2024-11-18 16:40:58 +09:00
5e1f41b48a Update app.js 2024-11-15 05:27:22 +09:00
b98901c75a Update app.js 2024-11-15 05:24:49 +09:00
9b50e5b078 Rename some files 2024-11-15 04:05:06 +09:00
d9ac6d01d0 Update README.md 2024-11-15 03:51:50 +09:00
57fbb16bd8 Add Advanced Mathematics Test 2024-11-15 03:48:19 +09:00
13a8c94bcf Add library numbers 2024-11-15 02:40:58 +09:00
0d6e2076d6
Rename FUNDING.yml to .github/FUNDING.yml 2024-11-13 16:23:47 +09:00
f6b04faea6
Update README.md 2024-11-13 16:06:55 +09:00
eedac13818
Update README.md 2024-11-13 16:03:38 +09:00
d45c21cf24
Delete lib/archive.js 2024-11-13 13:48:16 +09:00
54a1515bcb
Update README.md 2024-11-11 06:12:38 +09:00
4477ef84bf
Update archive.js 2024-11-08 00:07:06 +09:00
4370f40886
Create archive.js 2024-11-08 00:06:33 +09:00
fe2466b49a Update package.json 2024-11-07 23:39:51 +09:00
a8b54493f7
Update app.js 2024-11-06 16:31:37 +09:00
2ee54f77ae
Update FUNDING.yml 2024-11-06 16:21:25 +09:00
187578861b
Update FUNDING.yml 2024-11-06 16:16:27 +09:00
a0420cd10f
Update FUNDING.yml 2024-11-06 16:12:53 +09:00
2f1a0f6e41 Add support the Groq LLM API 2024-11-06 04:17:56 +09:00
6d0a6c645f Add README.md to WelsonJS.Toolkit 2024-11-05 21:03:41 +09:00
55d34f833d Update .appveyor.yml 2024-11-05 20:45:21 +09:00
a0e9a83ddd Update .appveyor.yml 2024-11-05 20:36:30 +09:00
9a35227728 Update WelsonJS.Toolkit.nuspec 2024-11-05 20:35:09 +09:00
af69d66ea9 Update the nuspec file 2024-11-05 20:33:50 +09:00
2487e56847 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-11-05 20:01:50 +09:00
5b264b64fd Change the API name DecryptStringHIGHT to DecryptString and EncryptStringHIGHT to EncryptString 2024-11-05 20:01:34 +09:00
ce7a0034be
Update README.md 2024-11-05 14:29:17 +09:00
a8a13b539c Update ScreenMatch.cs 2024-11-04 03:55:11 +09:00
b2975e053c Update ScreenMatch.cs 2024-11-04 03:24:42 +09:00
41fcb8706f Update README.md 2024-11-04 02:22:15 +09:00
3fc6f19227 Update README.md 2024-11-04 02:18:21 +09:00
3e78e0b5d2 Fix bugs related to the settings and logger 2024-11-04 02:04:02 +09:00
020f99c5b2 Update MainForm.cs 2024-11-04 01:22:33 +09:00
3989eeba45 Add Anthropic API integration 2024-11-04 00:32:25 +09:00
412c72f624 Change the application name to lowercase when used in logging 2024-11-02 04:03:01 +09:00
30c0e20eae fix #154 (Migrate parent.Log() to Microsoft.Extensions.Logging)
Migrate parent.Log() to Microsoft.Extensions.Logging
2024-11-02 03:51:07 +09:00
53bc51a3af Update README.md 2024-10-24 23:20:45 +09:00
f95b769f11 Update README.md 2024-10-23 20:55:31 +09:00
5d8e195635 Update README.md 2024-10-23 20:48:11 +09:00
a60d0649c0 Move the images of README.md to ics.catswords.net 2024-10-23 20:45:40 +09:00
377d2bdd71 Update README.md 2024-10-23 18:15:34 +09:00
64fec9583d Remove unnecessary images 2024-10-23 18:08:19 +09:00
9b6637a697 Update README.md 2024-10-23 18:02:35 +09:00
af096d38b8 Update README.md 2024-10-23 18:01:11 +09:00
7eb960c711 Update README.md 2024-10-23 18:00:37 +09:00
a98c1cbc92 Update README.md 2024-10-23 17:58:47 +09:00
53970f97a1 Update README.md 2024-10-23 17:53:59 +09:00
9193df71b7 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-10-23 17:53:22 +09:00
d180a01312 add nuget profile, update README.md 2024-10-23 17:53:12 +09:00
7f13b67f70
Update README.md 2024-10-23 15:32:21 +09:00
c9360c6651
Update README.md 2024-10-23 15:31:53 +09:00
489e10b76e
Update README.md 2024-10-22 18:22:48 +09:00
28be18de01 Update ScreenMatch.cs 2024-10-21 04:49:48 +09:00
c03a8011c2 Update ScreenMatch.cs 2024-10-21 04:16:46 +09:00
06731f4d4b Update ServiceMain.cs 2024-10-21 02:16:11 +09:00
44de5bfd1a
Update testloader.js 2024-10-20 00:07:53 +09:00
a00d43a59e
Update ScreenMatch.cs 2024-10-19 23:28:16 +09:00
9783e55069
Update extramath.js 2024-10-19 23:17:34 +09:00
3b101e177e
Update README.md 2024-10-19 21:04:34 +09:00
08b10b4e4a
Update http.js 2024-10-19 20:49:16 +09:00
65d5ee120b
Update README.md 2024-10-18 22:24:55 +09:00
2fc9b11aa6
Update README.md 2024-10-18 21:41:51 +09:00
feb85625c5 Update ScreenMatch.cs
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-10-15 05:22:07 +09:00
e1d4df74b9 Update defaultService.example.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-10-15 03:00:06 +09:00
6eaeab5c24 Update the dotnet dependencies 2024-10-15 02:26:35 +09:00
b93c6cd48b fix .env support
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-10-14 04:52:22 +09:00
94afeb406a Add some code to add the .env support
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-10-14 04:38:18 +09:00
9e623b645f
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-10-12 09:41:44 +09:00
4f92b782e9
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-10-08 16:25:59 +09:00
16427b347f
Update README.md 2024-10-08 15:49:22 +09:00
ea6add25ca
Update http.js 2024-10-08 15:24:24 +09:00
89e3704f33 Apply the color level based quantization 2024-10-08 14:59:04 +09:00
736356fe71 Check if the position of a specific template image has changed using previously extracted sample images.
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-10-07 03:39:28 +09:00
89dc45ac7c
Update SECURITY.MD
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-10-07 00:01:38 +09:00
c3d4250094
Update README.md 2024-10-06 22:04:22 +09:00
5357ec167a Update the Thanks to links
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-10-05 19:18:16 +09:00
7824de743f Update screenshot6.png
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-10-04 20:19:34 +09:00
adce996aae Update MainForm.cs 2024-10-04 17:01:02 +09:00
2e334ec12e
Merge pull request #150 from gnh1201/envform
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Add the user variables editor and update related files
2024-10-04 15:11:17 +09:00
641c2070a4 Update MainForm.cs, HeartbeatClient.cs 2024-10-04 15:09:05 +09:00
86916d2ed9 Add --user-variables-file parameter when starting a service 2024-10-03 22:56:04 +09:00
c157116680 Use the user variables in the screen matching feature 2024-10-03 22:27:26 +09:00
1a8c93627a Update EnvForm.cs 2024-10-03 21:23:51 +09:00
ee5f503e42 Add import and export feature 2024-10-03 20:58:42 +09:00
c4c7d5480b Update EnvForm.cs 2024-10-03 20:27:41 +09:00
06cb5095b2 Update the env form 2024-10-03 19:48:05 +09:00
f9ddd3b95e Add the env form 2024-10-03 18:09:14 +09:00
740f392c95
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-10-03 14:40:04 +09:00
be336e6e06 Update the favicon on the launcher app 2024-10-03 14:24:59 +09:00
2318092542 Update README.md 2024-10-03 13:57:09 +09:00
3964f081de Update README.md 2024-10-03 13:56:41 +09:00
ec451f633b Update favicon.ico and related files
New favicon designed by @druidesse
2024-10-03 13:55:26 +09:00
5a7165d142
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-10-02 14:36:47 +09:00
94183f1e60
Update http.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-09-28 16:44:43 +09:00
8300e1dba4
Update http.js 2024-09-28 16:44:27 +09:00
d413cb49b4
Update http.js 2024-09-28 16:36:38 +09:00
7babc6bad7
Update http.js 2024-09-28 16:26:47 +09:00
7e3a6bdf45
Update http.js 2024-09-28 16:24:24 +09:00
bd51f1d8e1
Update http.js 2024-09-28 16:23:39 +09:00
fac76f9328 Update README.md 2024-09-27 21:23:48 +09:00
8285eee3c1 Update testloader.js 2024-09-27 21:00:53 +09:00
a36dd8e257 Update lib/http.js, testloader.js 2024-09-27 20:53:29 +09:00
1e7061efae Update README.md 2024-09-27 16:34:13 +09:00
072110f282 Update README.md 2024-09-27 16:32:13 +09:00
3ecd35c4a6 Update README.md 2024-09-27 16:19:33 +09:00
b71366bac7 Add SearchAPI.io to README.MD 2024-09-27 16:17:15 +09:00
c6f614b106 Update testloader.js 2024-09-27 15:55:31 +09:00
a60e7e5d9e fix #145
* Fix #145
* Change the methods and variables `CharsetDetector` to `DetectCharset`
* Add searchapi.io SERP support
2024-09-27 15:53:19 +09:00
ad6cb7e430 Update README.md 2024-09-27 10:46:39 +09:00
e95275fa35 Update README.md 2024-09-27 10:44:26 +09:00
099e95bfd3 Update README.md 2024-09-27 10:22:09 +09:00
3c57828f3a Update README.md 2024-09-27 10:18:32 +09:00
6a4a94f486 Update README.md 2024-09-27 10:06:35 +09:00
27a0a0f5d7 Update README.md 2024-09-27 10:03:38 +09:00
dac6e7c5b1 Update README.md 2024-09-26 20:56:34 +09:00
80450467fc Update README.md 2024-09-26 20:47:00 +09:00
ff3cbd88dd Fix the Tab UI bug, and fix stdout/stderr clear issue 2024-09-26 19:35:43 +09:00
c411f596f9 Update webloader.js and the screenshot 2024-09-26 18:45:23 +09:00
a0933153ba Change the screenshot and the example log message 2024-09-26 18:35:25 +09:00
f03c0ef913 Change the screenshot and add ui components example page 2024-09-26 18:32:38 +09:00
f3a79a3523 Update README.md 2024-09-26 15:49:14 +09:00
f18cf9b859 Add support Tab UI with golden layout 2024-09-26 15:46:07 +09:00
bf66ef6354 Update README.md 2024-09-26 02:00:48 +09:00
330323f0c2 Update testloader.js 2024-09-26 01:26:06 +09:00
b82f00748a
Update README.md 2024-09-25 23:09:31 +09:00
0f7e74a5e2 Update README.md 2024-09-25 22:36:31 +09:00
4db50b12ca Add the partnerships section to README.md 2024-09-25 22:34:25 +09:00
abe59228be fix and test ok #143 2024-09-25 18:21:55 +09:00
3842d1bea8 Update http.js 2024-09-25 16:12:19 +09:00
4f1154f412 Add support ARM architecture (lib/http.js) 2024-09-25 16:11:41 +09:00
ce440ae7f7 Update websocket.js 2024-09-25 16:00:41 +09:00
124ea0ae30 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-09-25 15:53:11 +09:00
4327651e1d Update http.js 2024-09-25 15:52:47 +09:00
f1e45f01bb Change the default binary path (lib/http,js, lib/websocket.js) 2024-09-25 15:52:08 +09:00
5e6e3e30ba
Update certchecker.js 2024-09-25 14:46:53 +09:00
266971f5d3 fix #144 2024-09-25 14:12:19 +09:00
ed3b631b30 Update testloader.js 2024-09-25 12:10:47 +09:00
7389131bdc Update README.md 2024-09-23 23:27:06 +09:00
f9302f50ee Update README.md 2024-09-23 23:19:35 +09:00
13bcbbbb15 Update README.md 2024-09-23 23:16:03 +09:00
27f4b24344 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-09-23 22:53:40 +09:00
9a7cc6de38 Add the github octocat logo 2024-09-23 22:40:48 +09:00
15e31d60e6
Update README.md 2024-09-23 22:35:46 +09:00
528a9c93a4 Update README.md 2024-09-23 22:34:21 +09:00
7823a0a9b5 Add signpath logo 2024-09-23 22:32:57 +09:00
193fcb16c2
Update README.md 2024-09-23 22:29:45 +09:00
646c4babaa Update .appveyor.yml 2024-09-23 22:21:15 +09:00
f2e62d6602
Update README.md 2024-09-23 02:27:03 +09:00
8d5f88a488 Update MainForm.cs 2024-09-23 02:06:49 +09:00
c7af90896b Update http.js 2024-09-23 01:47:46 +09:00
b3bb9ba28c
Update http.js 2024-09-22 20:59:51 +09:00
54e7bb77f6
Update http.js 2024-09-22 00:15:01 +09:00
78a65f906e
Update http.js 2024-09-22 00:10:04 +09:00
9f8e930a45
Update http.js 2024-09-21 14:22:57 +09:00
5f91e9be12
Update http.js 2024-09-21 14:18:42 +09:00
e575f41a19
Update http.js 2024-09-21 14:14:43 +09:00
13cb1da59d
Update http.js 2024-09-21 14:12:39 +09:00
05874f90e5
Update http.js 2024-09-21 14:08:29 +09:00
25876bd81f Merge branch 'master' of https://github.com/gnh1201/welsonjs
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-09-20 23:41:33 +09:00
96c57b0daa Add keep_headers parameter #143 2024-09-20 23:41:04 +09:00
af395bf4ac
Update README.md #143 2024-09-20 23:27:27 +09:00
611c70a1ff
Update README.md 2024-09-20 23:26:30 +09:00
9730b639b9 Update the proxy API services #143 2024-09-20 23:21:37 +09:00
de6b70a5b1 Add the proxy API services #143 2024-09-20 23:10:30 +09:00
e7f65d50b0 Update ScreenMatch.cs and related files
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-09-20 16:53:50 +09:00
855cf6adef Update defaultService.example.js, .gitignore 2024-09-20 11:50:29 +09:00
5e82c58873 Update defaultService.example.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-20 10:56:28 +09:00
4b63596c3a Update ServiceMain.cs 2024-09-20 10:50:11 +09:00
8734f3f24a Update ScreenMatch.cs, ServiceMain.cs 2024-09-20 10:32:43 +09:00
c0e42480e0 Update ScreenMatch.cs 2024-09-20 09:36:44 +09:00
0742f17f2a Add the Bitmap Comparison with CRC32 hashing
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-19 03:29:43 +09:00
12ce97c385 Update ScreenMatch.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-18 15:51:24 +09:00
c36d7fb71f Update ScreenMatch.cs 2024-09-18 15:01:05 +09:00
27e9a328d4 Save file in the droptop coffee 2024-09-18 14:33:15 +09:00
83efe8a156 Create fsm.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-18 03:32:10 +09:00
ec278ade7b Update .gitignore
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-17 23:44:30 +09:00
e38e3fb088 Rename defaultService.js to defaultService.example.js 2024-09-17 23:42:04 +09:00
9cdd9e85ed fix (Happy Chuseok) 2024-09-17 22:22:46 +09:00
775ffb924d
Update SECURITY.MD
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-09-15 23:30:40 +09:00
efd35cd273
Update README.md 2024-09-15 23:29:51 +09:00
4144679db7 Add the event listener onAvScanResult
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-15 02:54:18 +09:00
f7b1461cc5 Add to ClamAV integration to the File Event Monitor
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-14 22:33:58 +09:00
93ea20cf25 Update settings.example.ini 2024-09-14 20:18:10 +09:00
13d7b821be
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-09-10 14:42:11 +09:00
8db76f49ae Update FileEventMonitor.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-09 17:13:07 +09:00
bc74515095 Update FileEventMonitor.cs 2024-09-09 17:10:31 +09:00
672a3637de Add event type: registry modification 2024-09-09 17:09:31 +09:00
91b73186d3 Fix the FileEventMonitor.cs 2024-09-09 16:47:51 +09:00
a18229afea Revert "Update app.js, defaultService.js"
This reverts commit c24166b36d.
2024-09-09 16:42:48 +09:00
c24166b36d Update app.js, defaultService.js 2024-09-09 15:28:33 +09:00
40edee2b83 Remove libyara.NET and a little fixes for sysmon events 2024-09-09 15:26:16 +09:00
671007bb79 Update FileEventMonitor.cs and related files
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-09 12:05:39 +09:00
bdee21a66f Update ScreenMatch.cs
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-09-06 17:04:15 +09:00
6f3153a816 Update ScreenMatch.cs, settings.example.ini 2024-09-06 17:03:11 +09:00
a69603a10c Add options to the screen time 2024-09-06 16:42:15 +09:00
28435522de Update ScreenMatch.cs 2024-09-06 16:10:58 +09:00
da08bb7bb9
Merge pull request #139 from soumt-r/grpc_fix
heartbeat grpc service
2024-09-06 15:35:14 +09:00
Soumt
126169e37c fix: fixed heartbeat grpc service 2024-09-06 00:54:00 +09:00
0eb897b07f
Update chrome.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-09-04 20:17:55 +09:00
38288153ed Apply Math.Sqrt(templateWidth * templateHeight) < 10.0
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-04 17:26:31 +09:00
9227518d1e Update ScreenMatch.cs 2024-09-04 16:20:48 +09:00
bab0a3bba2 Fix STAThreadAttribute issue 2024-09-04 16:18:05 +09:00
85ba0c14be Add the sample_clipboard option to the screen time 2024-09-04 14:12:28 +09:00
ca7b7ad3d5 Update ScreenMatch.cs 2024-09-04 13:26:20 +09:00
87d785df45
Update chrome.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-04 00:41:01 +09:00
34115728fe
Update chrome.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-02 21:41:35 +09:00
7ed1cab718
Update chrome.js 2024-09-02 21:14:05 +09:00
ecf12aa83f
Update chrome.js 2024-09-02 21:13:22 +09:00
ffbb560598
Update chrome.js 2024-09-02 20:51:42 +09:00
eb389d34c7
Update chrome.js 2024-09-02 20:51:28 +09:00
c6d55cd1fa Update settings.example.ini
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-09-02 16:03:26 +09:00
db557015fd Update ScreenMatch.cs 2024-09-02 16:01:30 +09:00
2f4b95313f Update ScreenMatch.cs 2024-09-02 15:30:20 +09:00
e70c152494 Add heartbeat.proto 2024-09-02 15:18:15 +09:00
9d7f14cddb Add submodule tessdata 2024-09-02 15:15:38 +09:00
dcdaaa11c2 Add tessdata to the assets 2024-09-02 14:58:05 +09:00
3a1d2ab1ba Update ScreenMatch.cs 2024-09-02 14:37:45 +09:00
ba654438ab Add option ocr128 to the screen time feature 2024-09-02 14:17:06 +09:00
4401ba6847 Remove orphan files 2024-09-02 12:48:07 +09:00
0777faaa5b
Update README.md 2024-09-02 12:39:36 +09:00
577b3f018a
Merge pull request #136 from gnh1201/dependabot/nuget/WelsonJS.Toolkit/WelsonJS.Service/RestSharp-112.0.0
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Bump RestSharp from 111.4.1 to 112.0.0 in /WelsonJS.Toolkit/WelsonJS.Service
2024-08-30 10:25:10 +09:00
dependabot[bot]
9b5fb5499c
Bump RestSharp in /WelsonJS.Toolkit/WelsonJS.Service
Bumps [RestSharp](https://github.com/restsharp/RestSharp) from 111.4.1 to 112.0.0.
- [Release notes](https://github.com/restsharp/RestSharp/releases)
- [Commits](https://github.com/restsharp/RestSharp/compare/111.4.1...112.0.0)

---
updated-dependencies:
- dependency-name: RestSharp
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-29 19:39:58 +00:00
6ab285bc89 Update testloader.js 2024-08-29 19:59:30 +09:00
af30097c6e Add pegjs test 2024-08-29 19:57:53 +09:00
a0e1e34974 Update README.md 2024-08-29 19:13:52 +09:00
09a472b956 Update README.md 2024-08-29 19:13:12 +09:00
1fec9c1f2a Update README.md 2024-08-29 19:12:26 +09:00
1c4b94faaf Add a parser generator (PEG.js) #135 2024-08-29 19:06:19 +09:00
3602cb4a00 refactor #132 2024-08-29 15:34:54 +09:00
e6fd3a800e Update ServiceMain.cs
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-08-29 11:40:23 +09:00
a8ad7746ee Sometimes we have to destroy everything to solve a problem. #132 2024-08-29 11:17:38 +09:00
4aace2a3ae Update settings.example.ini
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-08-27 01:48:32 +09:00
222fe3c1a0 Read the initial configurations from settings.ini 2024-08-27 01:47:55 +09:00
659fb12db1 Fix typos on FileEventMonitor.cs 2024-08-27 01:24:11 +09:00
8593240692 Use HTTP/1.1 on the gRPC client 2024-08-27 01:16:53 +09:00
34e97347f2 Remove non-free, non-microsoft, and no-updates in uriloader.js 2024-08-27 01:03:24 +09:00
7c0adf8f00 Update ScreenMatch.cs 2024-08-26 21:53:13 +09:00
7b7a25f5e9 Update ServiceMain.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-26 18:29:13 +09:00
4e6b63df50 Update ScreenMatch.cs, ServiceMain.cs 2024-08-26 17:53:21 +09:00
0df9166a13 Update the screen time feature 2024-08-26 15:24:38 +09:00
2db49f85f0 Add method ConvertToBinary to the screen time feature
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-26 01:23:02 +09:00
4947151d00 Update FileEventMonitor.cs 2024-08-25 23:22:52 +09:00
44d7d431e3 Revert "Update app.js, defaultService.js"
This reverts commit c208e6dc6c.
2024-08-25 23:21:58 +09:00
72f70d990d Update FileEventMonitor.cs 2024-08-25 23:16:21 +09:00
1f2f940374 Update .gitignore 2024-08-25 23:10:43 +09:00
c208e6dc6c Update app.js, defaultService.js 2024-08-25 23:08:46 +09:00
0eceab3d9b Add option of the interactive service application 2024-08-25 23:04:34 +09:00
f4703ef7a0 Delete 2024-07-29 19 56 13.png 2024-08-25 22:49:26 +09:00
50d1c93f94 Update settings.example.ini 2024-08-25 22:45:25 +09:00
ecfbf7032b Update .gitignore 2024-08-25 22:44:24 +09:00
d9bdd5c578 Update ScreenMatch.cs 2024-08-25 22:43:34 +09:00
277eb08cba Update ScreenMatch.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-25 18:07:31 +09:00
18e81f71ba Use backward search in the screen time 2024-08-25 17:57:22 +09:00
82ac8e5d02 Fix the argument passing convention 2024-08-25 15:28:03 +09:00
e4a8357715 Fix parameter types to pass arguments to scripting engine
Since `ArrayList` is highly compatible with COM, you can use it to pass an array to `ScriptControl`.
2024-08-25 12:56:01 +09:00
3a890168df Update ServiceMain.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-24 22:27:26 +09:00
02681a135e Update the screen time feature 2024-08-24 22:24:26 +09:00
b345d655f1 Change the class names 2024-08-24 21:32:44 +09:00
7f6e21c96e
Update ScreenMatching.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-24 16:18:24 +09:00
32975494f3
Update ScreenMatching.cs 2024-08-24 16:16:07 +09:00
ad06da549f
Update ScreenMatching.cs 2024-08-24 16:13:06 +09:00
ba9088f43f
Update ScreenMatching.cs 2024-08-24 15:57:42 +09:00
016239b014
Update ScreenMatching.cs 2024-08-24 15:40:15 +09:00
66d4926bba Update the screen time feature 2024-08-24 14:57:01 +09:00
7b62e47fd2 Update settings.example.ini 2024-08-24 14:14:01 +09:00
96b91b2298 Update the screen time feature 2024-08-24 13:44:48 +09:00
61ee6aeae0 Add thanks to Hacker News
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-08-23 13:11:32 +09:00
bbefd3331a Update .appveyor.yml 2024-08-23 12:21:37 +09:00
01477b97c5 Update .appveyor.yml 2024-08-23 12:17:35 +09:00
1751f81cce Update .appveyor.yml 2024-08-23 12:06:37 +09:00
cab0211e09 Update .appveyor.yml 2024-08-23 12:00:39 +09:00
2d5b79ceb1 Update .appveyor.yml 2024-08-23 12:00:31 +09:00
6b915a5b4c Update .appveyor.yml 2024-08-23 11:54:35 +09:00
1f0cb81105 Update .appveyor.yml 2024-08-23 11:48:13 +09:00
dbb008772e Update .appveyor.yml 2024-08-23 11:46:03 +09:00
0fa8286d08 Update .appveyor.yml 2024-08-23 11:44:37 +09:00
5146957ea1 Update .appveyor.yml 2024-08-23 11:42:46 +09:00
b183e1925d Update .appveyor.yml 2024-08-23 11:33:17 +09:00
158809732c Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-23 08:56:01 +09:00
7633675b33 Update README.md 2024-08-23 08:54:01 +09:00
f8e6340fda Update README.md 2024-08-23 08:46:33 +09:00
4a02689c71 Update README.md 2024-08-23 08:44:42 +09:00
7899efcb9e Update README.md 2024-08-23 08:29:40 +09:00
2c67b77156 Update README.md 2024-08-23 08:28:12 +09:00
dc7b5a9fb2 Update MessageReceiver.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-22 17:00:53 +09:00
97a930ccb3 Update MessageReceiver.cs 2024-08-22 16:59:58 +09:00
6ec6c07ad7 Update MessageReceiver.cs 2024-08-22 16:59:47 +09:00
3c90c76796 Update .appveyor.yml 2024-08-22 11:14:12 +09:00
0b0ca9912d Update .appveyor.yml 2024-08-22 10:39:01 +09:00
fabcdf185a Update .appveyor.yml 2024-08-22 10:34:14 +09:00
ad6eeb46d5 Update .appveyor.yml 2024-08-22 10:32:15 +09:00
6d43cb47a7 Update .appveyor.yml 2024-08-22 10:30:53 +09:00
ca9f0ba456 Update .appveyor.yml 2024-08-22 10:26:11 +09:00
bc0d6646e4 Update MainForm.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-22 09:54:58 +09:00
8c59024b96 Update README.md 2024-08-22 04:16:36 +09:00
ecdc0767b8 Remove DeviceId package (not working) 2024-08-22 04:12:31 +09:00
f61dc98fa6 Update WelsonJS.Toolkit.sln 2024-08-22 04:11:06 +09:00
c985f1fa0a Update WelsonJS.Launcher build configurations 2024-08-22 04:08:37 +09:00
ce88ae603b Update WelsonJS.Launcher 2024-08-22 04:02:31 +09:00
1e82f18bc9 Update MainForm.cs 2024-08-22 03:58:35 +09:00
d8558a4398 Add WelsonJS.Launcher component 2024-08-22 03:36:58 +09:00
7c77daabfa Update .gitignore
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-22 00:55:54 +09:00
81a31c7b1f
Update http.js 2024-08-21 23:38:48 +09:00
f3f2cc482c
Update SECURITY.MD
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-21 08:03:52 +09:00
e8bc5348a8
Update README.md 2024-08-21 08:01:31 +09:00
fe31fd2c97 Update MessageReceiver.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-20 19:37:10 +09:00
f6bbc31551 Update MessageReceiver.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-20 16:31:23 +09:00
8821eb0ae0 fix 2024-08-20 16:03:27 +09:00
c497c0fb26 Update MessageReceiver.cs 2024-08-20 13:44:47 +09:00
ed9e1a6d05 fix 2024-08-20 13:42:44 +09:00
1fa024546a Add flag disabledMessageReceiver 2024-08-20 10:36:59 +09:00
b3548bc35f Update .gitignore 2024-08-20 09:50:30 +09:00
5de04579b7 Update settings.example.ini 2024-08-20 09:49:58 +09:00
80b3e49cb8 Some update configurations 2024-08-20 09:49:03 +09:00
68d100458f Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-08-20 09:35:27 +09:00
3765d21648
Update SECURITY.MD 2024-08-20 09:34:48 +09:00
e7ed4794e2 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-08-20 09:25:56 +09:00
f181bf2696 Update MessageReceiver.cs, app.js #132 2024-08-20 09:25:50 +09:00
1704575cfb
Update SECURITY.MD 2024-08-20 09:11:19 +09:00
905c85a99c
Update SECURITY.MD 2024-08-20 09:06:57 +09:00
c8b3ac5d99 Related works for #132
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-19 17:04:50 +09:00
5d9fb71753 Replace GRPC proto file and delete the related file
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-19 00:35:23 +09:00
1863a76a4c Update build configurations
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-08-15 17:47:29 +09:00
8865723dd4 Update core-js version to 3.38.0
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-14 14:31:32 +09:00
eb05661e2b Update app.js 2024-08-14 14:25:55 +09:00
64e556f37a Update std.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-14 14:05:02 +09:00
a20ce41f73 Revert "Update std.js"
This reverts commit 9a583d0284.
2024-08-14 14:04:32 +09:00
9a583d0284 Update std.js 2024-08-14 14:04:17 +09:00
5ec537e142 Update std.js 2024-08-14 14:00:02 +09:00
243db3edaa Revert "Change variable naming convention, Remove dupilicate code (std.js)"
This reverts commit 3aa5a140d1.
2024-08-14 13:50:35 +09:00
3723f775bd Update .appveyor.yml
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-13 18:00:31 +09:00
83ecd79ec0 Update .appveyor.yml 2024-08-13 17:59:50 +09:00
9c77777577 Update .appveyor.yml 2024-08-13 17:59:18 +09:00
832bb12829 Revert "Add the package Costura.Fody"
This reverts commit d6012d88dd.
2024-08-13 17:39:26 +09:00
d6012d88dd Add the package Costura.Fody 2024-08-13 17:21:09 +09:00
d01d28fbf3
Update defaultService.js 2024-08-13 17:05:48 +09:00
f44f0b38b2 Update the files related to settings.ini
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-13 13:39:01 +09:00
d04e03200b some fixes 2024-08-13 11:21:48 +09:00
92bcb33171 Add settings.ini 2024-08-13 11:16:27 +09:00
41e542dc7a
Update FUNDING.yml
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-12 21:17:55 +09:00
c4740f7d61 Add ElasticsearchClient.cs, Update FileEventMonitor.cs 2024-08-12 21:15:03 +09:00
e8c69d1489 Update ScreenMatching.cs 2024-08-12 21:06:02 +09:00
5062d774b7 Some fixes 2024-08-12 21:05:17 +09:00
7de923f90c Remove the elasticsearch client library 2024-08-12 20:19:15 +09:00
7b03d9f020 Update .appveyor.yml 2024-08-12 17:16:16 +09:00
4ff438655d Update WelsonJS.Service.csproj 2024-08-12 17:10:34 +09:00
4ece37fdf4 Update FileEventMonitor 2024-08-12 17:08:32 +09:00
15bd7d40db Update ScreenMatching.cs, ServiceMain.cs 2024-08-12 16:53:31 +09:00
cf34039f5a Update FileEventMonitor.cs 2024-08-12 16:44:25 +09:00
f0a7316eef Some works #131 2024-08-12 16:42:37 +09:00
ee454527af Update FileEventMonitor.cs 2024-08-12 13:36:27 +09:00
5af61c3e76 Update ServiceMain.cs 2024-08-12 13:18:55 +09:00
e8ba073de2 Update FileEventMonitor.cs 2024-08-12 13:15:23 +09:00
0c03995f43 Update .appveyor.yml 2024-08-12 13:13:38 +09:00
5f0df92442 Update .appveyor.yml 2024-08-12 13:12:50 +09:00
1e16ff9483 Update pe.yar
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-12 13:07:16 +09:00
7c8fd0cd45 Update .appveyor.yml 2024-08-12 13:03:52 +09:00
bb2db7b64a Update .appveyor.yml 2024-08-12 13:02:11 +09:00
2631a8f577 some fixes 2024-08-12 13:00:04 +09:00
58d1829c9c Add Yara File Rule Matcher #131 2024-08-12 12:47:19 +09:00
1a4931e283
fix #122
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-08-08 11:07:52 +09:00
b2433e9057 Update .gitignore
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-07 16:31:19 +09:00
1b214a1604 Update bootstrap.bat 2024-08-07 11:58:00 +09:00
b8d2e362bf Update std.js 2024-08-07 11:55:50 +09:00
9f4f240493 Update std.js 2024-08-07 11:55:09 +09:00
3aa5a140d1 Change variable naming convention, Remove dupilicate code (std.js) 2024-08-07 11:52:34 +09:00
00868b708b
Update std.js 2024-08-06 22:03:24 +09:00
eead1f8775
Update std.js 2024-08-06 21:49:10 +09:00
cfadf1e369
Update std.js 2024-08-06 21:37:00 +09:00
fe31aa36bd
Update std.js 2024-08-06 21:34:50 +09:00
d6cf95b345
Update std.js 2024-08-06 21:34:01 +09:00
3ff02c442e
Update std.js 2024-08-06 21:30:31 +09:00
ca6f13196d
Update std.js 2024-08-06 21:15:59 +09:00
69888245bf
Update std.js 2024-08-06 21:00:02 +09:00
4a2fd7943a
Update std.js 2024-08-06 20:59:29 +09:00
3e86686613 Update .appveyor.yml 2024-08-06 20:27:40 +09:00
2bd104fc2f Update .appveyor.yml 2024-08-06 20:23:58 +09:00
334ec48d3e Update .appveyor.yml 2024-08-06 20:14:57 +09:00
ba5d038441 Update .appveyor.yml 2024-08-06 20:13:10 +09:00
93aababfc4 Update .appveyor.yml 2024-08-06 20:12:19 +09:00
daccf5e6de Create .appveyor.yml
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-06 20:08:17 +09:00
a6dbf1bb4b Update WelsonJS.Toolkit.csproj 2024-08-06 19:56:09 +09:00
34a9a843a4 JMT 2024-08-06 19:45:25 +09:00
8e88761547 Delete build_native_libraries.bat 2024-08-06 17:08:27 +09:00
1bb01be01d Remove the checked-in binaries #130 2024-08-06 17:05:51 +09:00
dbae10a4e5
Update har.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-08-03 21:56:26 +09:00
256ca14284
Update har.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-03 17:49:22 +09:00
ac2e1117a7
Update har.js 2024-08-03 17:10:34 +09:00
1b8fbf78bf
Update har.js 2024-08-03 16:49:30 +09:00
92e611f49a
Update har.js 2024-08-03 16:45:07 +09:00
5ff6680cee
Update har.js 2024-08-03 16:41:36 +09:00
aeef44d3d9
Update har.js 2024-08-03 15:53:30 +09:00
2e8c530ba9
Update har.js 2024-08-03 15:51:47 +09:00
c6cbe96e03
Update and rename hartool.js to har.js 2024-08-03 15:26:52 +09:00
45a1938aea
Create hartool.js 2024-08-03 15:25:41 +09:00
f55b70585a
Update SECURITY.MD 2024-08-03 14:07:30 +09:00
ff943d3fc2
Update SECURITY.MD
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-08-02 21:15:38 +09:00
a5672a16ff Update ScreenMatching.cs
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-08-02 16:53:33 +09:00
8df6270287 Update the screen time feature on WelsonJS.Service 2024-08-02 16:51:49 +09:00
70bce6eb72 Update .gitignore 2024-08-02 11:12:03 +09:00
75e386d2a7 Update .gitignore 2024-08-02 11:11:27 +09:00
05c06bffd2 Update WelsonJS.Service binaries 2024-08-02 11:09:32 +09:00
a7bc9fa21a Update ServiceMain.cs 2024-08-02 11:07:41 +09:00
8bd2382973 Update ServiceMain.cs 2024-08-02 11:07:04 +09:00
faf3d55d8d
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-07-31 18:17:09 +09:00
59d9d313f8
Update README.md 2024-07-31 18:14:57 +09:00
83e403cc54 Update setup.iss
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-31 16:19:08 +09:00
a80fd75ec3
Update SECURITY.MD 2024-07-31 09:44:30 +09:00
fc1694198b
Update SECURITY.MD 2024-07-31 09:41:12 +09:00
9ae992dc89 bug fix #126
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-31 00:43:42 +09:00
6297f9689d Add startInteractiveService.bat, uninstallService.bat 2024-07-30 18:17:26 +09:00
172a5109e9 Update setup.iss
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-30 15:46:11 +09:00
e881ec98ec Update README.md 2024-07-30 15:43:17 +09:00
6c9f905c2b Update README.md 2024-07-30 15:42:32 +09:00
0105ef9010 Update README.md 2024-07-30 15:41:05 +09:00
fe568f032e Add screenshot no.5 2024-07-30 15:40:17 +09:00
2766b2dcfc Update cover.png 2024-07-30 15:12:38 +09:00
2e37432990 Update README.md 2024-07-30 13:41:50 +09:00
38ad7ab669 Update README.md 2024-07-30 13:39:28 +09:00
27edbe4652 Update README.md 2024-07-30 13:30:10 +09:00
11abc2d1b3 Update README.md 2024-07-30 13:28:56 +09:00
119ad684ed Update README.md 2024-07-30 13:28:29 +09:00
accdf058c6 Update README.md 2024-07-30 13:22:05 +09:00
8d865b572d Change the cover image 2024-07-30 12:53:27 +09:00
3762dac556 Change the cover image 2024-07-30 12:53:06 +09:00
8f35bfb03b Update WelsonJS.Service
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-29 22:42:35 +09:00
3b09a47fb8 Update the Screen Matching feature 2024-07-29 22:28:07 +09:00
b687cf7727 Add Screen Matching feature 2024-07-29 21:43:14 +09:00
d5f55e0f28 Fix issue the cannot find the working directroy
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-29 16:06:04 +09:00
95a7588726 Revert "Some works for #124"
This reverts commit b5af648512.
2024-07-29 15:41:10 +09:00
f72db8bf2e Revert "Some works for #124"
This reverts commit f73b180329.
2024-07-29 15:41:05 +09:00
02d45ede0f Revert "Update defaultService.js"
This reverts commit ffd6cde177.
2024-07-29 15:40:11 +09:00
ffd6cde177 Update defaultService.js 2024-07-29 15:07:53 +09:00
f73b180329 Some works for #124 2024-07-29 15:04:22 +09:00
b5af648512 Some works for #124
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-29 01:35:46 +09:00
66879f229a Update installService.bat
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-07-27 21:38:38 +09:00
dad5c06a1b Add the service install script 2024-07-27 21:30:07 +09:00
0c5abb4658
Merge pull request #125 from gnh1201/dependabot/npm_and_yarn/requirejs-2.3.7
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Bump requirejs from 2.3.6 to 2.3.7
2024-07-26 17:29:31 +09:00
dependabot[bot]
0c09c5bd3b
Bump requirejs from 2.3.6 to 2.3.7
Bumps [requirejs](https://github.com/jrburke/r.js) from 2.3.6 to 2.3.7.
- [Commits](https://github.com/jrburke/r.js/compare/2.3.6...2.3.7)

---
updated-dependencies:
- dependency-name: requirejs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-26 08:25:56 +00:00
4a33238d7e Change the target framework version to 4.8, and renaming some functions 2024-07-26 17:24:56 +09:00
3b18896564 Fix incorrect version info of WelsonJS.Service
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-07-23 13:28:16 +09:00
84e094fc19 Update WelsonJS.Service binaries 2024-07-23 13:16:25 +09:00
639dfeeb68 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-07-23 13:13:38 +09:00
f60f99fc73 Update WelsonJS.Service and related files 2024-07-23 13:13:33 +09:00
95572825c3
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-23 12:41:57 +09:00
7ef118955d Update WelsonJS.Toolkit binaries 2024-07-23 05:29:46 +09:00
c3114ab3f9 Add Microsoft Teams links to WelsonJS.Toolkit 2024-07-23 05:24:39 +09:00
e25baeae9c Delete sfx_config.txt 2024-07-23 05:09:56 +09:00
4afc6deab8 Create sfx_config.txt
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-23 04:29:50 +09:00
d15f23a3c1 Update app.js and clean up files 2024-07-23 04:26:38 +09:00
aa4ca1b212 Update WelsonJS.Service binaries 2024-07-23 01:17:31 +09:00
d0fe3d6acb Update ServiceMain.Designer.cs 2024-07-23 01:14:59 +09:00
be16fbfd72 Add screenshot 4 2024-07-23 01:07:21 +09:00
8c247adede Update WelsonJS.Service binaries and example 2024-07-23 00:37:12 +09:00
def32aa559 Update ServiceMain.cs 2024-07-23 00:23:01 +09:00
1e9533a9a5 Update app.js 2024-07-23 00:22:01 +09:00
debc806516 Update ServiceMain.cs 2024-07-23 00:20:20 +09:00
91631c6c1d Update ServiceMain.cs 2024-07-22 21:02:07 +09:00
360d37cd36 Update ServiceMain.cs
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-22 20:36:34 +09:00
d758957d68 Update ServiceMain.cs 2024-07-22 20:21:54 +09:00
7456bf903e Update WelsonJS.Service component 2024-07-22 20:15:31 +09:00
239b039e2a Update WelsonJS.Service component 2024-07-22 18:47:08 +09:00
7c6c633362 Update app.js 2024-07-22 16:12:45 +09:00
575e0cf6fc Add WelsonJS.Service component 2024-07-22 16:04:40 +09:00
31fb594904
Update app.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-22 00:56:55 +09:00
a592cd08cf
Update app.js 2024-07-22 00:09:57 +09:00
ebb254061d
Update app.js 2024-07-22 00:08:00 +09:00
f2239e75a9
Update http.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-21 19:55:42 +09:00
0764d2793d
Update app.js 2024-07-21 19:38:25 +09:00
4db58b0a3a
Update app.js 2024-07-21 19:23:38 +09:00
ca2976f314
Update app.js 2024-07-21 19:04:39 +09:00
688d4963a5
Update app.js 2024-07-21 19:03:52 +09:00
84dc76800b
Update app.js 2024-07-21 19:00:09 +09:00
190a5c81e3
Update app.js 2024-07-21 18:57:57 +09:00
b096dbe7c6
Update app.js 2024-07-21 18:37:54 +09:00
8b5abfe022
Update http.js fix #122
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-20 17:19:50 +09:00
4db44324e4
Update README.MD 2024-07-20 16:38:02 +09:00
1d21145d95
Update README.MD 2024-07-20 16:37:25 +09:00
ac7169cfe3
Update README.MD 2024-07-20 16:36:42 +09:00
ca3baeebdd
Update README.MD 2024-07-20 16:36:16 +09:00
b92f68e697
Update README.MD 2024-07-20 16:35:41 +09:00
a6b77826d5
Update README.MD 2024-07-20 16:35:22 +09:00
ce591bd9a7
Update README.MD 2024-07-20 16:34:50 +09:00
d71ce372a3
Update README.MD 2024-07-20 16:33:52 +09:00
89a2cd3684
Update SECURITY.MD 2024-07-20 15:04:57 +09:00
f6f4bd673d
Update machine-uuid-mysql.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-07-15 00:37:24 +09:00
2064d40bc9
Update machine-uuid-mysql.js 2024-07-15 00:36:44 +09:00
ace15e3248
Create machine-uuid-mysql.js 2024-07-15 00:35:00 +09:00
a586b7c23f
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-13 16:20:08 +09:00
8cdcff4660
Update README.md
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-12 16:26:13 +09:00
a56d8eb11b
Update setup.iss
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-07-10 20:47:08 +09:00
0a35ade427
Update wmi.js 2024-07-10 20:42:46 +09:00
7a98e9c8bf
Merge pull request #120 from gnh1201/shell-prefix
Add `.setPrefix()` method to `lib/shell` and related files, and supports BITS / 명령행 접두어 및 BITS 지원
2024-07-10 20:06:59 +09:00
aa489da1dc fix 2024-07-10 20:05:45 +09:00
c49d2720f2 fix 2024-07-10 19:54:18 +09:00
0f8557b09f Update autoit.js 2024-07-10 19:47:24 +09:00
c9bc48ad88 fix 2024-07-10 19:46:30 +09:00
4c68780e87 Update shell.js 2024-07-10 19:39:45 +09:00
b3a4125253 Update http.js 2024-07-10 19:37:39 +09:00
1309e2ab8f fix 2024-07-10 19:26:58 +09:00
97f68c39bb
Create .sonarcloud.properties 2024-07-10 15:20:48 +09:00
3c375f6a7c
Update http.js 2024-07-10 13:03:59 +09:00
92c9ae3063
Update http.js 2024-07-10 12:59:28 +09:00
be6937156f
Update http.js 2024-07-10 12:56:18 +09:00
92fdc2ff57
Update http.js 2024-07-10 12:51:16 +09:00
98b49b80a1
Update http.js 2024-07-10 12:07:52 +09:00
840e3bfb4c
Update http.js 2024-07-10 12:05:47 +09:00
4716a3a39e
Update shell.js 2024-07-10 12:03:22 +09:00
f4b2a68121
Update shell.js 2024-07-10 12:01:05 +09:00
c773406464
Update shell.js 2024-07-10 12:00:55 +09:00
25536a9b07
Update powershell.js 2024-07-10 11:57:24 +09:00
870ad0e52e
Update powershell.js 2024-07-10 11:56:53 +09:00
dbe48f9624
Update http.js 2024-07-10 11:48:28 +09:00
fd18d9d150
Update adb.js 2024-07-10 11:37:58 +09:00
83bc9a4b58
Update shell.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-10 11:32:02 +09:00
4b02143a44
Update http.js 2024-07-10 11:31:27 +09:00
9dda6f1e09
Update shell.js 2024-07-10 11:27:02 +09:00
3e67209ae8
Merge pull request #118 from gnh1201/catproxy-nmap
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
NMAP support with Caterpillar Proxy
2024-07-04 15:25:40 +09:00
6cf7d3e223
Merge branch 'master' into catproxy-nmap 2024-07-04 15:24:52 +09:00
7453b1f1ad
Update catproxy.js 2024-07-04 14:58:29 +09:00
8a935345c5
Update catproxy.js 2024-07-04 14:58:14 +09:00
2e9143c220
Update nmap.js 2024-07-04 14:57:20 +09:00
5ba7476685
Update catproxy.js 2024-07-04 14:52:48 +09:00
cde58c21a4
Update catproxy.js 2024-07-04 14:30:12 +09:00
145e22de21
Update http.js
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-07-04 10:56:48 +09:00
a20e0004d2
Update testloader.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-07-01 01:46:54 +09:00
c0e2b7731a
Update catproxy.js 2024-07-01 01:29:24 +09:00
2f974727d6
Update jsonrpc2.js 2024-07-01 01:27:51 +09:00
c91e01e13d
Update and rename caterpillar.js to catproxy.js 2024-07-01 00:53:58 +09:00
137793cd77
Update caterpillar.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-06-26 17:18:36 +09:00
27636a4a72
Update jsonrpc2.js 2024-06-26 17:17:15 +09:00
d86c9728e3
Update caterpillar.js 2024-06-26 17:16:35 +09:00
7de4e4f1be
Create caterpillar.js 2024-06-26 17:07:52 +09:00
3733eaea45
Update jsonrpc2.js 2024-06-26 16:37:04 +09:00
c9c70d9be6
Update README.md
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-06-21 14:31:11 +09:00
54d421fb4f Update pipe-ipc.js
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-06-10 07:14:37 +09:00
14e87fbe63 Update lib/pipe-ipc, lib/xml 2024-06-10 07:13:45 +09:00
46eb8e6609 Clean up code 2024-06-10 06:23:35 +09:00
aa8f10b6a7 Update msoffice.js 2024-06-02 02:14:23 +09:00
b391867f14 fix mistypos 2024-06-02 02:04:46 +09:00
5f5386765d Add and fix the test files 2024-06-02 02:00:17 +09:00
b193fadd72 Update lib/msoffice, Create lib/filetypes.js and data 2024-06-01 06:58:11 +09:00
b6bff48cd0
Update README.md 2024-05-30 12:49:42 +09:00
1fd9adc8be
Update CITATION.cff 2024-05-30 12:08:59 +09:00
b74d64b7ad
Create CITATION.cff 2024-05-29 18:29:28 +09:00
02764be097
Add DOI 2024-05-29 17:22:24 +09:00
6af7be9572 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-05-28 16:13:00 +09:00
ed182b42f9 Update screenshot3.png 2024-05-28 16:12:56 +09:00
87d2a41193
Update CONTRIBUTING.md 2024-05-27 17:59:55 +09:00
ff7322a5de
Add files via upload 2024-05-27 17:51:23 +09:00
66d2f0fb7e
Add files via upload 2024-05-27 17:49:50 +09:00
062d00098e
Update http.js 2024-05-22 18:36:01 +09:00
a96052ce27
Update http.js 2024-05-22 18:34:45 +09:00
0f07c61ad6
Update http.js 2024-05-22 18:30:07 +09:00
2157a23d9f
Update README.md 2024-05-22 13:44:38 +09:00
3286121461 Update setup.iss 2024-05-13 17:52:15 +09:00
6361cb333e Update setup.iss 2024-05-13 17:44:16 +09:00
30ab79eae3 Edit installer files 2024-05-13 17:37:54 +09:00
c9c6481b3f Update AssemblyInfo.cs 2024-05-13 17:09:24 +09:00
e3e68bf696 Add BitmapUtils.cs, Toolkit.cs and more 2024-05-13 17:05:24 +09:00
2edda2b710 Update BitmapUtils.cs 2024-05-13 16:54:17 +09:00
24dcfdb2cc Add BitmapUtils.cs and more 2024-05-13 16:53:33 +09:00
2408e89940
Update chrome.js 2024-04-24 03:42:47 +09:00
547da8ab60
Update chrome.js 2024-04-24 03:41:38 +09:00
c1cc02c217
Update chrome.js 2024-04-24 03:33:12 +09:00
0b4cacf417
Update chrome.js 2024-04-24 03:28:57 +09:00
9bab66ab53 Add VoC link 2024-04-07 20:28:21 +09:00
02073e2247 Update README.md 2024-04-07 16:02:06 +09:00
4aff088de0 Update README.md 2024-04-07 16:01:10 +09:00
475739e9e9 Update README.md 2024-04-07 15:58:21 +09:00
a5f36ea692 Update jsonrpc2.js 2024-04-07 15:55:16 +09:00
6537f9a635 Update jsonrpc2.js 2024-04-07 15:53:55 +09:00
e332682fd2 Add JSON-RPC 2.0 support 2024-04-07 15:48:40 +09:00
9f24bf6384 Update lib/adb.js and delete unnecessary files 2024-04-07 15:30:30 +09:00
b7ac95d8ea Fix #111 2024-04-06 20:46:41 +09:00
14145d6f70 fix indentation 2024-04-06 20:26:58 +09:00
db5c294ab9 Fix the feedback 2024-04-05 #109 2024-04-06 20:26:07 +09:00
6591ee7074 Add linq.js 4.0.2 2024-04-06 15:17:59 +09:00
3f07d2355d Update README.md 2024-04-02 13:58:09 +09:00
b1a7a63987
Merge pull request #108 from fossabot/add-license-scan-badge
Add license scan report and status
2024-04-02 13:50:30 +09:00
7e75b5a812 Add FOSSA report link 2024-04-02 13:39:27 +09:00
d8a8b7e27c remove fossa_report 2024-04-02 11:41:51 +09:00
2d67c88fc8 Add fossa_report 2024-04-01 18:29:00 +09:00
87a16c69b6
Update package.json 2024-04-01 18:14:11 +09:00
fossabot
937d540db5 Add license scan report and status
Signed off by: fossabot <badges@fossa.com>
2024-04-01 06:05:12 -03:00
61de14a449 Update README.md 2024-03-21 02:09:23 +09:00
7f37d5e396 Update README.md 2024-03-21 02:05:12 +09:00
c7869d6819 Update README.md 2024-03-21 01:53:18 +09:00
ab6b28f220 Update README.md 2024-03-21 01:44:47 +09:00
7cc1dfd06a Update README.md 2024-03-21 01:37:38 +09:00
d4191917f6 Update README.md 2024-03-21 01:05:15 +09:00
c41bc5b791 Update README.md 2024-03-21 01:25:08 +09:00
853eabc898 Update README.md 2024-03-21 01:23:45 +09:00
8aa0005427 Update README.md 2024-03-21 01:22:09 +09:00
0b9c5f0c5e Fix summernote issues 2024-03-20 21:12:59 +09:00
0e324a349d Fix summernote issues 2024-03-20 16:30:30 +09:00
f7b4934f6b Update README.md 2024-03-20 11:22:37 +09:00
533521239f Add method Browser.waitUntil 2024-03-20 11:13:58 +09:00
05df3518ac Update encryptor.js 2024-03-19 18:00:08 +09:00
e0df993bad Update encryptor.js 2024-03-19 17:59:34 +09:00
4c88348ddf Update README.md 2024-03-19 17:48:40 +09:00
1308d7a115 Update README.md 2024-03-19 17:45:23 +09:00
aca13b53eb Update README.md 2024-03-19 17:44:39 +09:00
f105bb2eb7 Update README.md 2024-03-19 17:39:22 +09:00
40972575b6 Update README.md 2024-03-19 17:25:42 +09:00
98fe04291b Update README.md 2024-03-19 17:24:00 +09:00
ddb9a47f59 Update README.md 2024-03-19 17:23:01 +09:00
36c5a8a586 fix description 2024-03-19 17:21:51 +09:00
c8b5e82b12 Fix descriptions 2024-03-19 17:17:15 +09:00
2fb4b62b8d Update testloader.js, test-misc.json 2024-03-12 15:07:12 +09:00
51ef1508bd
Update FUNDING.yml 2024-02-23 17:10:22 +09:00
85fd0e2e01 Update encryptor.js 2024-01-30 18:28:54 +09:00
94f11d73cd Update app.js 2024-01-27 14:12:40 +09:00
302b33d48b Update sendmail.js 2024-01-27 14:01:57 +09:00
9cdfd205bf Remove the package: html5media 2024-01-27 13:51:32 +09:00
64d178a53a
Update README.MD 2024-01-27 10:02:42 +09:00
a5ba2423d5
Update README.MD 2024-01-27 10:02:19 +09:00
bbd45ab9f9
Update README.MD 2024-01-27 01:17:12 +09:00
ef755b3217
Update README.MD 2024-01-27 01:16:49 +09:00
4bd770d078 Update app.js 2024-01-27 00:50:25 +09:00
4db4d98f0b HIGHT(ISO/IEC 18033-3) encryption and decryption 2024-01-27 00:50:07 +09:00
453e63da2e Update app.js 2024-01-26 18:27:11 +09:00
01be6b6252 Update app.js 2024-01-26 16:58:27 +09:00
bafc0a085d Update app.js 2024-01-26 16:57:53 +09:00
79c64726e2 Update app.js 2024-01-26 16:55:49 +09:00
7d01adb54b Update HIGHT.cs 2024-01-26 16:29:22 +09:00
436ce3d88d
Update SECURITY.MD 2024-01-25 11:08:03 +09:00
d0593958e7
Update SECURITY.MD 2024-01-25 10:54:55 +09:00
0a069e3f3a
Update README.md 2024-01-25 06:14:01 +09:00
83d90a8110
Update FUNDING.yml 2024-01-25 06:12:30 +09:00
a268b5acc6
Update FUNDING.yml 2024-01-25 06:11:56 +09:00
bcdf4f9165
Update README.md 2024-01-25 06:10:54 +09:00
8f733eba64
Update README.md 2024-01-25 05:57:02 +09:00
8515627f82 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-01-25 01:33:03 +09:00
f4b86735fb Add EncryptStringHIGHT(), DecryptStringHIGHT() 2024-01-25 01:32:59 +09:00
166dd70ef9
[lib/http] cURL error with non-escaped ampersand on Command Prompt #103 2024-01-24 19:23:39 +09:00
541078bda8 Add WelsonJS.Cryptography.HIGHT 2024-01-24 13:28:20 +09:00
cfc9501554 Update app.js, lib/std.js 2024-01-08 15:42:54 +09:00
04c2325ade
Update chrome.js 2024-01-08 01:41:35 +09:00
6a0491c419
Update README.MD 2024-01-05 21:41:14 +09:00
60854fc9df
Update README.MD 2024-01-05 21:36:39 +09:00
df8b345ddf Update README.md 2024-01-05 16:17:09 +09:00
e650915bb9 Update README.md 2024-01-05 16:11:30 +09:00
ed2f98e558 Update README.md 2024-01-05 16:05:43 +09:00
1f7a4a0778 Update README.md 2024-01-05 16:01:58 +09:00
c179b2e478 Add image 2024-01-05 16:01:15 +09:00
c0c64de20d Update NamedSharedMemory.cs 2024-01-04 18:07:04 +09:00
82deec7a81 Remove the experimental files 2024-01-04 17:51:16 +09:00
1972c4f44a experimental 2024-01-04 17:43:57 +09:00
43a56c5360 experimental 2024-01-04 17:40:41 +09:00
604fc27a59 experimental 2024-01-04 17:35:59 +09:00
f0504e12ec Update testloader.js 2024-01-04 16:14:13 +09:00
7f9840f765 Merge branch 'master' of https://github.com/gnh1201/welsonjs 2024-01-04 15:55:41 +09:00
b1a0e91dd9 Update the native component 2024-01-04 15:55:21 +09:00
097f146499 Update test-misc.json 2024-01-04 15:48:09 +09:00
11209fa8d7 Update test-misc.json 2024-01-04 15:47:57 +09:00
bd5bf9ebe0 Update testoader.js 2024-01-04 15:47:05 +09:00
28fd89f22d shared memory #96 2024-01-04 15:23:26 +09:00
dddfa3cc47 Update testloader.js #96 2024-01-04 12:05:47 +09:00
525 changed files with 57294 additions and 11130 deletions

47
.appveyor.yml Normal file
View File

@ -0,0 +1,47 @@
version: 0.2.7.build{build}
image: Visual Studio 2019
clone_folder: C:\projects\welsonjs
environment:
ORGANIZATION_ID: 8ee5ec82-36dc-4619-ac33-5bc1117428fe
PROJECT_SLUG: welsonjs
ARTIFACT_CONFIGURATION_SLUG: initial
matrix:
- CONFIGURATION: Debug
SIGNING_POLICY_SLUG: test-signing
- CONFIGURATION: Release
SIGNING_POLICY_SLUG: release-signing
before_build:
- nuget restore WelsonJS.Toolkit
build_script:
- msbuild "C:\projects\welsonjs\WelsonJS.Toolkit\WelsonJS.Toolkit.sln" /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /p:Configuration=%CONFIGURATION% /p:Platform="x86"
after_build:
- cmd: mkdir artifacts
#- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Toolkit\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Service\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Launcher\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: nuget pack WelsonJS.Toolkit\WelsonJS.Toolkit\ -properties Configuration=%CONFIGURATION% -properties Platform=x86 -OutputDirectory artifacts\
- cmd: 7z a artifacts.zip artifacts\*
artifacts:
- path: artifacts.zip
name: WelsonJS.Toolkit
deploy:
- provider: Webhook
url: https://app.signpath.io/API/v1/%ORGANIZATION_ID%/Integrations/AppVeyor?ProjectSlug=%PROJECT_SLUG%&SigningPolicySlug=%SIGNING_POLICY_SLUG%&ArtifactConfigurationSlug=%ARTIFACT_CONFIGURATION_SLUG%
authorization:
secure: nABfe+lksIRfS7lVnkq3EdIYNH8KOka+5ZFTUJqUW2nckBubhrlAXarbCPJHLp9FWWf3zxAWhNwT0It+qyqPRQ==
notifications:
- provider: Email
to:
- abuse@catswords.net
subject: 'Build #{{build}} {{status}}'
on_build_success: false
on_build_failure: true

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: gnh1201
custom: ['https://gnh1201.link']

View File

@ -32,7 +32,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'csharp', 'javascript', 'python' ]
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
@ -42,7 +42,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -53,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@ -67,4 +67,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2

23
.github/workflows/llm-code-review.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: AI Code Review
on:
pull_request:
types: [opened, synchronize, reopened]
issues:
types: [opened, reopened]
jobs:
repofix:
runs-on: ubuntu-latest
steps:
- name: Run RepoFixAI
uses: Manav916/llm-code-review@main
with:
groq_api_key: ${{ secrets.GROQ_API_KEY }}
groq_model: 'llama-3.3-70b-versatile'
github_token: ${{ secrets.GITHUB_TOKEN }}
# exclude_extensions: 'txt'
repo_owner: ${{ github.repository_owner }}
repo_name: ${{ github.event.repository.name }}
event_number: ${{ github.event.number || github.event.issue.number }} # when listening for both pull requests and issues
event_name: ${{ github.event_name }}

18
.gitignore vendored
View File

@ -103,11 +103,13 @@ dist
# TernJS port file
.tern-port
# Custom directories and files
bin/
packages/
config.xml
staticip.xml
# ChatGPT API Key
data/chatgpt-apikey.txt
# user private assets
bin
data/*-apikey.txt
data/*.nomedia.txt
app/assets/img/_templates
app/assets/img/_captured
settings.ini
defaultService.js
lib/*.private.js
data/python313.zip

9
.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[submodule "app/assets/tessdata"]
path = app/assets/tessdata
url = https://github.com/tesseract-ocr/tessdata
[submodule "app/assets/tessdata_best"]
path = app/assets/tessdata_best
url = https://github.com/tesseract-ocr/tessdata_best
[submodule "app/assets/tessdata_fast"]
path = app/assets/tessdata_fast
url = https://github.com/tesseract-ocr/tessdata_fast

3
.sonarcloud.properties Normal file
View File

@ -0,0 +1,3 @@
sonar.issue.ignore.multicriteria=e1
sonar.issue.ignore.multicriteria.e1.ruleKey=javascript:S3504
sonar.issue.ignore.multicriteria.e1.resourceKey=**

11
CITATION.cff Normal file
View File

@ -0,0 +1,11 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
- family-names: "Go"
given-names: "Namhyeon"
orcid: "https://orcid.org/0009-0006-8421-0911"
title: "WelsonJS"
version: 0.2.7.12
doi: 10.5281/zenodo.11382384
date-released: 2024-05-29
url: "https://github.com/gnh1201/welsonjs"

70
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,70 @@
# Code of Conduct - WelsonJS
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviors that they deem
inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at <abuse@catswords.net>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version
[1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and
[2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md),
and was generated by [contributing-gen](https://github.com/bttger/contributing-gen).

147
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,147 @@
<!-- omit in toc -->
# Contributing to WelsonJS
First off, thanks for taking the time to contribute! ❤️
All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉
> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
> - Star the project
> - Tweet about it
> - Refer this project in your project's readme
> - Mention the project at local meetups and tell your friends/colleagues
<!-- omit in toc -->
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [I Have a Question](#i-have-a-question)
- [I Want To Contribute](#i-want-to-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Your First Code Contribution](#your-first-code-contribution)
- [Improving The Documentation](#improving-the-documentation)
- [Styleguides](#styleguides)
- [Commit Messages](#commit-messages)
- [Join The Project Team](#join-the-project-team)
## Code of Conduct
This project and everyone participating in it is governed by the
[WelsonJS Code of Conduct](https://github.com/gnh1201/welsonjs/blob/master/CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable behavior
to <abuse@catswords.net>.
## I Have a Question
> If you want to ask a question, we assume that you have read the available [Documentation](https://catswords.social/@catswords_oss).
Before you ask a question, it is best to search for existing [Issues](https://github.com/gnh1201/welsonjs//issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first.
If you then still feel the need to ask a question and need clarification, we recommend the following:
- Open an [Issue](https://github.com/gnh1201/welsonjs//issues/new).
- Provide as much context as you can about what you're running into.
- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant.
We will then take care of the issue as soon as possible.
You might want to create a separate issue tag for questions and include it in this description. People should then tag their issues accordingly.
Depending on how large the project is, you may want to outsource the questioning, e.g. to Stack Overflow. You may add additional contact and information possibilities:
- ActivityPub
- Stack Overflow tag or Public Forums
- E-Mail List
## I Want To Contribute
> ### Legal Notice <!-- omit in toc -->
> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
### Reporting Bugs
<!-- omit in toc -->
#### Before Submitting a Bug Report
A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.
- Make sure that you are using the latest version.
- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://catswords.social/@catswords_oss). If you are looking for support, you might want to check [this section](#i-have-a-question)).
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/gnh1201/welsonjs/issues?q=label%3Abug).
- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue.
- Collect information about the bug:
- Stack trace (Traceback)
- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
- Possibly your input and the output
- Can you reliably reproduce the issue? And can you also reproduce it with older versions?
<!-- omit in toc -->
#### How Do I Submit a Good Bug Report?
> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to <abuse@catswords.net>.
<!-- You may add a PGP key to allow the messages to be sent encrypted as well. -->
We use GitHub issues to track bugs and errors. If you run into an issue with the project:
- Open an [Issue](https://github.com/gnh1201/welsonjs//issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.)
- Explain the behavior you would expect and the actual behavior.
- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
- Provide the information you collected in the previous section.
Once it's filed:
- The project team will label the issue accordingly.
- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced.
- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be [implemented by someone](#your-first-code-contribution).
<!-- You might want to create an issue template for bugs and errors that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->
### Suggesting Enhancements
This section guides you through submitting an enhancement suggestion for WelsonJS, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.
<!-- omit in toc -->
#### Before Submitting an Enhancement
- Make sure that you are using the latest version.
- Read the [documentation](https://catswords.social/@catswords_oss) carefully and find out if the functionality is already covered, maybe by an individual configuration.
- Perform a [search](https://github.com/gnh1201/welsonjs/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
<!-- omit in toc -->
#### How Do I Submit a Good Enhancement Suggestion?
Enhancement suggestions are tracked as [GitHub issues](https://github.com/gnh1201/welsonjs//issues).
- Use a **clear and descriptive title** for the issue to identify the suggestion.
- Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you.
- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. <!-- this should only be included if the project has a GUI -->
- **Explain why this enhancement would be useful** to most WelsonJS users. You may also want to point out the other projects that solved it better and which could serve as inspiration.
<!-- You might want to create an issue template for enhancement suggestions that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->
### Your First Code Contribution
Just Notepad, in Windows machine.
## Styleguides
### Commit Messages
Flexible. We will respect your style.
## Join The Project Team
Contact us:
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* abuse@catswords.net
## Attribution
This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)!

View File

@ -1,8 +0,0 @@
# These are supported funding model platforms
github: gnh1201
open_collective: welsonjs
liberapay: catswords
custom: ['https://www.buymeacoffee.com/catswords']
patreon: catswords # Replace with a single Patreon username
ko_fi: catswords

216
README.md
View File

@ -1,73 +1,84 @@
# welsonjs
WelsonJS - Build a Windows app on the Windows built-in JavaScript engine.
Now, You can build an Windows desktop app with JavaScript, TypeScript, ReScript, and HTML/CSS on Windows built-in ECMAScript engine.
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs?ref=badge_shield)
[![AppVeyor Status](https://ci.appveyor.com/api/projects/status/github/gnh1201/welsonjs?svg=true)](https://ci.appveyor.com/project/gnh1201/welsonjs)
[![DOI 10.5281/zenodo.11382384](https://zenodo.org/badge/DOI/10.5281/zenodo.11382384.svg)](https://doi.org/10.5281/zenodo.11382384)
[![ChatGPT available](https://img.shields.io/badge/ChatGPT-74aa9c?logo=openai&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Anthropic available](https://img.shields.io/badge/Anthropic-000000?logo=Anthropic&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Grok available](https://img.shields.io/badge/Grok-000000?logo=x&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Google Gemini available](https://img.shields.io/badge/Google%20Gemini-886FBF?logo=googlegemini&logoColor=fff)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![slideshare.net presentation](https://img.shields.io/badge/SlideShare-black?logo=slideshare)](https://www.slideshare.net/slideshow/welsonjs-javascript-framework-presentation-2024/276005486)
[![YouTube promotion video](https://img.shields.io/badge/YouTube-red?logo=youtube)](https://youtu.be/JavH7Dms8-U)
[![Discord chat](https://img.shields.io/discord/359930650330923008?logo=discord)](https://discord.gg/XKG5CjtXEj)
[![Open to work](https://img.shields.io/badge/%23-OPENTOWORK-green)](https://github.com/gnh1201/welsonjs/discussions/167)
WelsonJS = ***W***indows + ***El***ectr***on***-like + ***Javascript(JS)*** + [Your contribution](FUNDING.yml)
<img src="app/assets/img/logo.svg" height="32" alt=""/> WelsonJS - Build a Windows app on the Windows built-in JavaScript engine.
Dual license notice: The default license for this project is GPL 3.0. However, if the GPL 3.0 license is not compatible with Microsoft products, it is subject to the MS-RL license.
![A Cover Image: Windows in 1999](https://ics.catswords.net/cover.png)
I presented this project in [the open-source contest in the Republic of Korea in November 2023](https://www.slideshare.net/gnh1201/welsonjs-2023).
Now, You can build a Windows desktop app with JavaScript, TypeScript, CoffeeScript, ReScript, and HTML/CSS on Windows built-in ECMAScript engine.
WelsonJS = ***W***indows + ***El***ectr***on***-like + ***Javascript(JS)*** + :heart:[Contributions](https://github.com/sponsors/gnh1201)
* :kissing_cat: [Download Latest WelsonJS Launcher (ics.catswords.net)](https://ics.catswords.net/welsonjs_launcher_latest.zip)
* :rocket: [Launch the WelsonJS environment on Microsoft Azure (azuremarketplace.microsoft.com)](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/catswords.catswords-welsonjs-feb2025-02?tab=Overview)
**Note**: The default license for this project is GPL 3.0. However, if the GPL 3.0 license is not compatible with Microsoft products, it is subject to the MS-RL license.
## Sponsors
* :octocat: [GitHub Sponsors](https://github.com/sponsors/gnh1201), :coffee: [Buy me a coffee](https://buymeacoffee.com/catswords)
* <img src="https://ics.catswords.net/logo_oss.gif" height="32" alt=""/> [Open SW Portal](https://oss.kr), NIPA National IT Industry Promotion Agency<sup>(정보통신산업진흥원)</sup>
* <img src="https://ics.catswords.net/signpath_logo.png" height="32" alt=""/> Free code signing provided by [SignPath.io](https://signpath.io), certificate by [SignPath Foundation](https://signpath.org/)
* <img src="https://ics.catswords.net/f1security_logo.png" height="32" alt=""/> [F1Security<sup>(에프원시큐리티)</sup>](https://f1security.co.kr/) provides [industry-leading](https://www.ksecurity.or.kr/kisis/subIndex/469.do) web security services.
* <img src="https://ics.catswords.net/microsoft_logo.png" height="32" alt=""/> [Microsoft ISV Success Program](https://www.microsoft.com/en-us/isv/isv-success), Grow your business with powerful tools.
* :zap: [Integrations](https://catswords-oss.rdbl.io/5719744820/8278298336) ([ScrapeOps](https://scrapeops.io?fpr=namhyeon75), [SearchApi](https://www.searchapi.io/?via=namhyeon), [AviationStack](https://aviationstack.com?utm_source=FirstPromoter&utm_medium=Affiliate&fpr=namhyeon71), [Coupang](https://link.coupang.com/a/b7HV3V)...)
## System Requirements
* **Operating Systems**: Windows XP SP3 or later (Currently, Windows 11 24H2)
* For systems running Windows 2000 or earlier versions (e.g., 95, 98, Me), please contact us separately.
## Why Choose WelsonJS?
WelsonJS is an advanced JavaScript framework designed to operate in extreme conditions where conventional solutions may fail. Unlike traditional JavaScript frameworks, WelsonJS focuses on executing scripts in constrained environments, ensuring reliable performance even with minimal system resources.
### Key Features
* **Lightweight and Efficient**: Optimized for environments with limited computing power, WelsonJS delivers efficient script execution without unnecessary overhead.
* **Windows ECMAScript Compatibility**: Designed to run seamlessly on Windows-based systems, adhering to the ECMAScript standard while maintaining lightweight execution.
* **Standalone Execution**: Unlike well-known JavaScript runtimes, which require external dependencies, a WelsonJS application can operate as a self-contained app, making it suitable for embedded systems and isolated environments.
* **Security-Oriented**: Built with security in mind, ensuring controlled execution of scripts without compromising system integrity.
* **Minimalist Design**: WelsonJS strips away unnecessary complexities, focusing on core functionalities that maximize performance and reliability.
### Use Cases
* **Legacy System Integration**: WelsonJS provides a practical solution for running JavaScript on older Windows environments where modern frameworks are not feasible.
* **Automation and Scripting**: Ideal for executing scripts in constrained environments, enabling automated workflows and system-level scripting.
* **Embedded Applications**: Suitable for devices and systems with strict resource constraints, such as industrial controllers and embedded platforms.
* **Security-Focused Environments**: Useful in security-sensitive applications where dependencies on external network connections are limited.
* **Office Automation**: Suitable for office automation tasks using Microsoft Office and various LLM-based AI (such as ChatGPT).
WelsonJS is tailored for developers who need a reliable, lightweight JavaScript framework in environments where traditional solutions are impractical. Whether working with legacy systems, embedded devices, or security-critical applications, WelsonJS ensures that JavaScript remains a viable and efficient option.
## Structure
![Structure](app/assets/img/structure.png)
![The structure of the WelsonJS framework can be extended based on whether it operates in a console (command prompt) environment, a GUI (with HTML/CSS) environment, or a service environment, with the `app.js` file at its core.](https://ics.catswords.net/structure.png)
## Specifications
- Built-in transpilers: [TypeScript](https://www.typescriptlang.org/), [Rescript](https://rescript-lang.org/), [CoffeeScript 2](https://coffeescript.org/), [LiveScript](https://livescript.net/)
- Ready to use on Windows machine immediately. No require additional software installation.
- ES5(ECMAScript 5), XML, JSON, YAML compatibility
- [github.com/zloirock/core-js](https://github.com/zloirock/core-js)
- [github.com/douglascrockford/JSON-js](https://github.com/douglascrockford/JSON-js) (aka. JSON2.js)
- [github.com/nodeca/js-yaml](https://github.com/nodeca/js-yaml)
- HTML5, CSS3 compatibility
- [github.com/aFarkas/html5shiv](https://github.com/aFarkas/html5shiv)
- [github.com/parndt/jquery-html5-placeholder-shim](https://github.com/parndt/jquery-html5-placeholder-shim)
- [github.com/scottjehl/Respond](https://github.com/scottjehl/Respond)
- [github.com/keithclark/selectivizr](https://github.com/keithclark/selectivizr)
- [github.com/arv/ExplorerCanvas](https://github.com/arv/ExplorerCanvas)
- [github.com/etianen/html5media](https://github.com/etianen/html5media)
- [github.com/Modernizr/Modernizr](https://github.com/Modernizr/Modernizr)
- Default CSS Framework
- [github.com/jslegers/cascadeframework](https://github.com/jslegers/cascadeframework)
- WYSIWYG HTML Editor
- [github.com/summernote/summernote](https://github.com/summernote/summernote)
- Included libraries
- [jQuery](https://jquery.com/)
- [jQuery UI](https://jqueryui.com/)
- [github.com/kamranahmedse/jquery-toast-plugin](https://github.com/kamranahmedse/jquery-toast-plugin)
- [github.com/hiddentao/squel](https://github.com/hiddentao/squel)
- [github.com/BorisMoore/jsrender](https://github.com/BorisMoore/jsrender)
- [Includes binaries](https://github.com/gnh1201/welsonjs/blob/master/bin/README.MD)
- [module.exports](https://nodejs.org/en/knowledge/getting-started/what-is-require/), CommonJS, UMD compatibility
- [NPM](https://www.npmjs.com/) compatibility
- [gRPC](https://grpc.io/) protocol support (New feature in 2023) [see video demo](https://youtu.be/GqbU5JKuLac)
* Built-in transpilers: [TypeScript](https://www.typescriptlang.org/), [Rescript](https://rescript-lang.org/), [CoffeeScript 2](https://coffeescript.org/), [LiveScript](https://livescript.net/)
* **Ready to use on Windows machine immediately. No additional software installation is required.**
* **WelsonJS Launcher**: Manage instances (Like a container), User-defined variable editor, [Microsoft Monaco Editor](https://github.com/microsoft/monaco-editor) and [React](https://react.dev/) (Pre-embedded rich code editor), [Microsoft Copilot](https://copilot.microsoft.com), and [Azure AI Services](https://azure.microsoft.com/en-us/products/ai-services) on the code editor.
* ES5(ECMAScript 5), XML, JSON, YAML compatibility: [core-js](https://github.com/zloirock/core-js), [JSON2.js](https://github.com/douglascrockford/JSON-js), [js-yaml](https://github.com/nodeca/js-yaml)
* HTML5 compatibility on the built-in HTML rendering engine: [html5shiv](https://github.com/aFarkas/html5shiv), [jquery-html5-placeholder-shim](https://github.com/parndt/jquery-html5-placeholder-shim), [Respond](https://github.com/scottjehl/Respond), [selectivizr](https://github.com/keithclark/selectivizr), [ExplorerCanvas](https://github.com/arv/ExplorerCanvas), [Modernizr](https://github.com/Modernizr/Modernizr)
* Classical CSS Frameworks: [cascadeframework](https://github.com/jslegers/cascadeframework), [golden-layout](https://github.com/golden-layout/golden-layout)
* WYSIWYG HTML Editor: [summernote](https://github.com/summernote/summernote)
* Included libraries: [jQuery](https://jquery.com/), [jQuery UI](https://jqueryui.com/), [jquery-toast-plugin](https://github.com/kamranahmedse/jquery-toast-plugin), [squel](https://github.com/hiddentao/squel), [jsrender](https://github.com/BorisMoore/jsrender), [linq](https://github.com/mihaifm/linq), [pegjs](https://github.com/pegjs/pegjs), [numbers.js](https://github.com/numbers/numbers.js)
* Compatible with modern JavaScript specifications: [module.exports](https://nodejs.org/api/modules.html#moduleexports), CommonJS, UMD compatibility, [NPM(Node Package Manager)](https://www.npmjs.com/) compatibility
* Support a device debugging protocol clients: [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/), [ADB(Android Debug Bridge)](https://source.android.com/docs/setup/build/adb)
* RPC(Remote Procedure Call) protocol clients: [gRPC](https://grpc.io/), [JSON-RPC 2.0](https://www.jsonrpc.org/specification)
* Various types of HTTP clients: [XHR(MSXML)](https://developer.mozilla.org/docs/Glossary/XMLHttpRequest), [cURL](https://curl.se/), [BITS](https://en.m.wikipedia.org/w/index.php?title=Background_Intelligent_Transfer_Service), [CERT](https://github.com/MicrosoftDocs/windowsserverdocs/blob/main/WindowsServerDocs/administration/windows-commands/certutil.md), [Web Proxy, SEO/SERP](https://catswords-oss.rdbl.io/5719744820/1706431912)
* The native toolkit for Windows environments: Write a Windows Service Application with JavaScript, Control a window handle, Cryptography (e.g., [ISO/IEC 18033-3:2010](https://www.iso.org/standard/54531.html) aka. [HIGHT](https://seed.kisa.or.kr/kisa/algorithm/EgovHightInfo.do)), [Named Shared Memory](https://learn.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory) based [IPC](https://qiita.com/gnh1201/items/4e70dccdb7adacf0ace5), [NuGet package](https://www.nuget.org/packages/WelsonJS.Toolkit)
* Generative AI integrations: [Multiple LLM and sLLM](https://catswords-oss.rdbl.io/5719744820/5510319392) (e.g., ChatGPT, Claude, ...)
* Aviation Data integrations: [AviationStack](https://aviationstack.com?utm_source=FirstPromoter&utm_medium=Affiliate&fpr=namhyeon71), [SearchApi Google Flight](https://www.searchapi.io/?via=namhyeon)
* VM infrastructure tool integrations: [OVFTool for Broadcom/VMware infrastructures](https://developer.broadcom.com/tools/open-virtualization-format-ovf-tool/latest)
* Everything you can imagine.
## Included libraries
- lib/std (Standard library)
- lib/system (System interface)
- lib/base64 (BASE64 encode and decode)
- lib/file (File I/O interface)
- lib/http (HTTP interface with MSXML and cURL)
- lib/json (JSON library)
- lib/registry (Windows Registry interface)
- lib/security (Windows Security Policy interface)
- lib/shell (Windows Shell (Command Prompt) interface)
- lib/powershell (Windows Powershell interface)
- lib/service (Windows Service interface)
- lib/oldbrowser (ES5, HTML5/CSS3 compatibility layer)
- lib/uri (URI scheme interface)
- lib/winlibs (Windows DLL(Dynamic-link library) interface)
- lib/autohotkey ([AutoHotkey](https://www.autohotkey.com/) interface)
- lib/autoit ([AutoIt3/AutoItX](https://www.autoitscript.com/) interface)
- lib/msoffice (Microsoft Office (e.g. Excel) interface)
- lib/gtk (GTK/GladeXML server GUI interface)
- lib/chrome (Chrome Web Browser Debugging interface)
- lib/toolkit (`WelsonJS.Toolkit` native component)
- lib/pipe-ipc (PIPE-based IPC(Inter-Process Communication) implementation)
- lib/chatgpt ([ChatGPT](https://openai.com/chatgpt) integration)
- Everything you can imagine.
## Make your own `sayhello` example
## Quick start
### 1. Write a file `lib/sayhello.js`
```js
@ -78,8 +89,8 @@ function say() {
exports.say = say;
exports.VERSIONINFO = "SayHello Library (sayhello.js) version 0.1";
exports.AUTHOR = "abuse@catswords.net"; // e.g. YOUR EMAIL ADDRESS
exports.VERSIONINFO = "SayHello (sayhello.js) version 0.1";
exports.AUTHOR = "abuse@catswords.net";
exports.global = global;
exports.require = global.require;
```
@ -98,46 +109,73 @@ function main() {
exports.main = main;
```
### 3. Execute file on the command prompt
### 3. Execute script on the console
```cmd
C:\Users\oss\Documents\GitHub\welsonjs> cscript app.js sayhello
C:\Users\JohnDoe\Documents\GitHub\welsonjs> cscript app.js sayhello
calling say()
hello
ended say()
```
## How to make your own setup file
- Please check `setup.iss` file it could be compile with [Inno Setup](https://jrsoftware.org/isinfo.php)
## How to release my application?
The WelsonJS framework suggests the following application release methods:
* **Compress to Zip, and use the launcher**: Compress the files and directories necessary for running the project into a Zip file, and distribute it along with the [WelsonJS Launcher](https://catswords-oss.rdbl.io/5719744820/4131485779).
* **Build a setup file**: Use [Inno Setup](https://jrsoftware.org/isinfo.php). The setup profile (the `setup.iss` file) is already included.
* **Copy all directories and files**: This is the simplest and most straightforward method.
## Screenshots
![Screenshot 1](app/assets/img/screenshot.png)
![(Screenshot 1) GUI environment](https://ics.catswords.net/screenshot.png)
![Screenshot 2](app/assets/img/screenshot2.png)
![(Screenshot 2) Command-line environment](https://ics.catswords.net/screenshot2.png)
![Screenshot 3](app/assets/img/screenshot3.png)
![(Screenshot 3) WelsonJS with Microsoft Excel](https://ics.catswords.net/screenshot3.png)
## Thanks!
![Thanks 1](app/assets/img/thanks.png)
![(Screenshot 4) Write a Windows Services with JavaScript](https://ics.catswords.net/screenshot4.png)
- https://www.facebook.com/javascript4u/posts/1484014618472735
- https://python5.com/q/xtbsqjxb
![(Screenshot 5) Template Matching on the computer screen](https://ics.catswords.net/screenshot5.png)
## Related projects
- [gnh1201/wsh-js-gtk](https://github.com/gnh1201/wsh-js-gtk) - GTK GUI ported to Windows Scripting Host - Javascript (Microsoft JScript) (wsh-js)
- [gnh1201/wsh-json](https://github.com/gnh1201/wsh-json) - JSON stringify/parse (encode/decode) for Windows Scripting Host
- [redskyit/wsh-appjs](https://github.com/redskyit/wsh-appjs) - require-js and app framework for Windows Scripting Host JavaScript
- [JohnLaTwC's gist](https://gist.github.com/JohnLaTwC/4315bbbd89da0996f5c08c032b391799) - JavaScript RAT
- [JSMan-/JS-Framework](https://github.com/JSMan-/JS-Framework) - No description
- [iconjack/setTimeout-for-windows-script-host](https://github.com/iconjack/setTimeout-for-windows-script-host) - Replacement for the missing setTimeout and clearTimeout function in Windows Script Host
- [johnjohnsp1/WindowsScriptHostExtension](https://github.com/johnjohnsp1/WindowsScriptHostExtension) - Inject DLL Prototype using Microsoft.Windows.ACTCTX COM Object
- [kuntashov/jsunit](https://github.com/kuntashov/jsunit) - JSUnit port for Windows Scripting Host
- [nickdoth/WSHHttpServer](https://github.com/nickdoth/WSHHttpServer) - HTTP server based on Windows Script Host
![(Screenshot 6) The Launcher for WelsonJS Application Packages](https://ics.catswords.net/screenshot6.png)
## Image stocks
- [7418_blocks_color_modules_rgb_square_icon](https://www.iconfinder.com/icons/7418/blocks_color_modules_rgb_square_icon) (Icon File) - Sergio Sanchesz Lopez, Futurosoft
![(Screenshot 7) Microsoft Monaco Editor on WelsonJS Launcher](https://ics.catswords.net/screenshot7.png)
## Contact me
If you have any inquiries about this project or if you are interested in becoming a partner, please feel free to contact us. By becoming an official partner, you can initiate exclusive (e.g. EULA) projects using WelsonJS. Explore the potential for achievements in various areas, such as website quality improvement and performance evaluation automation, with WelsonJS.
## Thanks to
* :heart: Artwork (Logo image): [@druidesse](https://github.com/druidesse)
* :heart: Artwork (Cover image): [@_bag0@x.com](https://x.com/_bag0)
* :heart: Special Contributors: [@hcho3](https://github.com/hcho3), :octocat: [GitHub Sponsors](https://github.com/sponsors/gnh1201)
* :sunglasses: Heavy-industry specialized CSP(Cloud Service Provider) in Republic of Korea - Use case establishment
* :sunglasses: Live-commerce specialized online advertisement companies in Republic of Korea - Use case establishment
* :sunglasses: Information security companies in Republic of Korea - Use case establishment
* :eyes: [Facebook Group "Javascript Programming"(javascript4u)](https://www.facebook.com/javascript4u/posts/build-a-windows-desktop-apps-with-javascript-html-and-cssmorioh-javascript-html-/1484014618472735/)
* :eyes: [morioh.com](https://morioh.com/a/23c427a82bf1/build-a-windows-desktop-apps-with-javascript-html-and-css)
* :eyes: CSDN
* :eyes: Qiita - Knowledge-base about WSH environment
* :sunglasses: Redsky Software - PoC(Proof of Concept) of the CommonJS on WSH environment
* :sunglasses: Inspired by a small-sized JavaScript payload demonstrated by a cybersecurity related group.
* :sunglasses: Inspired by the use of Named Shared Memory in a cross-runtime IPC implementation written by the unidentified developer.
* :eyes: Fediverse
* :eyes: [Hacker News](https://news.ycombinator.com/item?id=41316782)
* :eyes: [WebToolsWeekly](https://webtoolsweekly.com/archives/issue-585/)
* :eyes: [GeekNews](https://news.hada.io/weekly/202441) in GeekNews Weekly (2024-09-30 ~ 2024-10-06)
* :eyes: [daily.dev](https://app.daily.dev/posts/js-libraries-svg-tools-json-databases-8quregz3a)
* :eyes: [PitchHut](https://www.pitchhut.com/project/proj_Ya136OLSW5at)
* :eyes: [Disquiet](https://dis.qa/nv6T6)
- abuse@catswords.net
- ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
## Report abuse
* [GitHub Security Advisories (gnh1201/welsonjs)](https://github.com/gnh1201/welsonjs/security)
* [abuse@catswords.net](mailto:abuse@catswords.net)
## Join the community
I am always open. Collaboration, opportunities, and community activities are all welcome.
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join)
* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS #welsonjs on Discord (discord.gg)](https://discord.gg/XKG5CjtXEj)
## Special channels
* [A paid consultation channel (m.expert.naver.com)](https://m.expert.naver.com/mobile/expert/product/detail?storeId=100051156&productId=100144540) is available for Korean<sup>(한국어)</sup> region.
* [Join the private operations channel (forms.gle)](https://forms.gle/ZKAAaGTiGamksHoo8) is available for all regions.
## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs?ref=badge_large)

View File

@ -1,20 +0,0 @@
# REGASM for WelsonJS
In general, the location of REGASM is as follows.
```
C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe
```
Or it may vary depending on the version.
## How to register .NET COM/DLL component
Example:
```
C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe /codebase WelsonJS.Toolkit.dll
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe /codebase WelsonJS.Toolkit.dll
```
Thank you.

View File

@ -1,44 +1,63 @@
# Security Note for WelsonJS
## Caution
This repository contains information on accessing Windows APIs and functions on the JavaScript runtime, along with recent case studies. While this can provide a flexible development environment for anyone, it can also be misused for malicious purposes. Please be aware that using this project to create abuse tools, such as a DoS attack, may result in legal punishment in your country. We encourage you to use this project only for creating web technology-based applications, like Electron, or legally permitted testing tools.
## License
The WelsonJS project is available under either the GPLv3 or MS-RL opensource licenses. If the GPLv3 license is not compatible with Microsoft products, the MS-RL license applies; otherwise, the GPLv3 license is used. Under these licenses, if you distribute modified versions of this project's source code to third parties, you may be required to disclose the source code. For more details, please refer to the `LICENSE` and `LICENSE_MSRL` files.
## Known use cases
## Caution
This repository contains information on accessing Windows APIs and functions in the JavaScript runtime, along with recent case studies. While this can provide a flexible development environment for anyone, it can also be misused for malicious purposes. Please be aware that using this project to create abuse tools, such as for DoS attacks, may result in legal consequences in your country. We encourage you to use this project only for creating web technology-based applications, like Electron, or legally permitted testing tools.
## Known Use Cases
WelsonJS is typically used for the following purposes:
* Testing web accessibility and compliance, including adherence to W3C standards (WEB-ARIA, WCAG), national laws (ADA/DDA, GDPR), and other relevant regulations.
* Exploring vulnerabilities of equipment within the local network.
* Improving the availability of VPN or Proxy clients.
* Building automation, CD/CI (Continuous Integration/Continuous Delivery), DevOps, and SecOps.
* Asset evaluation (e.g. Get a purchase history from online shopping and delivery websites)
* Online video streaming quality testing and improvement.
* Testing web accessibility and compliance, including adherence to W3C standards (WEB-ARIA, WCAG), national laws (ADA/DDA, GDPR), and other relevant regulations.
* Exploring vulnerabilities of equipment within the local network.
* Improving the availability of VPN or proxy clients.
* Building automation, CI/CD (Continuous Integration/Continuous Delivery), DevOps, and SecOps.
* Asset evaluation (e.g., obtaining purchase history from online shopping and delivery websites).
* Online video streaming quality testing and improvement.
* Office automation and integration with LLM-based AI (e.g., ChatGPT) services.
## Notes
1. If you plan to use WelsonJS for a purpose other than those mentioned above, please contact us beforehand.
2. If you are looking for ways to use WelsonJS more efficiently, referencing the [LOLBAS (Living Off The Land Binaries and Scripts)](https://lolbas-project.github.io/) list can be helpful.
1. If you plan to use WelsonJS for a purpose other than those mentioned above, please contact us beforehand.
2. If you are looking for ways to use WelsonJS more efficiently, referencing the [LOLBAS (Living Off The Land Binaries and Scripts)](https://lolbas-project.github.io/) list can be helpful.
## Guidelines
### For the use of online shopping and delivery websites
We are aware of cases where WelsonJS has been used for asset valuation to access websites of online shopping or delivery companies. This is a good use case, but there have been reports of website downtime caused by excessive concurrent requests. Please exercise caution and avoid excessive simultaneous executions.
### Use of Online Shopping and Delivery Websites
We are aware of cases where WelsonJS has been used to access the websites of online shopping or delivery companies for asset valuation. This is a good use case, but there have been reports of website downtime caused by excessive concurrent requests. Please exercise caution and avoid excessive simultaneous executions.
### For the use of online video streaming quality testing and improvement
We are aware of cases where WelsonJS is used for the purpose of video streaming quality testing and improvement. It should be used solely for expert-level streaming quality testing, often referred to by terms like 4K, 8K, HD, FHD, UHD, 720p, 1080p, etc. For such purposes, it is recommended to use videos provided by television manufacturers (e.g., LG, Samsung) or graphics card manufacturers (e.g., NVIDIA, AMD) specifically for testing purposes. It is essential to avoid using videos that contain content not legally permitted in the region. The WelsonJS developers and maintainers take no responsibility for the use of videos containing illegal content.
### Use for Online Video Streaming Quality Testing and Improvement
We are aware of cases where WelsonJS is used for video streaming quality testing and improvement. It should be used solely for expert-level streaming quality testing, often referred to by terms like 4K, 8K, HD, FHD, UHD, 720p, 1080p, etc. For such purposes, it is recommended to use videos provided by television manufacturers (e.g., LG, Samsung) or graphics card manufacturers (e.g., NVIDIA, AMD) specifically for testing purposes. It is essential to avoid using videos that contain content not legally permitted in your region. The WelsonJS developers and maintainers take no responsibility for the use of videos containing illegal content.
### For the use of security testing
### Use for Scientific Research Institutes
WelsonJS is designed for flexible industrial facility control (a.k.a. Industrial Scripting) in environments where modifying compiled binaries is restricted. Parts or all of this project's source code may be found in use within scientific research institutes. In such cases, appropriate safety measures tailored to the specific application area may be required. If support is needed for these applications, please do not hesitate to contact us.
### Use for Security Testing
We are aware of instances where WelsonJS has been used by legitimate cybersecurity firms to discover and test vulnerabilities (such as credential stuffing) in IoT devices. If you intend to use WelsonJS as a security testing tool, it should be done in a controlled environment that complies with legal regulations.
### For the use of cloud monitoring
WelsonJS is a project initiated by a cloud service provider in response to a request to develop a lightweight software (e.g., agent) for collecting metrics on Windows systems. While using WelsonJS for this purpose is desirable, ensuring security in the server-client communication is entirely the responsibility of the user.
### Use for Cloud Monitoring
WelsonJS is a project inspired by the requirements of a cloud service provider to develop lightweight software (e.g., agents) for collecting metrics on Windows systems. While using WelsonJS for this purpose is desirable, ensuring security in the server-client communication is entirely the responsibility of the user.
## Alternative names
This program is also known by the following name. This name is used solely for the purpose of identifying the work and does not impact the license:
- "A0562"(2023) (2023 Open-source Development Contest, NIPA National IT Industry Promotion Agency, Republic of Korea)
- "C-2021-000237"(2021) (Copyright Registration Online System, Korea Copyright Commission, Republic of Korea)
- "Codename Macadamia"(2020) (Heavy industry specialized CSP in the Republic of Korea)
## Alternative Names
This program is also known by the following names. These names are used solely for the purpose of identifying the work and do not impact the license:
* DOI [10.5281/zenodo.11382384](https://zenodo.org/doi/10.5281/zenodo.11382384)(2024) (CERN/OpenAIRE Zenodo)
* ["284757291"](https://ics.catswords.net/1494315-Certificate%2BSoR-284757291.pdf)(2024) (Registered with the [UK Copyright Service](https://copyrightservice.co.uk/))
* ["A0562"](https://www.oss.kr/dev_competition_activities/show/544723e6-850a-4956-9194-79640420c19a)(2023) (2023 Open-source Development Contest, NIPA National IT Industry Promotion Agency<sup>(정보통신산업진흥원)</sup>, Republic of Korea)
* ["2025-02-08-1952"](https://ics.catswords.net/20250410092300005.pdf)(2025) (Technical Data Bailment System (Technology Escrow), "Korea Foundation for Cooperation of Large & Small Business, Rural Affairs"<sup>(대·중소기업·농어업협력재단)</sup>, Republic of Korea)
* "C-2021-000237"(2021) (Copyright Registration Online System, Korea Copyright Commission<sup>(한국저작권위원회)</sup>, Republic of Korea)
* "Codename Macadamia"(2020) (Heavy industry specialized CSP in the Republic of Korea)
## Report abuse
If you discover any instances of this project being misused, please report them.
* [GitHub Security Advisories](https://github.com/gnh1201/welsonjs/security)
* [abuse@catswords.net](mailto:abuse@catswords.net)
* abuse@catswords.net
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
## Join the community
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join)
* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS #welsonjs on Discord (discord.gg)](https://discord.gg/XKG5CjtXEj)
## Special channels
* [A paid consultation channel (m.expert.naver.com)](https://m.expert.naver.com/mobile/expert/product/detail?storeId=100051156&productId=100144540) is available for Korean<sup>(한국어)</sup> region.
* [Join the private operations channel (forms.gle)](https://forms.gle/ZKAAaGTiGamksHoo8) is available for all regions.

Binary file not shown.

View File

@ -0,0 +1,261 @@
namespace WelsonJS.Launcher
{
partial class EnvForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.gbUserDefinedVariables = new System.Windows.Forms.GroupBox();
this.lvUserDefinedVariables = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.gbUpdateUserDefinedVariable = new System.Windows.Forms.GroupBox();
this.checkDeleteVariable = new System.Windows.Forms.CheckBox();
this.btnOk = new System.Windows.Forms.Button();
this.btnOpenFile = new System.Windows.Forms.Button();
this.btnOpenDirectory = new System.Windows.Forms.Button();
this.textSetValue = new System.Windows.Forms.TextBox();
this.textSetName = new System.Windows.Forms.TextBox();
this.labelSetValue = new System.Windows.Forms.Label();
this.labelSetName = new System.Windows.Forms.Label();
this.gbImportAndExport = new System.Windows.Forms.GroupBox();
this.btnExport = new System.Windows.Forms.Button();
this.btnImport = new System.Windows.Forms.Button();
this.gbUserDefinedVariables.SuspendLayout();
this.gbUpdateUserDefinedVariable.SuspendLayout();
this.gbImportAndExport.SuspendLayout();
this.SuspendLayout();
//
// gbUserDefinedVariables
//
this.gbUserDefinedVariables.Controls.Add(this.lvUserDefinedVariables);
this.gbUserDefinedVariables.Location = new System.Drawing.Point(12, 12);
this.gbUserDefinedVariables.Name = "gbUserDefinedVariables";
this.gbUserDefinedVariables.Size = new System.Drawing.Size(419, 170);
this.gbUserDefinedVariables.TabIndex = 0;
this.gbUserDefinedVariables.TabStop = false;
this.gbUserDefinedVariables.Text = "User-defined variables";
//
// lvUserDefinedVariables
//
this.lvUserDefinedVariables.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2});
this.lvUserDefinedVariables.HideSelection = false;
this.lvUserDefinedVariables.Location = new System.Drawing.Point(16, 26);
this.lvUserDefinedVariables.Name = "lvUserDefinedVariables";
this.lvUserDefinedVariables.Size = new System.Drawing.Size(386, 129);
this.lvUserDefinedVariables.TabIndex = 0;
this.lvUserDefinedVariables.UseCompatibleStateImageBehavior = false;
this.lvUserDefinedVariables.SelectedIndexChanged += new System.EventHandler(this.lvUserDefinedVariables_SelectedIndexChanged);
//
// columnHeader1
//
this.columnHeader1.Text = "Name";
//
// columnHeader2
//
this.columnHeader2.Text = "Value";
//
// gbUpdateUserDefinedVariable
//
this.gbUpdateUserDefinedVariable.Controls.Add(this.checkDeleteVariable);
this.gbUpdateUserDefinedVariable.Controls.Add(this.btnOk);
this.gbUpdateUserDefinedVariable.Controls.Add(this.btnOpenFile);
this.gbUpdateUserDefinedVariable.Controls.Add(this.btnOpenDirectory);
this.gbUpdateUserDefinedVariable.Controls.Add(this.textSetValue);
this.gbUpdateUserDefinedVariable.Controls.Add(this.textSetName);
this.gbUpdateUserDefinedVariable.Controls.Add(this.labelSetValue);
this.gbUpdateUserDefinedVariable.Controls.Add(this.labelSetName);
this.gbUpdateUserDefinedVariable.Location = new System.Drawing.Point(12, 188);
this.gbUpdateUserDefinedVariable.Name = "gbUpdateUserDefinedVariable";
this.gbUpdateUserDefinedVariable.Size = new System.Drawing.Size(419, 229);
this.gbUpdateUserDefinedVariable.TabIndex = 1;
this.gbUpdateUserDefinedVariable.TabStop = false;
this.gbUpdateUserDefinedVariable.Text = "Update the user-defined variable";
//
// checkDeleteVariable
//
this.checkDeleteVariable.AutoSize = true;
this.checkDeleteVariable.Location = new System.Drawing.Point(31, 88);
this.checkDeleteVariable.Name = "checkDeleteVariable";
this.checkDeleteVariable.Size = new System.Drawing.Size(131, 16);
this.checkDeleteVariable.TabIndex = 7;
this.checkDeleteVariable.Text = "Delete this variable";
this.checkDeleteVariable.UseVisualStyleBackColor = true;
//
// btnOk
//
this.btnOk.Image = global::WelsonJS.Launcher.Properties.Resources.icon_check_32;
this.btnOk.Location = new System.Drawing.Point(303, 123);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(86, 86);
this.btnOk.TabIndex = 6;
this.btnOk.Text = "Ok";
this.btnOk.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
//
// btnOpenFile
//
this.btnOpenFile.Image = global::WelsonJS.Launcher.Properties.Resources.icon_file_32;
this.btnOpenFile.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnOpenFile.Location = new System.Drawing.Point(31, 169);
this.btnOpenFile.Name = "btnOpenFile";
this.btnOpenFile.Padding = new System.Windows.Forms.Padding(11, 0, 0, 0);
this.btnOpenFile.Size = new System.Drawing.Size(201, 40);
this.btnOpenFile.TabIndex = 5;
this.btnOpenFile.Text = "Open the file...";
this.btnOpenFile.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnOpenFile.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnOpenFile.UseVisualStyleBackColor = true;
this.btnOpenFile.Click += new System.EventHandler(this.btnOpenFile_Click);
//
// btnOpenDirectory
//
this.btnOpenDirectory.Image = global::WelsonJS.Launcher.Properties.Resources.icon_directory_32;
this.btnOpenDirectory.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnOpenDirectory.Location = new System.Drawing.Point(31, 123);
this.btnOpenDirectory.Name = "btnOpenDirectory";
this.btnOpenDirectory.Padding = new System.Windows.Forms.Padding(11, 0, 0, 0);
this.btnOpenDirectory.Size = new System.Drawing.Size(201, 40);
this.btnOpenDirectory.TabIndex = 4;
this.btnOpenDirectory.Text = "Open the directory...";
this.btnOpenDirectory.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnOpenDirectory.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnOpenDirectory.UseVisualStyleBackColor = true;
this.btnOpenDirectory.Click += new System.EventHandler(this.btnOpenDirectory_Click);
//
// textSetValue
//
this.textSetValue.Location = new System.Drawing.Point(98, 55);
this.textSetValue.Name = "textSetValue";
this.textSetValue.Size = new System.Drawing.Size(291, 21);
this.textSetValue.TabIndex = 3;
//
// textSetName
//
this.textSetName.Location = new System.Drawing.Point(98, 28);
this.textSetName.Name = "textSetName";
this.textSetName.Size = new System.Drawing.Size(291, 21);
this.textSetName.TabIndex = 2;
//
// labelSetValue
//
this.labelSetValue.AutoSize = true;
this.labelSetValue.Location = new System.Drawing.Point(29, 59);
this.labelSetValue.Name = "labelSetValue";
this.labelSetValue.Size = new System.Drawing.Size(61, 12);
this.labelSetValue.TabIndex = 1;
this.labelSetValue.Text = "Set value:";
//
// labelSetName
//
this.labelSetName.AutoSize = true;
this.labelSetName.Location = new System.Drawing.Point(29, 31);
this.labelSetName.Name = "labelSetName";
this.labelSetName.Size = new System.Drawing.Size(63, 12);
this.labelSetName.TabIndex = 0;
this.labelSetName.Text = "Set name:";
//
// gbImportAndExport
//
this.gbImportAndExport.Controls.Add(this.btnExport);
this.gbImportAndExport.Controls.Add(this.btnImport);
this.gbImportAndExport.Location = new System.Drawing.Point(12, 423);
this.gbImportAndExport.Name = "gbImportAndExport";
this.gbImportAndExport.Size = new System.Drawing.Size(419, 89);
this.gbImportAndExport.TabIndex = 2;
this.gbImportAndExport.TabStop = false;
this.gbImportAndExport.Text = "Import and export";
//
// btnExport
//
this.btnExport.Image = global::WelsonJS.Launcher.Properties.Resources.icon_export_32;
this.btnExport.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnExport.Location = new System.Drawing.Point(213, 29);
this.btnExport.Name = "btnExport";
this.btnExport.Padding = new System.Windows.Forms.Padding(11, 0, 0, 0);
this.btnExport.Size = new System.Drawing.Size(176, 40);
this.btnExport.TabIndex = 6;
this.btnExport.Text = "Export";
this.btnExport.UseVisualStyleBackColor = true;
this.btnExport.Click += new System.EventHandler(this.btnExport_Click);
//
// btnImport
//
this.btnImport.Image = global::WelsonJS.Launcher.Properties.Resources.icon_import_32;
this.btnImport.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnImport.Location = new System.Drawing.Point(31, 29);
this.btnImport.Name = "btnImport";
this.btnImport.Padding = new System.Windows.Forms.Padding(11, 0, 0, 0);
this.btnImport.Size = new System.Drawing.Size(176, 40);
this.btnImport.TabIndex = 5;
this.btnImport.Text = "Import";
this.btnImport.UseVisualStyleBackColor = true;
this.btnImport.Click += new System.EventHandler(this.btnImport_Click);
//
// EnvForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(447, 529);
this.Controls.Add(this.gbImportAndExport);
this.Controls.Add(this.gbUpdateUserDefinedVariable);
this.Controls.Add(this.gbUserDefinedVariables);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = global::WelsonJS.Launcher.Properties.Resources.favicon;
this.MaximizeBox = false;
this.Name = "EnvForm";
this.Text = "User-defined variables editor";
this.gbUserDefinedVariables.ResumeLayout(false);
this.gbUpdateUserDefinedVariable.ResumeLayout(false);
this.gbUpdateUserDefinedVariable.PerformLayout();
this.gbImportAndExport.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox gbUserDefinedVariables;
private System.Windows.Forms.GroupBox gbUpdateUserDefinedVariable;
private System.Windows.Forms.TextBox textSetValue;
private System.Windows.Forms.TextBox textSetName;
private System.Windows.Forms.Label labelSetValue;
private System.Windows.Forms.Label labelSetName;
private System.Windows.Forms.Button btnOk;
private System.Windows.Forms.Button btnOpenFile;
private System.Windows.Forms.Button btnOpenDirectory;
private System.Windows.Forms.CheckBox checkDeleteVariable;
private System.Windows.Forms.ListView lvUserDefinedVariables;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.GroupBox gbImportAndExport;
private System.Windows.Forms.Button btnImport;
private System.Windows.Forms.Button btnExport;
}
}

View File

@ -0,0 +1,295 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace WelsonJS.Launcher
{
public partial class EnvForm : Form
{
private Dictionary<string, string> userVariables = new Dictionary<string, string>();
private string tempFilePath;
private readonly Encoding defaultEncoding = Encoding.UTF8;
public EnvForm()
{
InitializeComponent();
InitializeListView();
// Set the variable file path
tempFilePath = Path.Combine(Program.GetAppDataPath(), "welsonjs_default.env");
LoadUserVariables(); // Load variables
}
// Initialize ListView
private void InitializeListView()
{
lvUserDefinedVariables.View = View.Details;
lvUserDefinedVariables.FullRowSelect = true;
lvUserDefinedVariables.Columns[0].Width = 150;
lvUserDefinedVariables.Columns[1].Width = 220;
lvUserDefinedVariables.SelectedIndexChanged += lvUserDefinedVariables_SelectedIndexChanged;
}
// Load user-defined variables from the temporary folder in .env format
private void LoadUserVariables()
{
if (File.Exists(tempFilePath))
{
try
{
string fileContent = File.ReadAllText(tempFilePath);
// Split based on new line characters
string[] keyValuePairs = fileContent.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
userVariables = new Dictionary<string, string>();
foreach (string pair in keyValuePairs)
{
// Split by the first occurrence of '='
int indexOfEquals = pair.IndexOf('=');
if (indexOfEquals != -1)
{
string key = pair.Substring(0, indexOfEquals).Trim();
string value = pair.Substring(indexOfEquals + 1).Trim();
// Remove surrounding quotes if present
if (value.StartsWith("\"") && value.EndsWith("\""))
{
value = value.Substring(1, value.Length - 2); // Remove the first and last character
}
// Unescape double quotes in the value
value = value.Replace("\\\"", "\"");
userVariables[key] = value;
}
else
{
MessageBox.Show($"Error parsing line: '{pair}'.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Error loading variable file: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
userVariables = new Dictionary<string, string>();
}
}
else
{
userVariables = new Dictionary<string, string>();
}
UpdateListView();
}
// Update ListView with current variables
private void UpdateListView()
{
lvUserDefinedVariables.Items.Clear();
foreach (var variable in userVariables)
{
var item = new ListViewItem(variable.Key);
item.SubItems.Add(variable.Value);
lvUserDefinedVariables.Items.Add(item);
}
}
// Handle ListView selection change
private void lvUserDefinedVariables_SelectedIndexChanged(object sender, EventArgs e)
{
if (lvUserDefinedVariables.SelectedItems.Count > 0)
{
var selectedItem = lvUserDefinedVariables.SelectedItems[0];
textSetName.Text = selectedItem.Text;
textSetValue.Text = selectedItem.SubItems[1].Text;
checkDeleteVariable.Checked = false;
}
}
// Handle OK button click
private void btnOk_Click(object sender, EventArgs e)
{
var name = textSetName.Text.Trim();
var value = textSetValue.Text.Trim();
if (string.IsNullOrEmpty(name))
{
MessageBox.Show("Please enter a variable name.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (checkDeleteVariable.Checked)
{
if (userVariables.ContainsKey(name))
{
userVariables.Remove(name);
MessageBox.Show("Variable deleted.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Variable not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
userVariables[name] = value;
MessageBox.Show("Variable saved.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
UpdateListView();
SaveUserVariables(); // Save variables
ClearInputFields();
}
// Save user-defined variables to the temporary folder in .env format
private void SaveUserVariables()
{
try
{
List<string> lines = new List<string>();
foreach (var variable in userVariables)
{
// Escape double quotes in the value
string value = variable.Value.Replace("\"", "\\\"");
// Enclose the value in double quotes if it contains spaces
if (value.Contains(" "))
{
value = $"\"{value}\"";
}
// Create the line in the format: KEY=VALUE
string line = $"{variable.Key}={value}";
lines.Add(line);
}
// Write lines to the file
File.WriteAllLines(tempFilePath, lines, defaultEncoding);
}
catch (Exception ex)
{
MessageBox.Show($"Error saving variable file: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// Clear input fields
private void ClearInputFields()
{
textSetName.Clear();
textSetValue.Clear();
checkDeleteVariable.Checked = false;
}
// Handle "Open Directory" button click
private void btnOpenDirectory_Click(object sender, EventArgs e)
{
using (var folderDialog = new FolderBrowserDialog())
{
if (folderDialog.ShowDialog() == DialogResult.OK)
{
textSetValue.Text = folderDialog.SelectedPath;
}
}
}
// Handle "Open File" button click
private void btnOpenFile_Click(object sender, EventArgs e)
{
using (var fileDialog = new OpenFileDialog())
{
if (fileDialog.ShowDialog() == DialogResult.OK)
{
textSetName.Text = Path.GetFileName(fileDialog.FileName);
textSetValue.Text = fileDialog.FileName;
}
}
}
private void btnImport_Click(object sender, EventArgs e)
{
using (var openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "Env files (*.env)|*.env|All files (*.*)|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
// Load variables from the selected file
string filePath = openFileDialog.FileName;
string[] lines = File.ReadAllLines(filePath, defaultEncoding);
foreach (string line in lines)
{
// Skip empty lines
if (string.IsNullOrWhiteSpace(line)) continue;
int indexOfEquals = line.IndexOf('=');
if (indexOfEquals != -1)
{
string key = line.Substring(0, indexOfEquals).Trim();
string value = line.Substring(indexOfEquals + 1).Trim();
// Remove surrounding quotes if present
if (value.StartsWith("\"") && value.EndsWith("\""))
{
value = value.Substring(1, value.Length - 2);
}
// Unescape double quotes in the value
value = value.Replace("\\\"", "\"");
// Update or add the key-value pair
userVariables[key] = value;
}
}
// Save the updated variables to the file
SaveUserVariables();
UpdateListView(); // Refresh the display
}
catch (Exception ex)
{
MessageBox.Show($"Error importing variable file: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void btnExport_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Env files (*.env)|*.env|All files (*.*)|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
// Save the current variables to the selected file
string filePath = saveFileDialog.FileName;
List<string> lines = new List<string>();
foreach (var variable in userVariables)
{
// Escape double quotes in the value
string value = variable.Value.Replace("\"", "\\\"");
// Enclose the value in double quotes if it contains spaces
if (value.Contains(" "))
{
value = $"\"{value}\"";
}
lines.Add($"{variable.Key}={value}");
}
File.WriteAllLines(filePath, lines, defaultEncoding);
}
catch (Exception ex)
{
MessageBox.Show($"Error exporting variable file: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,89 @@
namespace WelsonJS.Launcher
{
partial class GlobalSettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.gbMaxScriptStatements = new System.Windows.Forms.GroupBox();
this.btnOkMaxScriptStatements = new System.Windows.Forms.Button();
this.txtMaxScriptStatements = new System.Windows.Forms.TextBox();
this.gbMaxScriptStatements.SuspendLayout();
this.SuspendLayout();
//
// gbMaxScriptStatements
//
this.gbMaxScriptStatements.Controls.Add(this.btnOkMaxScriptStatements);
this.gbMaxScriptStatements.Controls.Add(this.txtMaxScriptStatements);
this.gbMaxScriptStatements.Location = new System.Drawing.Point(12, 12);
this.gbMaxScriptStatements.Name = "gbMaxScriptStatements";
this.gbMaxScriptStatements.Size = new System.Drawing.Size(290, 67);
this.gbMaxScriptStatements.TabIndex = 0;
this.gbMaxScriptStatements.TabStop = false;
this.gbMaxScriptStatements.Text = "MaxScriptStatements (GUI only)";
//
// btnOkMaxScriptStatements
//
this.btnOkMaxScriptStatements.Location = new System.Drawing.Point(218, 30);
this.btnOkMaxScriptStatements.Name = "btnOkMaxScriptStatements";
this.btnOkMaxScriptStatements.Size = new System.Drawing.Size(57, 21);
this.btnOkMaxScriptStatements.TabIndex = 1;
this.btnOkMaxScriptStatements.Text = "Ok";
this.btnOkMaxScriptStatements.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnOkMaxScriptStatements.UseVisualStyleBackColor = true;
this.btnOkMaxScriptStatements.Click += new System.EventHandler(this.btnOkMaxScriptStatements_Click);
//
// txtMaxScriptStatements
//
this.txtMaxScriptStatements.Location = new System.Drawing.Point(15, 30);
this.txtMaxScriptStatements.Name = "txtMaxScriptStatements";
this.txtMaxScriptStatements.Size = new System.Drawing.Size(197, 21);
this.txtMaxScriptStatements.TabIndex = 1;
//
// GlobalSettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(315, 92);
this.Controls.Add(this.gbMaxScriptStatements);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = global::WelsonJS.Launcher.Properties.Resources.favicon;
this.MaximizeBox = false;
this.Name = "GlobalSettingsForm";
this.Text = "Global settings...";
this.gbMaxScriptStatements.ResumeLayout(false);
this.gbMaxScriptStatements.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox gbMaxScriptStatements;
private System.Windows.Forms.TextBox txtMaxScriptStatements;
private System.Windows.Forms.Button btnOkMaxScriptStatements;
}
}

View File

@ -0,0 +1,56 @@
using Microsoft.Win32;
using System;
using System.Windows.Forms;
namespace WelsonJS.Launcher
{
public partial class GlobalSettingsForm : Form
{
private const string RegistryPath = "Software\\Microsoft\\Internet Explorer\\Styles";
private const string RegistryKey = "MaxScriptStatements";
public GlobalSettingsForm()
{
InitializeComponent();
LoadRegistryValue();
}
private void LoadRegistryValue()
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegistryPath))
{
if (key != null)
{
string value = key.GetValue(RegistryKey)?.ToString();
if (value != null && int.TryParse(value, out int maxStatements))
{
txtMaxScriptStatements.Text = maxStatements.ToString();
}
}
}
}
private void btnOkMaxScriptStatements_Click(object sender, EventArgs e)
{
try
{
if (int.TryParse(txtMaxScriptStatements.Text, out int maxStatements))
{
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(RegistryPath))
{
key.SetValue(RegistryKey, maxStatements, RegistryValueKind.DWord);
}
MessageBox.Show($"MaxScriptStatements setting has been changed to {maxStatements}.", "Confirmation", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Please enter a valid number within the DWORD range.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show($"An error occurred while trying to change the MaxScriptStatements setting: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,25 @@
using System.Net;
using System.Threading.Tasks;
namespace WelsonJS.Launcher
{
/// <summary>
/// Defines a contract for resource tools that can handle specific HTTP requests.
/// </summary>
public interface IResourceTool
{
/// <summary>
/// Determines whether this tool can handle the specified path.
/// </summary>
/// <param name="path">The request path to check.</param>
/// <returns>True if this tool can handle the request; otherwise, false.</returns>
bool CanHandle(string path);
/// <summary>
/// Asynchronously processes the HTTP request for the specified path.
/// </summary>
/// <param name="context">The HTTP listener context containing request and response objects.</param>
/// <param name="path">The request path to handle.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task HandleAsync(HttpListenerContext context, string path);
}
}

View File

@ -0,0 +1,170 @@
namespace WelsonJS.Launcher
{
partial class InstancesForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lvInstances = new System.Windows.Forms.ListView();
this.chInstanceId = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.chFirstDeployTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.btnDelete = new System.Windows.Forms.Button();
this.btnOpenWithExplorer = new System.Windows.Forms.Button();
this.cbInteractiveServiceApp = new System.Windows.Forms.CheckBox();
this.txtUseSpecificScript = new System.Windows.Forms.TextBox();
this.cbUseSpecificScript = new System.Windows.Forms.CheckBox();
this.btnStart = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// lvInstances
//
this.lvInstances.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.chInstanceId,
this.chFirstDeployTime});
this.lvInstances.HideSelection = false;
this.lvInstances.Location = new System.Drawing.Point(8, 8);
this.lvInstances.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.lvInstances.Name = "lvInstances";
this.lvInstances.Size = new System.Drawing.Size(384, 170);
this.lvInstances.TabIndex = 0;
this.lvInstances.UseCompatibleStateImageBehavior = false;
this.lvInstances.View = System.Windows.Forms.View.Details;
//
// chInstanceId
//
this.chInstanceId.Text = "Instance ID";
this.chInstanceId.Width = 220;
//
// chFirstDeployTime
//
this.chFirstDeployTime.Text = "First Deploy Time";
this.chFirstDeployTime.Width = 160;
//
// btnDelete
//
this.btnDelete.Image = global::WelsonJS.Launcher.Properties.Resources.icon_delete_32;
this.btnDelete.Location = new System.Drawing.Point(120, 243);
this.btnDelete.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.btnDelete.Name = "btnDelete";
this.btnDelete.Size = new System.Drawing.Size(105, 40);
this.btnDelete.TabIndex = 2;
this.btnDelete.Text = "Delete";
this.btnDelete.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnDelete.UseVisualStyleBackColor = true;
this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click);
//
// btnOpenWithExplorer
//
this.btnOpenWithExplorer.Image = global::WelsonJS.Launcher.Properties.Resources.icon_directory_32;
this.btnOpenWithExplorer.Location = new System.Drawing.Point(229, 243);
this.btnOpenWithExplorer.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.btnOpenWithExplorer.Name = "btnOpenWithExplorer";
this.btnOpenWithExplorer.Size = new System.Drawing.Size(162, 40);
this.btnOpenWithExplorer.TabIndex = 3;
this.btnOpenWithExplorer.Text = "Open with Explorer";
this.btnOpenWithExplorer.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnOpenWithExplorer.UseVisualStyleBackColor = true;
this.btnOpenWithExplorer.Click += new System.EventHandler(this.btnOpenWithExplorer_Click);
//
// cbInteractiveServiceApp
//
this.cbInteractiveServiceApp.AutoSize = true;
this.cbInteractiveServiceApp.Location = new System.Drawing.Point(10, 215);
this.cbInteractiveServiceApp.Name = "cbInteractiveServiceApp";
this.cbInteractiveServiceApp.Size = new System.Drawing.Size(254, 16);
this.cbInteractiveServiceApp.TabIndex = 9;
this.cbInteractiveServiceApp.Text = "This is an Interactive Service Application";
this.cbInteractiveServiceApp.UseVisualStyleBackColor = true;
//
// txtUseSpecificScript
//
this.txtUseSpecificScript.Enabled = false;
this.txtUseSpecificScript.Location = new System.Drawing.Point(199, 189);
this.txtUseSpecificScript.Name = "txtUseSpecificScript";
this.txtUseSpecificScript.Size = new System.Drawing.Size(110, 21);
this.txtUseSpecificScript.TabIndex = 8;
//
// cbUseSpecificScript
//
this.cbUseSpecificScript.AutoSize = true;
this.cbUseSpecificScript.Location = new System.Drawing.Point(10, 192);
this.cbUseSpecificScript.Name = "cbUseSpecificScript";
this.cbUseSpecificScript.Size = new System.Drawing.Size(184, 16);
this.cbUseSpecificScript.TabIndex = 7;
this.cbUseSpecificScript.Text = "I want to use specific script ";
this.cbUseSpecificScript.UseVisualStyleBackColor = true;
this.cbUseSpecificScript.CheckedChanged += new System.EventHandler(this.cbUseSpecificScript_CheckedChanged);
//
// btnStart
//
this.btnStart.Image = global::WelsonJS.Launcher.Properties.Resources.icon_start_32;
this.btnStart.Location = new System.Drawing.Point(10, 243);
this.btnStart.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(105, 40);
this.btnStart.TabIndex = 1;
this.btnStart.Text = "Start";
this.btnStart.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnStart.UseVisualStyleBackColor = true;
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
//
// InstancesForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(401, 296);
this.Controls.Add(this.btnStart);
this.Controls.Add(this.lvInstances);
this.Controls.Add(this.btnDelete);
this.Controls.Add(this.cbUseSpecificScript);
this.Controls.Add(this.cbInteractiveServiceApp);
this.Controls.Add(this.btnOpenWithExplorer);
this.Controls.Add(this.txtUseSpecificScript);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = global::WelsonJS.Launcher.Properties.Resources.favicon;
this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.MaximizeBox = false;
this.Name = "InstancesForm";
this.Text = "Instances";
this.Load += new System.EventHandler(this.InstancesForm_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ListView lvInstances;
private System.Windows.Forms.Button btnDelete;
private System.Windows.Forms.Button btnOpenWithExplorer;
private System.Windows.Forms.CheckBox cbInteractiveServiceApp;
private System.Windows.Forms.TextBox txtUseSpecificScript;
private System.Windows.Forms.CheckBox cbUseSpecificScript;
private System.Windows.Forms.ColumnHeader chInstanceId;
private System.Windows.Forms.ColumnHeader chFirstDeployTime;
private System.Windows.Forms.Button btnStart;
}
}

View File

@ -0,0 +1,141 @@
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WelsonJS.Launcher
{
public partial class InstancesForm : Form
{
private string entryFileName;
private string scriptName;
private const string timestampFormat = "yyyy-MM-dd HH:mm:ss";
public InstancesForm()
{
InitializeComponent();
entryFileName = "bootstrap.bat";
}
private void InstancesForm_Load(object sender, EventArgs e)
{
lvInstances.Items.Clear();
LoadInstances(Program.GetAppDataPath());
LoadInstances(Path.GetTempPath());
}
private void LoadInstances(string instancesRoot)
{
if (!Directory.Exists(instancesRoot))
return;
foreach (string dir in Directory.GetDirectories(instancesRoot))
{
string timestampFile = Path.Combine(dir, ".welsonjs_first_deploy_time");
string entryScriptFile = Path.Combine(dir, "app.js");
string firstDeployTime = null;
if (File.Exists(timestampFile)
&& DateTime.TryParse(File.ReadAllText(timestampFile).Trim(), out DateTime parsedTimestamp))
{
firstDeployTime = parsedTimestamp.ToString(timestampFormat);
}
else if (File.Exists(entryScriptFile))
{
firstDeployTime = File.GetCreationTime(entryScriptFile).ToString(timestampFormat);
}
if (firstDeployTime != null)
{
lvInstances.Items.Add(new ListViewItem(new[]
{
Path.GetFileName(dir),
firstDeployTime
})
{
Tag = dir
});
}
}
}
private void btnStart_Click(object sender, EventArgs e)
{
if (lvInstances.SelectedItems.Count > 0)
{
scriptName = txtUseSpecificScript.Text;
string instanceId = lvInstances.SelectedItems[0].Text;
string workingDirectory = Program.GetWorkingDirectory(instanceId, true);
Task.Run(() =>
{
try
{
// Run the appliction
Program.RunCommandPrompt(workingDirectory, entryFileName, scriptName, cbUseSpecificScript.Checked, cbInteractiveServiceApp.Checked);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
});
}
else
{
MessageBox.Show("No selected an instance");
}
}
private void btnDelete_Click(object sender, EventArgs e)
{
if (lvInstances.SelectedItems.Count > 0)
{
string instanceId = lvInstances.SelectedItems[0].Text;
string workingDirectory = Program.GetWorkingDirectory(instanceId, false);
if (!Directory.Exists(workingDirectory))
{
workingDirectory = Path.Combine(Path.GetTempPath(), instanceId);
}
if (Directory.Exists(workingDirectory))
{
Directory.Delete(workingDirectory, true);
lvInstances.Items.Clear();
LoadInstances(Program.GetAppDataPath());
LoadInstances(Path.GetTempPath());
}
}
else
{
MessageBox.Show("No selected an instance");
}
}
private void btnOpenWithExplorer_Click(object sender, EventArgs e)
{
if (lvInstances.SelectedItems.Count > 0)
{
string instanceId = lvInstances.SelectedItems[0].Text;
string workingDirectory = Program.GetWorkingDirectory(instanceId, true);
if (Directory.Exists(workingDirectory))
{
System.Diagnostics.Process.Start("explorer", workingDirectory);
}
}
else
{
MessageBox.Show("No selected an instance");
}
}
private void cbUseSpecificScript_CheckedChanged(object sender, EventArgs e)
{
txtUseSpecificScript.Enabled = cbUseSpecificScript.Checked;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,279 @@
namespace WelsonJS.Launcher
{
partial class MainForm
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.btnRunFromZipFile = new System.Windows.Forms.Button();
this.btnRunFromExternalLink = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
this.cbUseSpecificScript = new System.Windows.Forms.CheckBox();
this.txtUseSpecificScript = new System.Windows.Forms.TextBox();
this.cbInteractiveServiceApp = new System.Windows.Forms.CheckBox();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.userdefinedVariablesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.instancesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.runAsAdministratorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.globalSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.startCodeEditorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openCopilotToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.openLauncherToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openCodeEditorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout();
this.contextMenuStrip1.SuspendLayout();
this.SuspendLayout();
//
// btnRunFromZipFile
//
this.btnRunFromZipFile.Image = global::WelsonJS.Launcher.Properties.Resources.icon_zip_128;
this.btnRunFromZipFile.Location = new System.Drawing.Point(24, 67);
this.btnRunFromZipFile.Name = "btnRunFromZipFile";
this.btnRunFromZipFile.Size = new System.Drawing.Size(200, 200);
this.btnRunFromZipFile.TabIndex = 0;
this.btnRunFromZipFile.Text = "From ZIP file...";
this.btnRunFromZipFile.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
this.btnRunFromZipFile.UseVisualStyleBackColor = true;
this.btnRunFromZipFile.Click += new System.EventHandler(this.btnRunFromZipFile_Click);
//
// btnRunFromExternalLink
//
this.btnRunFromExternalLink.Image = global::WelsonJS.Launcher.Properties.Resources.icon_link_128;
this.btnRunFromExternalLink.Location = new System.Drawing.Point(230, 67);
this.btnRunFromExternalLink.Name = "btnRunFromExternalLink";
this.btnRunFromExternalLink.Size = new System.Drawing.Size(200, 200);
this.btnRunFromExternalLink.TabIndex = 1;
this.btnRunFromExternalLink.Text = "From external link...";
this.btnRunFromExternalLink.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
this.btnRunFromExternalLink.UseVisualStyleBackColor = true;
this.btnRunFromExternalLink.Click += new System.EventHandler(this.btnRunFromExternalLink_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(24, 41);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(312, 12);
this.label1.TabIndex = 2;
this.label1.Text = "Choose the location of WelsonJS application package.";
//
// linkLabel1
//
this.linkLabel1.AutoSize = true;
this.linkLabel1.Location = new System.Drawing.Point(24, 345);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(219, 12);
this.linkLabel1.TabIndex = 3;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "https://github.com/gnh1201/welsonjs";
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
//
// cbUseSpecificScript
//
this.cbUseSpecificScript.AutoSize = true;
this.cbUseSpecificScript.Location = new System.Drawing.Point(26, 281);
this.cbUseSpecificScript.Name = "cbUseSpecificScript";
this.cbUseSpecificScript.Size = new System.Drawing.Size(184, 16);
this.cbUseSpecificScript.TabIndex = 4;
this.cbUseSpecificScript.Text = "I want to use specific script ";
this.cbUseSpecificScript.UseVisualStyleBackColor = true;
this.cbUseSpecificScript.CheckedChanged += new System.EventHandler(this.cbUseSpecificScript_CheckedChanged);
//
// txtUseSpecificScript
//
this.txtUseSpecificScript.Enabled = false;
this.txtUseSpecificScript.Location = new System.Drawing.Point(214, 278);
this.txtUseSpecificScript.Name = "txtUseSpecificScript";
this.txtUseSpecificScript.Size = new System.Drawing.Size(110, 21);
this.txtUseSpecificScript.TabIndex = 5;
//
// cbInteractiveServiceApp
//
this.cbInteractiveServiceApp.AutoSize = true;
this.cbInteractiveServiceApp.Location = new System.Drawing.Point(26, 305);
this.cbInteractiveServiceApp.Name = "cbInteractiveServiceApp";
this.cbInteractiveServiceApp.Size = new System.Drawing.Size(254, 16);
this.cbInteractiveServiceApp.TabIndex = 6;
this.cbInteractiveServiceApp.Text = "This is an Interactive Service Application";
this.cbInteractiveServiceApp.UseVisualStyleBackColor = true;
//
// menuStrip1
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.settingsToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(461, 24);
this.menuStrip1.TabIndex = 7;
this.menuStrip1.Text = "menuStrip1";
//
// settingsToolStripMenuItem
//
this.settingsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.userdefinedVariablesToolStripMenuItem,
this.instancesToolStripMenuItem,
this.runAsAdministratorToolStripMenuItem,
this.globalSettingsToolStripMenuItem,
this.startCodeEditorToolStripMenuItem,
this.openCopilotToolStripMenuItem});
this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
this.settingsToolStripMenuItem.Size = new System.Drawing.Size(62, 20);
this.settingsToolStripMenuItem.Text = "Settings";
//
// userdefinedVariablesToolStripMenuItem
//
this.userdefinedVariablesToolStripMenuItem.Name = "userdefinedVariablesToolStripMenuItem";
this.userdefinedVariablesToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
this.userdefinedVariablesToolStripMenuItem.Text = "User-defined variables";
this.userdefinedVariablesToolStripMenuItem.Click += new System.EventHandler(this.userdefinedVariablesToolStripMenuItem_Click);
//
// instancesToolStripMenuItem
//
this.instancesToolStripMenuItem.Name = "instancesToolStripMenuItem";
this.instancesToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
this.instancesToolStripMenuItem.Text = "Instances";
this.instancesToolStripMenuItem.Click += new System.EventHandler(this.instancesToolStripMenuItem_Click);
//
// runAsAdministratorToolStripMenuItem
//
this.runAsAdministratorToolStripMenuItem.Name = "runAsAdministratorToolStripMenuItem";
this.runAsAdministratorToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
this.runAsAdministratorToolStripMenuItem.Text = "Run as Administrator...";
this.runAsAdministratorToolStripMenuItem.Click += new System.EventHandler(this.runAsAdministratorToolStripMenuItem_Click);
//
// globalSettingsToolStripMenuItem
//
this.globalSettingsToolStripMenuItem.Name = "globalSettingsToolStripMenuItem";
this.globalSettingsToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
this.globalSettingsToolStripMenuItem.Text = "Global settings...";
this.globalSettingsToolStripMenuItem.Click += new System.EventHandler(this.globalSettingsToolStripMenuItem_Click);
//
// startCodeEditorToolStripMenuItem
//
this.startCodeEditorToolStripMenuItem.Name = "startCodeEditorToolStripMenuItem";
this.startCodeEditorToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
this.startCodeEditorToolStripMenuItem.Text = "Start the code editor...";
this.startCodeEditorToolStripMenuItem.Click += new System.EventHandler(this.startCodeEditorToolStripMenuItem_Click);
//
// openCopilotToolStripMenuItem
//
this.openCopilotToolStripMenuItem.Name = "openCopilotToolStripMenuItem";
this.openCopilotToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
this.openCopilotToolStripMenuItem.Text = "Open the Copilot...";
this.openCopilotToolStripMenuItem.Click += new System.EventHandler(this.openCopilotToolStripMenuItem_Click);
//
// notifyIcon1
//
this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
this.notifyIcon1.Icon = global::WelsonJS.Launcher.Properties.Resources.favicon;
this.notifyIcon1.Text = "WelsonJS Launcher";
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openLauncherToolStripMenuItem,
this.openCodeEditorToolStripMenuItem,
this.exitToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(199, 70);
//
// openLauncherToolStripMenuItem
//
this.openLauncherToolStripMenuItem.Name = "openLauncherToolStripMenuItem";
this.openLauncherToolStripMenuItem.Size = new System.Drawing.Size(198, 22);
this.openLauncherToolStripMenuItem.Text = "Open the launcher...";
//
// openCodeEditorToolStripMenuItem
//
this.openCodeEditorToolStripMenuItem.Name = "openCodeEditorToolStripMenuItem";
this.openCodeEditorToolStripMenuItem.Size = new System.Drawing.Size(198, 22);
this.openCodeEditorToolStripMenuItem.Text = "Open the code editor...";
this.openCodeEditorToolStripMenuItem.Click += new System.EventHandler(this.openCodeEditorToolStripMenuItem_Click);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(198, 22);
this.exitToolStripMenuItem.Text = "Exit";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(461, 382);
this.Controls.Add(this.cbInteractiveServiceApp);
this.Controls.Add(this.txtUseSpecificScript);
this.Controls.Add(this.cbUseSpecificScript);
this.Controls.Add(this.linkLabel1);
this.Controls.Add(this.label1);
this.Controls.Add(this.btnRunFromExternalLink);
this.Controls.Add(this.btnRunFromZipFile);
this.Controls.Add(this.menuStrip1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = global::WelsonJS.Launcher.Properties.Resources.favicon;
this.MainMenuStrip = this.menuStrip1;
this.MaximizeBox = false;
this.Name = "MainForm";
this.Text = "WelsonJS Application Launcher";
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.contextMenuStrip1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnRunFromZipFile;
private System.Windows.Forms.Button btnRunFromExternalLink;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.LinkLabel linkLabel1;
private System.Windows.Forms.CheckBox cbUseSpecificScript;
private System.Windows.Forms.TextBox txtUseSpecificScript;
private System.Windows.Forms.CheckBox cbInteractiveServiceApp;
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem userdefinedVariablesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem instancesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem runAsAdministratorToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem globalSettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem startCodeEditorToolStripMenuItem;
private System.Windows.Forms.NotifyIcon notifyIcon1;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openCodeEditorToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openLauncherToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openCopilotToolStripMenuItem;
}
}

View File

@ -0,0 +1,275 @@
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Security.Principal;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WelsonJS.Launcher
{
public partial class MainForm : Form
{
private string workingDirectory;
private string instanceId;
private string entryFileName;
private string scriptName;
public MainForm()
{
entryFileName = "bootstrap.bat";
InitializeComponent();
if (IsInAdministrator())
{
Text = Text + " (Administrator)";
}
notifyIcon1.DoubleClick += OnShow;
openLauncherToolStripMenuItem.Click += OnShow;
exitToolStripMenuItem.Click += OnExit;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
this.Hide();
this.ShowInTaskbar = false;
notifyIcon1.Visible = true;
}
base.OnFormClosing(e);
}
private void OnShow(object sender, EventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
this.ShowInTaskbar = true;
this.Focus();
notifyIcon1.Visible = false;
}
private void OnExit(object sender, EventArgs e)
{
notifyIcon1.Visible = false;
Application.Exit();
}
private void EnableUI()
{
label1.Text = "Choose the location of WelsonJS application package.";
btnRunFromZipFile.Enabled = true;
btnRunFromExternalLink.Enabled = true;
cbUseSpecificScript.Enabled = true;
cbInteractiveServiceApp.Enabled = true;
if (cbUseSpecificScript.Checked)
{
txtUseSpecificScript.Enabled = true;
}
}
private void DisableUI()
{
label1.Text = "Please wait...";
btnRunFromZipFile.Enabled = false;
btnRunFromExternalLink.Enabled = false;
cbUseSpecificScript.Enabled = false;
cbInteractiveServiceApp.Enabled = false;
txtUseSpecificScript.Enabled = false;
}
private void SafeInvoke(Action action)
{
if (InvokeRequired)
{
Invoke(action);
}
else
{
action();
}
}
private void btnRunFromExternalLink_Click(object sender, EventArgs e)
{
MessageBox.Show("Coming soon...!");
}
private void btnRunFromZipFile_Click(object sender, EventArgs e)
{
using (var openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "zip files (*.zip)|*.zip|All files (*.*)|*.*";
openFileDialog.FilterIndex = 2;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = openFileDialog.FileName;
ExtractAndRun(filePath);
}
}
}
private void ExtractAndRun(string filePath)
{
instanceId = Guid.NewGuid().ToString();
workingDirectory = Program.GetWorkingDirectory(instanceId);
scriptName = txtUseSpecificScript.Text;
Task.Run(() =>
{
try
{
// If exists, delete all
if (Directory.Exists(workingDirectory))
{
Directory.Delete(workingDirectory, true);
}
// try to extact ZIP file
ZipFile.ExtractToDirectory(filePath, workingDirectory);
// record the first deploy time
RecordFirstDeployTime(workingDirectory);
// follow the sub-directory
workingDirectory = Program.GetWorkingDirectory(instanceId, true);
// Run the appliction
Program.RunCommandPrompt(workingDirectory, entryFileName, scriptName, cbUseSpecificScript.Checked, cbInteractiveServiceApp.Checked);
}
catch (Exception ex)
{
SafeInvoke(() =>
{
MessageBox.Show("Error: " + ex.Message);
});
}
// Enable UI
SafeInvoke(() => {
EnableUI();
});
});
DisableUI();
}
private void RecordFirstDeployTime(string directory)
{
try
{
string filePath = Path.Combine(directory, ".welsonjs_first_deploy_time");
string text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
File.WriteAllText(filePath, text);
}
catch (Exception ex)
{
throw new Exception($"Failed to record first deploy time: {ex.Message}");
}
}
private bool IsInAdministrator()
{
try
{
WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return wp.IsInRole(WindowsBuiltInRole.Administrator);
}
catch
{
return false;
}
}
private void cbUseSpecificScript_CheckedChanged(object sender, EventArgs e)
{
txtUseSpecificScript.Enabled = cbUseSpecificScript.Checked;
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Program.OpenWebBrowser(Program.GetAppConfig("RepositoryUrl"));
}
private void userdefinedVariablesToolStripMenuItem_Click(object sender, EventArgs e)
{
(new EnvForm()).Show();
}
private void instancesToolStripMenuItem_Click(object sender, EventArgs e)
{
(new InstancesForm()).Show();
}
private void runAsAdministratorToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!IsInAdministrator())
{
ProcessStartInfo procInfo = new ProcessStartInfo
{
UseShellExecute = true,
FileName = Application.ExecutablePath,
WorkingDirectory = Environment.CurrentDirectory,
Verb = "runas"
};
try
{
Process.Start(procInfo);
Application.Exit();
}
catch (Exception ex)
{
MessageBox.Show("Failed to run as administrator: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show("Already running as Administrator.");
}
}
private void globalSettingsToolStripMenuItem_Click(object sender, EventArgs e)
{
(new GlobalSettingsForm()).Show();
}
private void startCodeEditorToolStripMenuItem_Click(object sender, EventArgs e)
{
Program.StartResourceServer();
if (!Program.resourceServer.IsRunning())
{
Program.resourceServer.Start();
((ToolStripMenuItem)sender).Text = "Open the code editor...";
}
else
{
Program.OpenWebBrowser(Program.resourceServer.GetPrefix());
}
}
private void openCodeEditorToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Program.resourceServer == null)
{
MessageBox.Show("A resource server is not running.");
}
else
{
Program.OpenWebBrowser(Program.resourceServer.GetPrefix());
}
}
private void openCopilotToolStripMenuItem_Click(object sender, EventArgs e)
{
Program.OpenWebBrowser(Program.GetAppConfig("CopilotUrl"));
}
}
}

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="notifyIcon1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>134, 17</value>
</metadata>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>249, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,191 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Configuration;
namespace WelsonJS.Launcher
{
internal static class Program
{
static Mutex mutex;
public static ResourceServer resourceServer;
[STAThread]
static void Main()
{
mutex = new Mutex(true, "WelsonJS.Launcher.Mutex", out bool isMutexNotExists);
if (!isMutexNotExists)
{
MessageBox.Show("WelsonJS Launcher already running.");
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
mutex.ReleaseMutex();
mutex.Dispose();
}
public static void RunCommandPrompt(string workingDirectory, string entryFileName, string scriptName, bool isConsoleApplication = false, bool isInteractiveServiceAapplication = false)
{
if (!isConsoleApplication)
{
if (!File.Exists(Path.Combine(workingDirectory, entryFileName)))
{
throw new Exception("Not Found: " + entryFileName);
}
}
else
{
if (!Directory.EnumerateFiles(workingDirectory, scriptName + ".*").Any())
{
throw new Exception("Not found matches file: " + scriptName);
}
}
Process process = new Process
{
StartInfo = new ProcessStartInfo("cmd")
{
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
Arguments = "/k",
}
};
process.Start();
process.StandardInput.WriteLine("pushd " + workingDirectory);
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
if (isInteractiveServiceAapplication)
{
process.StandardInput.WriteLine($"start cmd /c startInteractiveService.bat");
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
}
else if (!isConsoleApplication)
{
process.StandardInput.WriteLine(entryFileName);
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
}
else
{
process.StandardInput.WriteLine($"start cmd /c cscript app.js {scriptName}");
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
}
process.StandardInput.Close();
process.WaitForExit();
}
public static string GetFinalDirectory(string path)
{
string[] directories = Directory.GetDirectories(path);
while (directories.Length == 1)
{
path = directories[0];
directories = Directory.GetDirectories(path);
}
return path;
}
public static string GetAppDataPath()
{
string path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"WelsonJS"
);
Directory.CreateDirectory(path);
if (!Directory.Exists(path))
{
throw new IOException("Failed to create directory: " + path);
}
return path;
}
public static string GetWorkingDirectory(string instanceId, bool followSubDirectory = false)
{
string workingDirectory = Path.Combine(GetAppDataPath(), instanceId);
if (followSubDirectory)
{
if (!Directory.Exists(workingDirectory))
{
workingDirectory = Path.Combine(Path.GetTempPath(), instanceId);
}
workingDirectory = GetFinalDirectory(workingDirectory);
}
return workingDirectory;
}
public static void StartResourceServer()
{
lock(typeof(Program))
{
if (resourceServer == null)
{
resourceServer = new ResourceServer(GetAppConfig("ResourceServerPrefix"), "editor.html");
}
}
}
public static void OpenWebBrowser(string url)
{
Uri resourceServerUri = new Uri(GetAppConfig("ResourceServerPrefix"));
Uri devToolsUri = new Uri(GetAppConfig("DevToolsPrefix"));
string userDataDir = Path.Combine(GetAppDataPath(), "EdgeUserProfile");
string remoteAllowOrigins = $"{resourceServerUri.Scheme}://{resourceServerUri.Host}:{resourceServerUri.Port}";
int remoteDebuggingPort = devToolsUri.Port;
string[] arguments = {
$"\"{url}\"",
$"--remote-debugging-port={remoteDebuggingPort}",
$"--remote-allow-origins={remoteAllowOrigins}", // for security reason
$"--user-data-dir=\"{userDataDir}\""
};
Process.Start(new ProcessStartInfo
{
FileName = "msedge.exe",
Arguments = string.Join(" ", arguments),
UseShellExecute = true
});
}
public static string GetAppConfig(string key)
{
string value = ConfigurationManager.AppSettings[key];
if (!string.IsNullOrEmpty(value))
{
return value;
}
value = Properties.Resources.ResourceManager.GetString(key);
if (!string.IsNullOrEmpty(value))
{
return value;
}
return null;
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("WelsonJS.Launcher")]
[assembly: AssemblyDescription("Launcher for WelsonJS Application Packages")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Catswords")]
[assembly: AssemblyProduct("WelsonJS")]
[assembly: AssemblyCopyright("Catswords OSS, GPLv3 or Ms-RL")]
[assembly: AssemblyTrademark("WelsonJS")]
[assembly: AssemblyCulture("")]
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
[assembly: ComVisible(false)]
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
[assembly: Guid("4074d413-195c-45e9-9e63-0d07914187b8")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.7.54")]
[assembly: AssemblyFileVersion("0.2.7.54")]

View File

@ -0,0 +1,289 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace WelsonJS.Launcher.Properties {
using System;
/// <summary>
/// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다.
/// </summary>
// 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder
// 클래스에서 자동으로 생성되었습니다.
// 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을
// 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WelsonJS.Launcher.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을
/// 재정의합니다.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// 과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string AzureAiServiceApiKey {
get {
return ResourceManager.GetString("AzureAiServiceApiKey", resourceCulture);
}
}
/// <summary>
/// 2024-05-01-preview과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string AzureAiServiceApiVersion {
get {
return ResourceManager.GetString("AzureAiServiceApiVersion", resourceCulture);
}
}
/// <summary>
/// https://ai-catswords656881030318.services.ai.azure.com/과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string AzureAiServicePrefix {
get {
return ResourceManager.GetString("AzureAiServicePrefix", resourceCulture);
}
}
/// <summary>
/// https://catswords.blob.core.windows.net/welsonjs/blob.config.xml과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string BlobConfigUrl {
get {
return ResourceManager.GetString("BlobConfigUrl", resourceCulture);
}
}
/// <summary>
/// https://catswords.blob.core.windows.net/welsonjs/과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string BlobStoragePrefix {
get {
return ResourceManager.GetString("BlobStoragePrefix", resourceCulture);
}
}
/// <summary>
/// https://copilot.microsoft.com/과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string CopilotUrl {
get {
return ResourceManager.GetString("CopilotUrl", resourceCulture);
}
}
/// <summary>
/// http://localhost:9222/과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string DevToolsPrefix {
get {
return ResourceManager.GetString("DevToolsPrefix", resourceCulture);
}
}
/// <summary>
/// 1.1.1.1과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string DnsServerAddress {
get {
return ResourceManager.GetString("DnsServerAddress", resourceCulture);
}
}
/// <summary>
/// (아이콘)과(와) 유사한 System.Drawing.Icon 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Icon favicon {
get {
object obj = ResourceManager.GetObject("favicon", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// 90과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string HttpClientTimeout {
get {
return ResourceManager.GetString("HttpClientTimeout", resourceCulture);
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_check_32 {
get {
object obj = ResourceManager.GetObject("icon_check_32", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_delete_32 {
get {
object obj = ResourceManager.GetObject("icon_delete_32", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_directory_32 {
get {
object obj = ResourceManager.GetObject("icon_directory_32", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_export_32 {
get {
object obj = ResourceManager.GetObject("icon_export_32", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_file_32 {
get {
object obj = ResourceManager.GetObject("icon_file_32", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_import_32 {
get {
object obj = ResourceManager.GetObject("icon_import_32", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_link_128 {
get {
object obj = ResourceManager.GetObject("icon_link_128", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_start_32 {
get {
object obj = ResourceManager.GetObject("icon_start_32", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap icon_zip_128 {
get {
object obj = ResourceManager.GetObject("icon_zip_128", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// https://github.com/gnh1201/welsonjs과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string RepositoryUrl {
get {
return ResourceManager.GetString("RepositoryUrl", resourceCulture);
}
}
/// <summary>
/// http://localhost:3000/과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string ResourceServerPrefix {
get {
return ResourceManager.GetString("ResourceServerPrefix", resourceCulture);
}
}
/// <summary>
/// 141.101.82.1과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string WhoisClientAddress {
get {
return ResourceManager.GetString("WhoisClientAddress", resourceCulture);
}
}
/// <summary>
/// https://xn--c79as89aj0e29b77z.xn--3e0b707e/kor/whois/whois.jsp과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string WhoisReferrerUrl {
get {
return ResourceManager.GetString("WhoisReferrerUrl", resourceCulture);
}
}
/// <summary>
/// https://xn--c79as89aj0e29b77z.xn--3e0b707e/kor/whois.jsc과(와) 유사한 지역화된 문자열을 찾습니다.
/// </summary>
internal static string WhoisServerUrl {
get {
return ResourceManager.GetString("WhoisServerUrl", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,193 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="icon_link_128" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_link_128.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_zip_128" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_zip_128.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="favicon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\favicon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_directory_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_directory_32.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_file_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_file_32.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_check_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_check_32.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_export_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_export_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_import_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_import_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_delete_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_delete_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_start_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_start_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="CopilotUrl" xml:space="preserve">
<value>https://copilot.microsoft.com/</value>
</data>
<data name="RepositoryUrl" xml:space="preserve">
<value>https://github.com/gnh1201/welsonjs</value>
</data>
<data name="ResourceServerPrefix" xml:space="preserve">
<value>http://localhost:3000/</value>
</data>
<data name="DevToolsPrefix" xml:space="preserve">
<value>http://localhost:9222/</value>
</data>
<data name="AzureAiServiceApiKey" xml:space="preserve">
<value />
</data>
<data name="AzureAiServicePrefix" xml:space="preserve">
<value>https://ai-catswords656881030318.services.ai.azure.com/</value>
</data>
<data name="DnsServerAddress" xml:space="preserve">
<value>1.1.1.1</value>
</data>
<data name="WhoisClientAddress" xml:space="preserve">
<value>141.101.82.1</value>
</data>
<data name="WhoisReferrerUrl" xml:space="preserve">
<value>https://xn--c79as89aj0e29b77z.xn--3e0b707e/kor/whois/whois.jsp</value>
</data>
<data name="WhoisServerUrl" xml:space="preserve">
<value>https://xn--c79as89aj0e29b77z.xn--3e0b707e/kor/whois.jsc</value>
</data>
<data name="BlobStoragePrefix" xml:space="preserve">
<value>https://catswords.blob.core.windows.net/welsonjs/</value>
</data>
<data name="AzureAiServiceApiVersion" xml:space="preserve">
<value>2024-05-01-preview</value>
</data>
<data name="BlobConfigUrl" xml:space="preserve">
<value>https://catswords.blob.core.windows.net/welsonjs/blob.config.xml</value>
</data>
<data name="HttpClientTimeout" xml:space="preserve">
<value>90</value>
</data>
</root>

View File

@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace WelsonJS.Launcher.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -0,0 +1,500 @@
// ResourceServer.cs
// A resource server of WelsonJS Editor (WelsonJS.Launcher)
// Namhyeon Go <abuse@catswords.net>
// https://github.com/gnh1201/welsonjs
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
namespace WelsonJS.Launcher
{
public class ResourceServer
{
private readonly HttpListener _listener;
private CancellationTokenSource _cts;
private Task _serverTask;
private bool _isRunning;
private string _prefix;
private string _resourceName;
private List<IResourceTool> _tools = new List<IResourceTool>();
private static readonly HttpClient _httpClient = new HttpClient();
private static readonly string _defaultMimeType = "application/octet-stream";
private static BlobConfig _blobConfig;
static ResourceServer()
{
// Set timeout
int timeout = int.TryParse(Program.GetAppConfig("HttpClientTimeout"), out timeout) ? timeout : 90;
_httpClient.Timeout = TimeSpan.FromSeconds(timeout);
// Fetch a blob config from Internet
FetchBlobConfig();
}
public ResourceServer(string prefix, string resourceName)
{
_prefix = prefix;
_listener = new HttpListener();
_listener.Prefixes.Add(prefix);
_resourceName = resourceName;
// Add resource tools
_tools.Add(new ResourceTools.Completion(this, _httpClient));
_tools.Add(new ResourceTools.Settings(this, _httpClient));
_tools.Add(new ResourceTools.DevTools(this, _httpClient));
_tools.Add(new ResourceTools.DnsQuery(this, _httpClient));
_tools.Add(new ResourceTools.Tfa(this, _httpClient));
_tools.Add(new ResourceTools.Whois(this, _httpClient));
}
public string GetPrefix()
{
return _prefix;
}
public void Start()
{
if (_isRunning) return;
_isRunning = true;
_cts = new CancellationTokenSource();
_listener.Start();
// Open the web browser
Program.OpenWebBrowser(_prefix);
// Run a task with cancellation token
_serverTask = Task.Run(() => ListenLoop(_cts.Token));
}
public void Stop()
{
_isRunning = false;
_cts.Cancel();
_listener.Stop();
MessageBox.Show("Server stopped.");
}
public bool IsRunning()
{
return _isRunning;
}
private async Task ListenLoop(CancellationToken token)
{
while (!token.IsCancellationRequested && _isRunning)
{
try
{
await ProcessRequest(await _listener.GetContextAsync());
}
catch (Exception ex)
{
if (token.IsCancellationRequested || !_isRunning) break;
MessageBox.Show($"Error: {ex.Message}");
}
}
}
private async Task ProcessRequest(HttpListenerContext context)
{
string path = context.Request.Url.AbsolutePath.TrimStart('/');
// Serve from a resource name
if (String.IsNullOrEmpty(path))
{
ServeResource(context, GetResource(_resourceName), "text/html");
return;
}
// Serve the favicon.ico file
if ("favicon.ico".Equals(path, StringComparison.OrdinalIgnoreCase))
{
ServeResource(context, GetResource("favicon"), "image/x-icon");
return;
}
// Serve from a resource tool
foreach (var tool in _tools)
{
if (tool.CanHandle(path))
{
await tool.HandleAsync(context, path);
return;
}
}
// Serve from the blob server
if (await ServeBlob(context, path)) return;
// Fallback to serve from a resource name
ServeResource(context, GetResource(_resourceName), "text/html");
}
private async Task<bool> ServeBlob(HttpListenerContext context, string path, string prefix = null)
{
byte[] data;
string mimeType;
if (!String.IsNullOrEmpty(prefix))
{
string url = $"{prefix}{path}";
try
{
using (var client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.UserAgent.ParseAdd(context.Request.UserAgent);
HttpResponseMessage response = await client.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
Trace.TraceError($"Failed to serve blob. URL: {url}, Status: {response.StatusCode}");
return false;
}
data = await response.Content.ReadAsByteArrayAsync();
mimeType = response.Content.Headers.ContentType?.MediaType ?? _defaultMimeType;
ServeResource(context, data, mimeType);
_ = TrySaveCachedBlob(path, data, mimeType);
return true;
}
}
catch (Exception ex)
{
Trace.TraceError($"Failed to serve blob. URL: {url}, Exception: {ex.Message}");
return false;
}
}
else
{
// use the cached data
if (TryGetCachedBlob(path, out mimeType, true))
{
if (TryGetCachedBlob(path, out data))
{
if (String.IsNullOrEmpty(mimeType))
{
mimeType = _defaultMimeType;
}
ServeResource(context, data, mimeType);
return true;
}
}
// use a blob source
if (await TryServeFromBlob(context, path))
{
return true;
}
}
return false;
}
private async Task<bool> TryServeFromBlob(HttpListenerContext context, string path)
{
if (_blobConfig != null)
{
foreach (var route in _blobConfig.Routes)
{
foreach (var (regex, index) in route.RegexConditions.Select((r, i) => (r, i)))
{
if (!regex.Compiled.IsMatch(path)) continue;
var match = (index < route.Matches.Count) ? route.Matches[index] : route.Matches.First();
var _path = route.StripPrefix ? path.Substring(match.Length) : path;
foreach (var prefixUrl in route.PrefixUrls)
{
if (await ServeBlob(context, _path, prefixUrl))
return true;
}
}
}
}
// fallback
string prefix = Program.GetAppConfig("BlobStoragePrefix");
if (await ServeBlob(context, path, prefix))
return true;
return false;
}
private string GetCachedBlobPath(string path)
{
// Get a hash from the path
string hashedPath;
using (MD5 md5 = MD5.Create())
{
byte[] bHashedPath = md5.ComputeHash(Encoding.UTF8.GetBytes(path));
hashedPath = BitConverter.ToString(bHashedPath).Replace("-", "").ToLowerInvariant();
}
// Get a sub-directory paths from the hashed path
string[] subDirectoryPaths = new string[] {
hashedPath.Substring(0, 2),
hashedPath.Substring(2, 2),
hashedPath.Substring(4, 2)
};
// Return the cache path
return Path.Combine(Program.GetAppDataPath(), "BlobCache", String.Join("\\", subDirectoryPaths), hashedPath);
}
private bool TryGetCachedBlob(string path, out byte[] data, bool isMetadata = false)
{
string cachePath = GetCachedBlobPath(path);
if (isMetadata)
{
cachePath = $"{cachePath}.meta";
}
try
{
if (File.Exists(cachePath))
{
data = File.ReadAllBytes(cachePath);
return true;
}
}
catch (Exception ex)
{
Trace.TraceError($"Cache Read Error: {ex.Message}");
}
data = null;
return false;
}
private bool TryGetCachedBlob(string path, out string data, bool isMetadata = false)
{
byte[] bData;
if (TryGetCachedBlob(path, out bData, isMetadata))
{
data = Encoding.UTF8.GetString(bData);
return true;
}
data = null;
return false;
}
private async Task<bool> TrySaveCachedBlob(string path, byte[] data, string mimeType)
{
await Task.Delay(0);
try
{
string cachePath = GetCachedBlobPath(path);
string cacheDirectory = Path.GetDirectoryName(cachePath);
// Is exists the cached blob directory
if (!Directory.Exists(cacheDirectory))
{
Directory.CreateDirectory(cacheDirectory);
}
// Save the cache
File.WriteAllBytes(cachePath, data);
// Save the cache meta
File.WriteAllBytes($"{cachePath}.meta", Encoding.UTF8.GetBytes(mimeType));
return true;
}
catch (Exception ex)
{
Trace.TraceError($"Error: {ex.Message}");
return false;
}
}
public void ServeResource(HttpListenerContext context)
{
ServeResource(context, "<error>Not Found</error>", "application/xml", 404);
}
public void ServeResource(HttpListenerContext context, byte[] data, string mimeType = "text/html", int statusCode = 200)
{
string xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
if (data == null)
{
data = Encoding.UTF8.GetBytes(xmlHeader + "\r\n<error>Could not find the resource.</error>");
mimeType = "application/xml";
statusCode = 404;
}
context.Response.StatusCode = statusCode;
context.Response.ContentType = mimeType;
context.Response.ContentLength64 = data.Length;
using (Stream outputStream = context.Response.OutputStream)
{
outputStream.Write(data, 0, data.Length);
}
}
public void ServeResource(HttpListenerContext context, string data, string mimeType = "text/html", int statusCode = 200)
{
string xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
if (data == null)
{
data = xmlHeader + "\r\n<error>Could not find the resource.</error>";
mimeType = "application/xml";
statusCode = 404;
}
else if (mimeType == "application/xml" && !data.StartsWith("<?xml"))
{
data = xmlHeader + "\r\n" + data;
}
ServeResource(context, Encoding.UTF8.GetBytes(data), mimeType, statusCode);
}
private byte[] GetResource(string resourceName)
{
// Try to fetch embedded resource.
byte[] data = GetEmbeddedResource(typeof(Program).Namespace + "." + resourceName);
if (data != null) return data;
// Fallback: Try to fetch resource from ResourceManager.
return GetResourceFromManager(resourceName);
}
private byte[] GetEmbeddedResource(string fullResourceName)
{
Assembly assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(fullResourceName))
{
if (stream != null)
{
using (MemoryStream memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}
return null;
}
private byte[] GetResourceFromManager(string resourceName)
{
object resourceObject = Properties.Resources.ResourceManager.GetObject(resourceName);
switch (resourceObject)
{
case byte[] resourceBytes:
return resourceBytes;
case System.Drawing.Icon icon:
return ConvertIconToBytes(icon);
default:
return null;
}
}
private byte[] ConvertIconToBytes(System.Drawing.Icon icon)
{
using (MemoryStream memoryStream = new MemoryStream())
{
icon.Save(memoryStream);
return memoryStream.ToArray();
}
}
private static async void FetchBlobConfig()
{
try
{
string url = Program.GetAppConfig("BlobConfigUrl");
var response = await _httpClient.GetStreamAsync(url);
var serializer = new XmlSerializer(typeof(BlobConfig));
using (var reader = new StreamReader(response))
{
_blobConfig = (BlobConfig)serializer.Deserialize(reader);
}
_blobConfig?.Compile();
}
catch (Exception ex)
{
Trace.TraceError($"Failed to fetch a blob config. Exception: {ex.Message}");
}
}
}
[XmlRoot("blobConfig")]
public class BlobConfig
{
[XmlArray("routes")]
[XmlArrayItem("route")]
public List<BlobRoute> Routes { get; set; } = new List<BlobRoute>();
public void Compile()
{
foreach (var route in Routes)
{
if (route.Matches == null) continue;
route.RegexConditions = new List<RegexCondition>();
foreach (var match in route.Matches)
{
route.RegexConditions.Add(new RegexCondition
{
Pattern = match,
Compiled = new Regex(
match.StartsWith("^") ? match : "^" + Regex.Escape(match),
RegexOptions.Compiled)
});
}
}
}
}
public class BlobRoute
{
[XmlArray("matches")]
[XmlArrayItem("match")]
public List<string> Matches { get; set; }
[XmlArray("prefixUrls")]
[XmlArrayItem("url")]
public List<string> PrefixUrls { get; set; }
[XmlAttribute("stripPrefix")]
public bool StripPrefix { get; set; }
[XmlIgnore]
public List<RegexCondition> RegexConditions { get; set; }
}
public class RegexCondition
{
[XmlIgnore]
public string Pattern { get; set; }
[XmlIgnore]
public Regex Compiled { get; set; }
}
}

View File

@ -0,0 +1,214 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Net.Http;
namespace WelsonJS.Launcher.ResourceTools
{
public class Completion : IResourceTool
{
private readonly ResourceServer Server;
private readonly HttpClient _httpClient;
private const string Prefix = "completion/";
private List<string> Executables = new List<string>();
public Completion(ResourceServer server, HttpClient httpClient)
{
Server = server;
_httpClient = httpClient;
new Task(() =>
{
Executables.AddRange(GetInstalledSoftwareExecutables());
Executables.AddRange(GetExecutablesFromPath());
Executables.AddRange(GetExecutablesFromNetFx());
}).Start();
}
public bool CanHandle(string path)
{
return path.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase);
}
public async Task HandleAsync(HttpListenerContext context, string path)
{
await Task.Delay(0);
string word = path.Substring(Prefix.Length);
try
{
CompletionItem[] completionItems = Executables
.Where(exec => exec.IndexOf(word, 0, StringComparison.OrdinalIgnoreCase) > -1)
.Take(100) // Limit the number of results
.Select(exec => new CompletionItem
{
Label = Path.GetFileName(exec),
Kind = "Text",
Documentation = $"An executable file: {exec}",
InsertText = exec
})
.ToArray();
XElement response = new XElement("suggestions",
completionItems.Select(item => new XElement("item",
new XElement("label", item.Label),
new XElement("kind", item.Kind),
new XElement("documentation", item.Documentation),
new XElement("insertText", item.InsertText)
))
);
Server.ServeResource(context, response.ToString(), "application/xml");
}
catch (Exception ex)
{
Server.ServeResource(context, $"<error>Failed to process completion request. {ex.Message}</error>", "application/xml", 500);
}
}
private List<string> GetInstalledSoftwareExecutables()
{
List<string> executables = new List<string>();
string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey))
{
if (key != null)
{
foreach (string subKeyName in key.GetSubKeyNames())
{
using (RegistryKey subKey = key.OpenSubKey(subKeyName))
{
string installLocation = subKey?.GetValue("InstallLocation") as string;
string uninstallString = subKey?.GetValue("UninstallString") as string;
List<string> executablePaths = FindExecutables(installLocation, uninstallString);
executables.AddRange(executablePaths);
}
}
}
}
return executables;
}
private List<string> FindExecutables(string installLocation, string uninstallString)
{
List<string> executables = new List<string>();
if (!string.IsNullOrEmpty(installLocation) && Directory.Exists(installLocation))
{
try
{
List<string> executableFiles = Directory.GetFiles(installLocation, "*.exe", SearchOption.AllDirectories)
.OrderByDescending(f => new FileInfo(f).Length)
.ToList();
executables.AddRange(executableFiles);
}
catch (Exception ex)
{
Debug.WriteLine($"Error enumerating executables in '{installLocation}': {ex}");
}
}
if (!string.IsNullOrEmpty(uninstallString))
{
if (TryParseExecutablePath(uninstallString, out string executablePath))
{
executables.Add(executablePath);
}
}
return executables;
}
private static bool TryParseExecutablePath(string s, out string path)
{
Match match = Regex.Match(s, @"(?<=""|^)([a-zA-Z]:\\[^""]+\.exe)", RegexOptions.IgnoreCase);
if (match.Success)
{
path = match.Value;
return true;
}
path = null;
return false;
}
private List<string> GetExecutablesFromPath()
{
List<string> executables = new List<string>();
string[] paths = Environment.GetEnvironmentVariable("PATH")?.Split(';');
if (paths != null)
{
foreach (string path in paths)
{
if (Directory.Exists(path))
{
try
{
executables.AddRange(Directory.GetFiles(path, "*.exe", SearchOption.TopDirectoryOnly));
}
catch (Exception ex)
{
Debug.WriteLine($"Error enumerating executables in '{path}': {ex}");
}
}
}
}
return executables;
}
private List<string> GetExecutablesFromNetFx()
{
List<string> executables = new List<string>();
string windir = Environment.GetEnvironmentVariable("WINDIR");
if (!string.IsNullOrEmpty(windir))
{
string[] paths = new string[]
{
Path.Combine(windir, "Microsoft.NET", "Framework"),
Path.Combine(windir, "Microsoft.NET", "Framework64")
};
foreach (string path in paths)
{
if (Directory.Exists(path))
{
try
{
executables.AddRange(Directory.GetFiles(path, "*.exe", SearchOption.AllDirectories));
}
catch (Exception ex)
{
Debug.WriteLine($"Error enumerating executables in '{path}': {ex}");
}
}
}
}
return executables;
}
}
public class CompletionItem
{
public string Label { get; set; }
public string Kind { get; set; }
public string Documentation { get; set; }
public string InsertText { get; set; }
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace WelsonJS.Launcher.ResourceTools
{
public class DevTools : IResourceTool
{
private ResourceServer Server;
private readonly HttpClient _httpClient;
private const string Prefix = "devtools/";
public DevTools(ResourceServer server, HttpClient httpClient)
{
Server = server;
_httpClient = httpClient;
}
public bool CanHandle(string path)
{
return path.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase);
}
public async Task HandleAsync(HttpListenerContext context, string path)
{
string endpoint = path.Substring(Prefix.Length);
try
{
string url = Program.GetAppConfig("DevToolsPrefix") + endpoint;
string data = await _httpClient.GetStringAsync(url);
Server.ServeResource(context, data, "application/json");
}
catch (Exception ex)
{
Server.ServeResource(context, $"<error>Failed to process DevTools request. {ex.Message}</error>", "application/xml", 500);
}
}
}
}

View File

@ -0,0 +1,343 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace WelsonJS.Launcher.ResourceTools
{
public class DnsQuery : IResourceTool
{
private readonly ResourceServer Server;
private readonly HttpClient _httpClient;
private const string Prefix = "dns-query/";
private string DnsServer;
private const int DnsPort = 53;
private const int Timeout = 5000;
private static readonly Random _random = new Random();
public DnsQuery(ResourceServer server, HttpClient httpClient)
{
Server = server;
_httpClient = httpClient;
DnsServer = Program.GetAppConfig("DnsServerAddress");
}
public bool CanHandle(string path)
{
return path.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase);
}
public async Task HandleAsync(HttpListenerContext context, string path)
{
await Task.Delay(0);
string query = path.Substring(Prefix.Length);
if (string.IsNullOrWhiteSpace(query) || query.Length > 255)
{
Server.ServeResource(context, "<error>Invalid query parameter</error>", "application/xml", 400);
return;
}
try
{
Dictionary<string, List<string>> allRecords = QueryAll(query);
StringBuilder result = new StringBuilder();
foreach (var recordType in allRecords.Keys)
{
result.AppendLine($"\n{recordType} Records:");
foreach (var record in allRecords[recordType])
{
result.AppendLine(record);
}
}
string data = result.ToString();
Server.ServeResource(context, data, "text/plain", 200);
}
catch (Exception ex)
{
Server.ServeResource(context, $"<error>Failed to process DNS query. {ex.Message}</error>", "application/xml", 500);
}
}
public List<string> QueryA(string domain) => QueryDns(domain, 1);
public List<string> QueryNS(string domain) => QueryDns(domain, 2);
public List<string> QueryCNAME(string domain) => QueryDns(domain, 5);
public List<string> QuerySOA(string domain) => QueryDns(domain, 6);
public List<string> QueryPTR(string domain) => QueryDns(domain, 12);
public List<string> QueryMX(string domain) => QueryDns(domain, 15);
public List<string> QueryTXT(string domain) => QueryDns(domain, 16);
public List<string> QueryAAAA(string domain) => QueryDns(domain, 28);
public List<string> QuerySRV(string domain) => QueryDns(domain, 33);
public List<string> QueryNAPTR(string domain) => QueryDns(domain, 35);
public List<string> QueryCAA(string domain) => QueryDns(domain, 257);
public Dictionary<string, List<string>> QueryAll(string domain)
{
var results = new Dictionary<string, List<string>>();
results["A"] = QueryA(domain);
results["NS"] = QueryNS(domain);
results["CNAME"] = QueryCNAME(domain);
results["SOA"] = QuerySOA(domain);
results["PTR"] = QueryPTR(domain);
results["MX"] = QueryMX(domain);
results["TXT"] = QueryTXT(domain);
results["AAAA"] = QueryAAAA(domain);
results["SRV"] = QuerySRV(domain);
results["NAPTR"] = QueryNAPTR(domain);
results["CAA"] = QueryCAA(domain);
return results;
}
private List<string> QueryDns(string domain, ushort type)
{
List<string> records = new List<string>();
// Validate domain format
if (string.IsNullOrWhiteSpace(domain))
{
records.Add("Error: Domain cannot be empty");
return records;
}
// Basic domain format validation
if (domain.Length > 255 ||
!domain.Split('.').All(part => part.Length > 0 && part.Length <= 63))
{
records.Add("Error: Invalid domain format");
return records;
}
try
{
using (UdpClient udpClient = new UdpClient(DnsServer, DnsPort))
{
udpClient.Client.ReceiveTimeout = Timeout;
byte[] request = CreateDnsQuery(domain, type);
udpClient.Send(request, request.Length);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, DnsPort);
byte[] response = udpClient.Receive(ref remoteEP);
records.AddRange(ParseDnsResponse(response, type));
}
}
catch (Exception ex)
{
records.Add($"Error: {ex.Message}");
}
return records;
}
private byte[] CreateDnsQuery(string domain, ushort type)
{
byte[] query = new byte[512];
query[0] = (byte)_random.Next(0, 256);
query[1] = (byte)_random.Next(0, 256);
query[2] = 0x01;
query[3] = 0x00;
query[4] = 0x00;
query[5] = 0x01;
for (int i = 6; i < 12; i++)
query[i] = 0x00;
int position = 12;
foreach (string part in domain.Split('.'))
{
query[position++] = (byte)part.Length;
byte[] label = Encoding.ASCII.GetBytes(part);
Array.Copy(label, 0, query, position, label.Length);
position += label.Length;
}
query[position++] = 0x00;
query[position++] = (byte)(type >> 8);
query[position++] = (byte)(type & 0xFF);
query[position++] = 0x00;
query[position++] = 0x01;
byte[] finalQuery = new byte[position];
Array.Copy(query, finalQuery, position);
return finalQuery;
}
private List<string> ParseDnsResponse(byte[] response, ushort queryType)
{
List<string> results = new List<string>();
// Check response code from DNS server
int responseCode = response[3] & 0x0F;
if (responseCode != 0)
{
string errorMessage = "DNS server returned error: ";
switch (responseCode)
{
case 1: errorMessage += "Format Error"; break;
case 2: errorMessage += "Server Failure"; break;
case 3: errorMessage += "Name Error (Domain does not exist)"; break;
case 4: errorMessage += "Not Implemented"; break;
case 5: errorMessage += "Refused"; break;
default: errorMessage += $"Unknown Error ({responseCode})"; break;
}
results.Add(errorMessage);
return results;
}
int answerCount = (response[6] << 8) | response[7];
if (answerCount == 0)
{
results.Add("No records found.");
return results;
}
int position = 12; // Skip DNS header
while (response[position] != 0)
position += response[position] + 1;
position += 5; // End of Question section
for (int i = 0; i < answerCount; i++)
{
while (response[position] != 0 && (response[position] & 0xC0) == 0)
position += response[position] + 1;
position += 2; // Skip Type, Class fields
ushort recordType = (ushort)((response[position] << 8) | response[position + 1]);
position += 8; // Skip TTL and Data length fields
ushort dataLength = (ushort)((response[position] << 8) | response[position + 1]);
position += 2; // Read Data Length
byte[] data = new byte[dataLength];
Array.Copy(response, position, data, 0, dataLength);
position += dataLength;
switch (recordType)
{
case 1:
results.Add($"A: {new IPAddress(data)}");
break;
case 2:
results.Add($"NS: {DecodeDomainName(response, data, 0)}");
break;
case 5:
results.Add($"CNAME: {DecodeDomainName(response, data, 0)}");
break;
case 6:
results.Add($"SOA: {DecodeDomainName(response, data, 0)}");
break;
case 12:
results.Add($"PTR: {DecodeDomainName(response, data, 0)}");
break;
case 15:
// MX record processing (priority and exchange)
if (data.Length >= 2)
{
ushort priority = (ushort)((data[0] << 8) | data[1]);
string exchange = DecodeDomainName(response, data, 2); // Decode domain name after 2 bytes
results.Add($"MX: Priority {priority}, Exchange {exchange}");
}
else
{
results.Add($"MX: Invalid data length.");
}
break;
case 16:
int txtPos = 0;
while (txtPos < data.Length)
{
int txtLength = data[txtPos++];
results.Add($"TXT: {Encoding.UTF8.GetString(data, txtPos, txtLength)}");
txtPos += txtLength;
}
break;
case 28:
results.Add($"AAAA: {new IPAddress(data)}");
break;
case 33:
ushort prioritySrv = (ushort)((data[0] << 8) | data[1]);
ushort weight = (ushort)((data[2] << 8) | data[3]);
ushort port = (ushort)((data[4] << 8) | data[5]);
string target = DecodeDomainName(response, data, 6);
results.Add($"SRV: Priority {prioritySrv}, Weight {weight}, Port {port}, Target {target}");
break;
case 35:
if (data.Length >= 7)
{
ushort order = (ushort)((data[0] << 8) | data[1]);
ushort preference = (ushort)((data[2] << 8) | data[3]);
// Extract flags, services, regexp and replacement
results.Add($"NAPTR: Order {order}, Preference {preference}");
}
else
{
results.Add($"NAPTR: Invalid data length: {BitConverter.ToString(data)}");
}
break;
case 257:
if (data.Length >= 2)
{
byte flags = data[0];
int tagLen = data[1];
if (data.Length >= 2 + tagLen)
{
string tag = Encoding.ASCII.GetString(data, 2, tagLen);
string value = Encoding.ASCII.GetString(data, 2 + tagLen, data.Length - 2 - tagLen);
results.Add($"CAA: Flags {flags}, Tag {tag}, Value {value}");
}
else
{
results.Add($"CAA: Invalid data length: {BitConverter.ToString(data)}");
}
}
else
{
results.Add($"CAA: Invalid data length: {BitConverter.ToString(data)}");
}
break;
default:
results.Add($"Unknown Type {recordType}: {BitConverter.ToString(data)}");
break;
}
}
return results;
}
private string DecodeDomainName(byte[] response, byte[] data, int startIndex)
{
int position = startIndex;
List<string> labels = new List<string>();
while (data[position] != 0)
{
// Handle 0xC0 pointer (compressed domain name handling)
if ((data[position] & 0xC0) == 0xC0)
{
int pointer = ((data[position] & 0x3F) << 8) | data[position + 1];
return DecodeDomainName(response, response, pointer); // Recursive call to decode from the pointer
}
int labelLength = data[position++];
labels.Add(Encoding.ASCII.GetString(data, position, labelLength));
position += labelLength;
}
return string.Join(".", labels);
}
}
}

View File

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Resources;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace WelsonJS.Launcher.ResourceTools
{
public class Settings : IResourceTool
{
private readonly ResourceServer Server;
private readonly HttpClient _httpClient;
private const string Prefix = "settings";
public Settings(ResourceServer server, HttpClient httpClient)
{
Server = server;
_httpClient = httpClient;
}
public bool CanHandle(string path)
{
return path.Equals(Prefix, StringComparison.OrdinalIgnoreCase);
}
public async Task HandleAsync(HttpListenerContext context, string path)
{
await Task.Delay(0);
// Get current namespace (e.g., WelsonJS.Launcher)
string ns = typeof(Program).Namespace;
// Build resource base name (e.g., WelsonJS.Launcher.Properties.Resources)
string resourceBaseName = ns + ".Properties.Resources";
// Load resource strings using ResourceManager
var resourceManager = new ResourceManager(resourceBaseName, Assembly.GetExecutingAssembly());
var resourceSet = resourceManager.GetResourceSet(
System.Globalization.CultureInfo.CurrentCulture,
true,
true
);
var resourceStrings = new Dictionary<string, string>();
foreach (System.Collections.DictionaryEntry entry in resourceSet)
{
if (entry.Value is string strValue)
{
resourceStrings[(string)entry.Key] = strValue;
}
}
// Load settings from app.config
var appConfig = ConfigurationManager.AppSettings.AllKeys
.ToDictionary(k => k, k => ConfigurationManager.AppSettings[k]);
// Merge by starting with resourceStrings and letting app.config override
var finalConfig = new Dictionary<string, string>(resourceStrings);
foreach (var kv in appConfig)
{
finalConfig[kv.Key] = kv.Value;
}
// Generate XML using XElement
XElement xml = new XElement("settings",
finalConfig.Select(kv => new XElement(kv.Key, kv.Value))
);
Server.ServeResource(context, xml.ToString(), "application/xml");
}
}
}

View File

@ -0,0 +1,103 @@
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using System.Net.Http;
namespace WelsonJS.Launcher.ResourceTools
{
public class Tfa : IResourceTool
{
private readonly ResourceServer Server;
private readonly HttpClient _httpClient;
private const string Prefix = "tfa/";
private const string Base32Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
public Tfa(ResourceServer server, HttpClient httpClient)
{
Server = server;
_httpClient = httpClient;
}
public bool CanHandle(string path)
{
return path.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase);
}
public async Task HandleAsync(HttpListenerContext context, string path)
{
await Task.Delay(0);
string endpoint = path.Substring(Prefix.Length);
if (endpoint.Equals("pubkey"))
{
Server.ServeResource(context, GetPubKey(), "text/plain", 200);
return;
}
Server.ServeResource(context);
}
public int GetOtp(string key)
{
byte[] binaryKey = DecodeBase32(key.Replace(" ", ""));
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds() / 30;
byte[] timestampBytes = BitConverter.GetBytes(timestamp);
Array.Reverse(timestampBytes); // Ensure big-endian order
using (var hmac = new HMACSHA1(binaryKey))
{
byte[] hash = hmac.ComputeHash(timestampBytes);
int offset = hash[hash.Length - 1] & 0xF;
int otp = ((hash[offset] & 0x7F) << 24) |
((hash[offset + 1] & 0xFF) << 16) |
((hash[offset + 2] & 0xFF) << 8) |
(hash[offset + 3] & 0xFF);
return otp % 1000000; // Ensure 6-digit OTP
}
}
public string GetPubKey()
{
using (var rng = RandomNumberGenerator.Create())
{
var key = new char[16];
var randomBytes = new byte[16];
rng.GetBytes(randomBytes);
for (int i = 0; i < 16; i++)
{
key[i] = Base32Chars[randomBytes[i] % Base32Chars.Length];
}
return string.Join(" ", Enumerable.Range(0, 4).Select(i => new string(key, i * 4, 4)));
}
}
private static byte[] DecodeBase32(string key)
{
int buffer = 0, bitsLeft = 0;
var binaryKey = new List<byte>();
foreach (char c in key)
{
int value = Base32Chars.IndexOf(c);
if (value < 0) continue; // Ignore invalid characters
buffer = (buffer << 5) + value;
bitsLeft += 5;
if (bitsLeft >= 8)
{
bitsLeft -= 8;
binaryKey.Add((byte)((buffer >> bitsLeft) & 0xFF));
}
}
return binaryKey.ToArray();
}
}
}

View File

@ -0,0 +1,60 @@
using System.Net;
using System.Threading.Tasks;
using System;
using System.Net.Http;
using System.Text;
namespace WelsonJS.Launcher.ResourceTools
{
public class Whois : IResourceTool
{
private readonly ResourceServer Server;
private readonly HttpClient _httpClient;
private const string Prefix = "whois/";
public Whois(ResourceServer server, HttpClient httpClient)
{
Server = server;
_httpClient = httpClient;
}
public bool CanHandle(string path)
{
return path.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase);
}
public async Task HandleAsync(HttpListenerContext context, string path)
{
string query = path.Substring(Prefix.Length);
if (string.IsNullOrWhiteSpace(query) || query.Length > 255)
{
Server.ServeResource(context, "<error>Invalid query parameter</error>", "application/xml", 400);
return;
}
string clientAddress = Program.GetAppConfig("WhoisClientAddress");
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Program.GetAppConfig("WhoisServerUrl"))
{
Content = new StringContent($"query={Uri.EscapeDataString(query)}&ip={clientAddress}", Encoding.UTF8, "application/x-www-form-urlencoded")
};
request.Headers.Add("Accept", "*/*");
request.Headers.Add("User-Agent", context.Request.UserAgent);
_httpClient.DefaultRequestHeaders.Referrer = new Uri(Program.GetAppConfig("WhoisReferrerUrl"));
try
{
HttpResponseMessage response = await _httpClient.SendAsync(request);
string responseBody = await response.Content.ReadAsStringAsync();
Server.ServeResource(context, responseBody, "text/plain", (int)response.StatusCode);
}
catch (Exception ex)
{
Server.ServeResource(context, $"<error>Failed to process WHOIS request. {ex.Message}</error>", "application/xml", 500);
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4074D413-195C-45E9-9E63-0D07914187B8}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>WelsonJS.Launcher</RootNamespace>
<AssemblyName>WelsonJS.Launcher</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="IResourceTool.cs" />
<Compile Include="ResourceTools\Settings.cs" />
<Compile Include="ResourceTools\Completion.cs" />
<Compile Include="ResourceTools\DevTools.cs" />
<Compile Include="ResourceTools\DnsQuery.cs" />
<Compile Include="ResourceTools\Tfa.cs" />
<Compile Include="ResourceTools\Whois.cs" />
<Compile Include="EnvForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="EnvForm.Designer.cs">
<DependentUpon>EnvForm.cs</DependentUpon>
</Compile>
<Compile Include="InstancesForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="InstancesForm.Designer.cs">
<DependentUpon>InstancesForm.cs</DependentUpon>
</Compile>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GlobalSettingsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="GlobalSettingsForm.Designer.cs">
<DependentUpon>GlobalSettingsForm.cs</DependentUpon>
</Compile>
<Compile Include="ResourceServer.cs" />
<EmbeddedResource Include="EnvForm.resx">
<DependentUpon>EnvForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="InstancesForm.resx">
<DependentUpon>InstancesForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="GlobalSettingsForm.resx">
<DependentUpon>GlobalSettingsForm.cs</DependentUpon>
</EmbeddedResource>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon_link_128.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon_zip_128.png" />
</ItemGroup>
<ItemGroup>
<None Include="favicon.ico" />
<None Include="Resources\favicon.ico" />
<None Include="Resources\icon_check_32.png" />
<None Include="Resources\icon_directory_32.png" />
<None Include="Resources\icon_file_32.png" />
<None Include="Resources\icon_export_32.png" />
<None Include="Resources\icon_import_32.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon_delete_32.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon_start_32.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="editor.html" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="ResourceServerPrefix" value="http://localhost:3000/"/>
<add key="RepositoryUrl" value="https://github.com/gnh1201/welsonjs"/>
<add key="CopilotUrl" value="https://copilot.microsoft.com/"/>
<add key="DevToolsPrefix" value="http://localhost:9222/"/>
<add key="AzureAiServicePrefix" value="https://ai-catswords656881030318.services.ai.azure.com/"/>
<add key="AzureAiServiceApiKey" value=""/>
<add key="AzureAiServiceApiVersion" value="2024-05-01-preview"/>
<add key="WhoisServerUrl" value="https://xn--c79as89aj0e29b77z.xn--3e0b707e/kor/whois.jsc"/>
<add key="WhoisReferrerUrl" value="https://xn--c79as89aj0e29b77z.xn--3e0b707e/kor/whois/whois.jsp"/>
<add key="WhoisClientAddress" value="141.101.82.1"/>
<add key="DnsServerAddress" value="1.1.1.1"/>
<add key="BlobStoragePrefix" value="https://catswords.blob.core.windows.net/welsonjs/"/>
<add key="BlobConfigUrl" value="https://catswords.blob.core.windows.net/welsonjs/blob.config.xml"/>
<add key="HttpClientTimeout" value="90"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
</configuration>

View File

@ -0,0 +1,597 @@
<!DOCTYPE html>
<html>
<head>
<title>WelsonJS Editor</title>
<meta name="title" content="WelsonJS Editor">
<meta name="description" content="WelsonJS can build a Windows app on the Windows built-in JavaScript engine.">
<meta name="keywords" content="ecmascript, javascript, windows">
<meta name="robots" content="noindex, nofollow">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="language" content="English">
<meta name="author" content="Namhyeon Go (abuse@catswords.net)">
<style>
html, body, #app, #app > .app {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#container {
border: 1px solid grey;
height: calc(100% - 167px);
display: flex;
overflow: hidden;
}
#editor {
flex: 3;
}
#promptEditor {
flex: 1;
}
.banner {
text-align: center;
padding: 10px;
background-color: #f1f1f1;
font-size: 14px;
}
</style>
</head>
<body>
<div id="app"></div>
<script>
var require = {
paths: {
vs: 'http://localhost:3000/ajax/libs/monaco-editor/0.52.2/min/vs'
}
};
</script>
<script src="http://localhost:3000/ajax/libs/lodash/4.17.21/lodash.min.js" integrity="sha384-H6KKS1H1WwuERMSm+54dYLzjg0fKqRK5ZRyASdbrI/lwrCc6bXEmtGYr5SwvP1pZ" crossorigin="anonymous"></script>
<script src="http://localhost:3000/ajax/libs/jsoneditor/10.1.3/jsoneditor.min.js" integrity="sha384-NdVVc20Tze856ZAWEoJNCk0mL4zJrGztRwULc5Hz25HUXQQgYtmjFtgVAxR4p5dD" crossorigin="anonymous"></script>
<script src="http://localhost:3000/ajax/libs/react/18.3.1/umd/react.production.min.js" integrity="sha384-DGyLxAyjq0f9SPpVevD6IgztCFlnMF6oW/XQGmfe+IsZ8TqEiDrcHkMLKI6fiB/Z" crossorigin="anonymous"></script>
<script src="http://localhost:3000/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js" integrity="sha384-gTGxhz21lVGYNMcdJOyq01Edg0jhn/c22nsx0kyqP0TxaV5WVdsSH1fSDUf5YJj1" crossorigin="anonymous"></script>
<script src="http://localhost:3000/ajax/libs/axios/1.8.4/axios.min.js" integrity="sha384-06w+raHvkSL3+E7mbQ2X6DZwI5A3veU8Ba+NLrAPxxRGw4Xy78sihHDHQMustMM4" crossorigin="anonymous"></script>
<script src="http://localhost:3000/ajax/libs/fast-xml-parser/4.5.1/fxparser.min.js" integrity="sha384-ae/HepOQ8hiJ/VA6yGwPMGXQXOkT/lJpjlcQ7EUgibUcfnBltuozgNj4IgOZ9QLc" crossorigin="anonymous"></script>
<script src="http://localhost:3000/ajax/libs/dompurify/3.2.4/purify.min.js" integrity="sha384-eEu5CTj3qGvu9PdJuS+YlkNi7d2XxQROAFYOr59zgObtlcux1ae1Il3u7jvdCSWu" crossorigin="anonymous"></script>
<script src="http://localhost:3000/ajax/libs/monaco-editor/0.52.2/min/vs/loader.js" integrity="sha384-pHG02SG8pId94Np3AbPmBEJ1yPqaH0IkJGLSNGXYmuGhkazT8Lr/57WYpbkGjJtu" crossorigin="anonymous"></script>
<script src="http://localhost:3000/ajax/libs/monaco-editor/0.52.2/min/vs/editor/editor.main.js" integrity="sha384-fj9z+NUc93I3woCCy5IRQfrQ8Amu1E27tllwgb5gz3d9Vr1ymS13xcF6two3e4KH" crossorigin="anonymous"></script>
<script>
function loadResource(url, mimeType, integrity) {
mimeType = mimeType || 'application/javascript';
return new Promise((resolve, reject) => {
let el;
if (mimeType === 'text/css') {
el = document.createElement('link');
el.rel = 'stylesheet';
el.type = mimeType;
el.href = url;
} else {
el = document.createElement('script');
el.type = mimeType;
el.src = url;
}
if (integrity) {
el.integrity = integrity;
el.crossOrigin = 'anonymous';
}
el.onload = resolve;
el.onerror = reject;
(mimeType === 'text/css' ? document.head : document.body).appendChild(el);
});
}
Promise.all([
loadResource("http://localhost:3000/ajax/libs/metroui/dev/lib/metro.css", "text/css", "sha384-4XgOiXH2ZMaWt5s5B35yKi7EAOabhZvx7wO8Jr71q2vZ+uONdRza/6CsK2kpyocd"),
loadResource("http://localhost:3000/ajax/libs/metroui/dev/lib/icons.css", "text/css", "sha384-FuLND994etg+RtnpPSPMyNBvL+fEz+xGhbN61WUWuDEeZ+wJzcQ8SGqAMuI5hWrt"),
loadResource("http://localhost:3000/ajax/libs/monaco-editor/0.52.2/min/vs/editor/editor.main.css", "text/css", "sha384-06yHXpYRlHEPaR4AS0fB/W+lMN09Zh5e1XMtfkNQdHV38OlhfkOEW5M+pCj3QskC"),
loadResource("http://localhost:3000/ajax/libs/jsoneditor/10.1.3/jsoneditor.min.css", "text/css", "sha384-cj1rYBc4/dVYAknZMTkVCDRL6Knzugf32igVqsuFW0iRWFHKH8Ci8+ekC8gNsFZ+")
]).then(() => {
const _e = React.createElement;
function Button({ id, icon, caption, onClick }) {
return _e(
'button',
{ id, className: 'ribbon-button', onClick },
_e('span', { className: `icon ${icon}` }),
_e('span', { className: 'caption' }, caption)
);
}
function Group({ title, buttons }) {
return _e(
'div',
{ className: 'group' },
buttons.map((btn, index) =>
_e(Button, { key: index, ...btn })
),
_e('span', { className: 'title' }, title)
);
}
function RibbonMenu({
onOpenFileClick, onSaveFileClick, onCopliotClick, onAzureAiClick,
onSavePromptClick, onLoadPromptClick, onQueryWhoisClick, onQueryDnsClick
}) {
const fileButtons = [
{
id: 'btnOpenFile',
icon: 'mif-folder-open',
caption: 'Open File',
onClick: onOpenFileClick
},
{
id: 'btnSaveFile',
icon: 'mif-floppy-disks',
caption: 'Save File',
onClick: onSaveFileClick
}
];
const aiButtons = [
{ id: 'btnCopilot', icon: 'mif-rocket', caption: 'Copilot', onClick: onCopliotClick },
{ id: 'btnAzureAi', icon: 'mif-rocket', caption: 'Azure AI', onClick: onAzureAiClick },
{ id: 'btnSavePrompt', icon: 'mif-floppy-disks', caption: 'Save', onClick: onSavePromptClick },
{ id: 'btnLoadPrompt', icon: 'mif-file-upload', caption: 'Load', onClick: onLoadPromptClick }
];
const networkToolsButtons = [
{ id: 'btnWhois', icon: 'mif-earth', caption: 'Whois', onClick: onQueryWhoisClick },
{ id: 'btnDnsQuery', icon: 'mif-earth', caption: 'DNS', onClick: onQueryDnsClick }
];
return _e(
'nav',
{ 'className': 'ribbon-menu' },
_e('ul', { className: 'tabs-holder' },
_e('li', { className: 'static' }, _e('a', { href: '#heading-tab' }, 'WelsonJS')),
_e('li', { className: 'active' }, _e('a', { href: '#editor-tab' }, 'Editor'))
),
_e('div', { className: 'content-holder' },
_e('div', { className: 'section active', id: 'editor-tab' },
_e(Group, { title: 'File', buttons: fileButtons }),
_e(Group, { title: 'Generative AI', buttons: aiButtons }),
_e(Group, { title: 'Network tools', buttons: networkToolsButtons })
)
)
);
}
function Editor({ editorRef }) {
const containerRef = React.useRef(null);
React.useEffect(() => {
if (!containerRef.current)
return;
require(['vs/editor/editor.main'], () => {
const instance = monaco.editor.create(containerRef.current, {
value: ['// lib/sayhello.js', 'function say() {', ' console.log("hello");', '}', '', 'exports.say = say;', '', 'exports.VERSIONINFO = "SayHello (sayhello.js) version 0.1";', 'exports.AUTHOR = "abuse@catswords.net";', 'exports.global = global;', 'exports.require = global.require;'].join('\n'),
language: 'javascript'
});
editorRef.current = instance;
});
}, []);
return _e('div', { id: 'editor', ref: containerRef });
}
function PromptEditor({ promptEditorRef, promptMessagesRef }) {
const containerRef = React.useRef(null);
React.useEffect(() => {
if (!containerRef.current)
return;
const invoke = () => {
try {
if (promptEditorRef.current) {
const updated = promptEditorRef.current.get();
promptMessagesRef.current = updated;
} else {
throw new Error("promptEditorRef.current is null");
}
} catch (e) {
console.error("Invalid JSON structure", e);
}
};
const throttledInvoke = _.throttle(invoke, 300, {
leading: true,
trailing: true
});
const options = {
onChange: throttledInvoke
};
const instance = new JSONEditor(containerRef.current, options);
instance.set(promptMessagesRef.current);
promptEditorRef.current = instance;
return () => {
if (instance) {
throttledInvoke.flush();
throttledInvoke.cancel();
instance.destroy();
}
};
}, []);
return _e('div', { id: 'promptEditor', ref: containerRef });
}
function App() {
const serverPrefix = "http://localhost:3000/";
const editorRef = React.useRef(null);
const promptEditorRef = React.useRef(null);
const settingsRef = React.useRef({});
const fileNameRef = React.useRef('sayhello.js');
const promptMessagesRef = React.useRef([]);
const fetchSettings = () => axios.get(`${serverPrefix}settings`)
.then(response => {
const parser = new XMLParser();
const result = parser.parse(response.data);
settingsRef.current = result.settings;
});
const resizeEditor = () => {
if (editorRef.current) {
const ribbon = document.querySelector('nav')?.offsetHeight || 0;
const banner = document.querySelector('.banner')?.offsetHeight || 0;
const h = document.documentElement.clientHeight - ribbon - banner;
const editorDiv = document.getElementById('editor');
if (editorDiv) editorDiv.style.height = h + 'px';
if (editorRef.current) editorRef.current.layout();
}
};
const getSuggestions = (word) => axios.get(`${serverPrefix}completion/${encodeURIComponent(word)}`)
.then(response => {
const parser = new XMLParser();
const result = parser.parse(response.data);
if (!result.suggestions || !result.suggestions.item) {
return {
suggestions: []
};
}
const items = Array.isArray(result.suggestions.item) ? result.suggestions.item : [result.suggestions.item];
const suggestions = items.map(function (item) {
return {
label: item.label,
kind: monaco.languages.CompletionItemKind.Text,
documentation: item.documentation || "",
insertText: '"' + item.insertText + '"',
range: range
};
});
return {
suggestions: suggestions
};
})
.catch(function () {
return {
suggestions: []
};
});
const pushPromptMessage = (role, content) => {
promptMessagesRef.current.push({
role: role,
content: content
});
promptEditorRef.current.set(promptMessagesRef.current);
};
const navigate = (href) => {
const a = document.createElement("a");
a.href = href;
a.target = "_blank";
document.body.appendChild(a);
a.click();
};
const appendTextToEditor = (text) => {
const editor = editorRef.current;
const position = editor.getPosition();
const range = new monaco.Range(position.lineNumber, position.column, position.lineNumber, position.column);
editor.executeEdits('', [{
range: range,
text: "\n" + text,
forceMoveMarkers: true
}]);
resizeEditor();
};
const openFile = () => {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.onchange = () => {
const file = fileInput.files[0];
if (!file)
return;
const reader = new FileReader();
reader.onload = (e) => {
const fileName = file.name;
const ext = fileName.split('.').pop().toLowerCase();
const langMap = {
js: 'javascript', ts: 'typescript', html: 'html',
css: 'css', json: 'json', py: 'python', java: 'java',
c: 'c', cpp: 'cpp', cs: 'csharp', php: 'php',
rb: 'ruby', go: 'go', rs: 'rust'
};
const lang = langMap[ext] || 'plaintext';
monaco.editor.setModelLanguage(editorRef.current.getModel(), lang);
editorRef.current.setValue(e.target.result);
fileNameRef.current = fileName;
};
reader.readAsText(file);
};
fileInput.click();
};
const saveFile = () => {
const text = editorRef.current.getValue();
const fileName = prompt("Enter file name:", fileNameRef.current);
if (!fileName)
return;
const blob = new Blob([text], { type: 'text/plain' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = fileNameRef.current;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
const sendMessageToCopilot = () => {
const promptMessage = prompt("Enter a prompt message:", '');
if (!promptMessage || promptMessage.trim() == '') {
alert("A prompt message is required.");
return;
}
appendTextToEditor(`\n// ${promptMessage}... Generating text with Copilot...`);
pushPromptMessage("user", promptMessage);
(async () => {
const targetWsUrl = await getTargetByUrl('copilot.microsoft.com');
if (targetWsUrl) {
await _sendMessageToCopilot(targetWsUrl, promptMessage);
} else {
alert("Microsoft Copilot not running. Please visit copilot.microsoft.com first.");
}
})();
};
const _sendMessageToCopilot = async (wsUrl, promptMessage) => {
const socket = new WebSocket(wsUrl);
const steps = [
{
id: 1,
method: 'Input.insertText',
params: {
text: promptMessage
}
},
{
id: 2,
method: 'Input.dispatchKeyEvent',
params: {
type: 'keyDown',
key: 'Enter',
code: 'Enter'
}
},
{
id: 3,
method: 'Runtime.evaluate',
params: {
expression: '((e)=>e[e.length-1].querySelector("code")?.innerText||e[e.length-1].innerText)(document.querySelectorAll("[data-content=ai-message]"))'
}
}
];
socket.onopen = () => {
steps.forEach((step) => {
if (step.id == 3) {
setTimeout(() => {
socket.send(JSON.stringify(step));
}, 9000);
} else {
socket.send(JSON.stringify(step));
}
});
};
socket.onmessage = (event) => {
const response = JSON.parse(event.data);
console.log("Sent successfully:", response.result);
if (response.id == 3) {
const responseContent = response.result.result.value;
appendTextToEditor("/*\n" + responseContent + "\n*/");
pushPromptMessage("assistant", responseContent);
socket.close();
}
};
};
const getTargetByUrl = async (urlPart) => {
const response = await fetch(`${serverPrefix}devtools/json`);
const targets = await response.json();
const target = targets.find(target => target.url.includes(urlPart));
if (target) {
console.log(`Found target: ${target.title} (${target.id})`);
return target.webSocketDebuggerUrl;
} else {
console.log('Target not found');
return null;
}
};
const sendMessageToAzureAi = () => {
const promptMessage = prompt("Enter a prompt message:", '');
if (!promptMessage || promptMessage.trim() == '') {
alert("A prompt message is required.");
return;
}
appendTextToEditor(`\n// ${promptMessage}... Generating text with Azure AI...`);
pushPromptMessage("user", promptMessage);
const apiKey = settingsRef.current.AzureAiServiceApiKey;
const url = `${settingsRef.current.AzureAiServicePrefix}models/chat/completions?api-version=${settingsRef.current.AzureAiServiceApiVersion}`;
const data = {
messages: promptMessagesRef.current,
max_tokens: 2048,
temperature: 0.8,
top_p: 0.1,
presence_penalty: 0,
frequency_penalty: 0,
model: 'Phi-4'
};
axios.post(url, data, {
headers: {
'Content-Type': 'application/json',
'api-key': apiKey
}
}).then(response => {
response.data.choices.forEach(x => {
const responseContent = x.message.content;
pushPromptMessage("assistant", responseContent);
const responseText = DOMPurify.sanitize(responseContent, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] });
appendTextToEditor(`/*\n${responseText}\n*/`);
});
})
.catch(error => {
console.error('Error:', error.response?.data || error.message);
});
};
const savePromptMessages = () => {
const text = JSON.stringify(promptMessagesRef.current, null, 4);
const blob = new Blob([text], { type: 'text/plain' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = "prompt.json";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
const loadPromptMessages = () => {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.json';
fileInput.onchange = function (event) {
const file = event.target.files[0];
if (!file)
return;
let reader = new FileReader();
reader.onload = function (e) {
promptMessagesRef.current = JSON.parse(e.target.result);
promptEditorRef.current.set(promptMessagesRef.current);
appendTextToEditor("\n//Prompt loaded successfully.");
};
reader.readAsText(file);
};
fileInput.click();
};
const queryWhois = () => {
const hostname = prompt("Enter a hostname or IP address:", '');
if (!hostname || hostname.trim() == '') {
appendTextToEditor("\n// A hostname or IP address is required.");
return;
}
axios.get(`${serverPrefix}whois/${hostname}`).then(response => {
const responseText = DOMPurify.sanitize(response.data, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] });
appendTextToEditor(`/*\n${responseText}\n*/`);
pushPromptMessage("system", responseText);
}).catch(error => {
console.error(error);
});
};
const queryDns = () => {
const hostname = prompt("Enter a hostname or IP address:", '');
if (!hostname || hostname.trim() == '') {
appendTextToEditor("\n// A hostname or IP address is required.");
return;
}
axios.get(`${serverPrefix}dns-query/${hostname}`).then(response => {
const responseText = response.data;
appendTextToEditor(`/*\n${responseText}\n*/`);
pushPromptMessage("system", responseText);
}).catch(error => {
console.error(error);
});
};
React.useEffect(() => {
window.addEventListener('resize', () => {
resizeEditor();
});
window.dispatchEvent(new Event('resize'));
}, []);
fetchSettings();
return _e('div', { className: 'app' },
_e(RibbonMenu, {
onOpenFileClick: openFile,
onSaveFileClick: saveFile,
onCopliotClick: sendMessageToCopilot,
onAzureAiClick: sendMessageToAzureAi,
onSavePromptClick: savePromptMessages,
onLoadPromptClick: loadPromptMessages,
onQueryWhoisClick: queryWhois,
onQueryDnsClick: queryDns
}),
_e('div', { id: 'container' },
_e(Editor, { editorRef }),
_e(PromptEditor, { promptEditorRef, promptMessagesRef })
),
_e('div', { className: 'banner' }, _e('a', { href: 'https://github.com/gnh1201/welsonjs' }, 'WelsonJS'), ' Editor powered by Metro UI, Monaco Editor, and JSONEditor.'),
);
}
const container = document.getElementById('app');
const root = ReactDOM.createRoot(container);
root.render(_e(App));
});
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net472" />
</packages>

View File

@ -0,0 +1,30 @@
// ElasticsearchClient.cs
// https://github.com/gnh1201/welsonjs
using RestSharp.Authenticators;
using RestSharp;
namespace WelsonJS.Service
{
public class ElasticsearchClient
{
private readonly RestClient client;
public ElasticsearchClient(string baseUrl, string username, string password)
{
var options = new RestClientOptions(baseUrl)
{
Authenticator = new HttpBasicAuthenticator(username, password)
};
client = new RestClient(options);
}
public RestResponse IndexDocument(string indexName, object document)
{
var request = new RestRequest($"/{indexName}/_doc", Method.Post);
request.AddHeader("Content-Type", "application/json");
request.AddJsonBody(document);
return client.Execute(request);
}
}
}

View File

@ -0,0 +1,255 @@
// FileEventMonitor.cs
// Namhyeon Go <abuse@catswords.net>
// https://github.com/gnh1201/welsonjs
using ClamAV.Net.Client;
using ClamAV.Net.Client.Results;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics.Eventing.Reader;
using System.ServiceProcess;
using System.Threading.Tasks;
namespace WelsonJS.Service
{
public class FileEventMonitor
{
private EventLogWatcher eventLogWatcher;
private ServiceMain parent;
private ILogger logger;
private enum EventType: int
{
FileCreate = 11,
NetworkConnection = 3,
RegistryEvent_1 = 12,
RegistryEvent_2 = 13,
RegistryEvent_3 = 14
};
private enum FileCreateEvent: int {
RuleName,
UtcTime,
ProcessGuid,
ProcessId,
Image,
TargetFilename,
CreationUtcTime,
User
};
private enum NetworkConnectionEvent: int
{
RuleName,
UtcTime,
ProcessGuid,
ProcessId,
Image,
User,
Protocol,
Initiated,
SourceIsIpv6,
SourceIp,
SourceHostname,
SourcePort,
SourcePortName,
DestinationIsIpv6,
DestinationIp,
DestinationHostname,
DestinationPort,
DestinationPortName,
};
private enum RegistryEvent: int
{
RuleName,
EventType,
UtcTime,
ProcessGuid,
ProcessId,
Image,
TargetObject,
Details,
User
}
private string clamAvConenctionString;
private IClamAvClient clamAvClient;
public FileEventMonitor(ServiceBase _parent, string workingDirectory, ILogger _logger)
{
parent = (ServiceMain)_parent;
logger = _logger;
try
{
clamAvConenctionString = parent.ReadSettingsValue("CLAMAV_HOST");
}
catch (Exception ex)
{
clamAvConenctionString = "tcp://127.0.0.1:3310";
logger.LogInformation($"Failed to read the address because of {ex.Message}. Set default: {clamAvConenctionString}");
}
ConnectToClamAv().Start();
}
public void Start()
{
try
{
string query = @"<QueryList>
<Query Id='0' Path='Microsoft-Windows-Sysmon/Operational'>
<Select Path='Microsoft-Windows-Sysmon/Operational'>*[System/EventID=11 or System/EventID=3 or System/EventID=12 or System/EventID=13 or System/EventID=14]</Select>
</Query>
</QueryList>";
EventLogQuery eventLogQuery = new EventLogQuery("Microsoft-Windows-Sysmon/Operational", PathType.LogName, query);
eventLogWatcher = new EventLogWatcher(eventLogQuery);
eventLogWatcher.EventRecordWritten += new EventHandler<EventRecordWrittenEventArgs>(OnEventRecordWritten);
eventLogWatcher.Enabled = true;
}
catch (Exception ex)
{
logger.LogInformation($"Could not reach to the Sysmon service: {ex.Message}");
}
}
public void Stop()
{
if (eventLogWatcher != null)
{
try
{
eventLogWatcher.Dispose();
eventLogWatcher = null;
}
catch (Exception)
{
eventLogWatcher = null;
}
}
}
private void OnEventRecordWritten(object sender, EventRecordWrittenEventArgs e)
{
if (e.EventRecord != null)
{
int eventId = e.EventRecord.Id;
try
{
switch (eventId)
{
case (int)EventType.FileCreate:
{
string ruleName = e.EventRecord.Properties[(int)FileCreateEvent.RuleName]?.Value?.ToString();
string processId = e.EventRecord.Properties[(int)FileCreateEvent.ProcessId]?.Value?.ToString();
string image = e.EventRecord.Properties[(int)FileCreateEvent.Image]?.Value?.ToString();
string fileName = e.EventRecord.Properties[(int)FileCreateEvent.TargetFilename]?.Value?.ToString();
logger.LogInformation($"> Detected the file creation: {fileName}");
logger.LogInformation(parent.DispatchServiceEvent("fileCreated", new string[] {
ruleName,
processId,
image,
fileName
}));
if (clamAvClient != null)
{
logger.LogInformation($"> Starting the ClamAV scan: {fileName}");
Task.Run(async () =>
{
await ScanWithClamAv(fileName);
});
}
break;
}
case (int)EventType.NetworkConnection:
{
string ruleName = e.EventRecord.Properties[(int)NetworkConnectionEvent.RuleName]?.Value?.ToString();
string processId = e.EventRecord.Properties[(int)NetworkConnectionEvent.ProcessId]?.Value?.ToString();
string image = e.EventRecord.Properties[(int)NetworkConnectionEvent.Image]?.Value?.ToString();
string protocol = e.EventRecord.Properties[(int)NetworkConnectionEvent.Protocol]?.Value?.ToString();
string destinationIp = e.EventRecord.Properties[(int)NetworkConnectionEvent.DestinationIp]?.Value?.ToString();
string desinationPort = e.EventRecord.Properties[(int)NetworkConnectionEvent.DestinationPort]?.Value?.ToString();
string dstinationAddress = $"{protocol}://{destinationIp}:{desinationPort}";
logger.LogInformation($"> Detected the network connection: {dstinationAddress}");
logger.LogInformation(parent.DispatchServiceEvent("networkConnected", new string[] {
ruleName,
processId,
image,
dstinationAddress
}));
break;
}
case (int)EventType.RegistryEvent_1:
case (int)EventType.RegistryEvent_2:
case (int)EventType.RegistryEvent_3:
{
string ruleName = e.EventRecord.Properties[(int)RegistryEvent.RuleName]?.Value?.ToString();
string processId = e.EventRecord.Properties[(int)RegistryEvent.ProcessId]?.Value?.ToString();
string image = e.EventRecord.Properties[(int)RegistryEvent.Image]?.Value?.ToString();
string eventType = e.EventRecord.Properties[(int)RegistryEvent.EventType]?.Value?.ToString();
string targetObject = e.EventRecord.Properties[(int)RegistryEvent.TargetObject]?.Value?.ToString();
logger.LogInformation($"> Detected the registry modification: {targetObject}");
logger.LogInformation(parent.DispatchServiceEvent("registryModified", new string[] {
ruleName,
processId,
image,
eventType,
targetObject
}));
break;
}
default:
throw new ArgumentException("Not supported event type");
}
}
catch (Exception ex)
{
logger.LogInformation($"Failed to process the event bacause of {ex.Message}.");
}
}
else
{
logger.LogInformation("The event instance was null.");
}
}
private async Task ConnectToClamAv()
{
try {
// Create a client
clamAvClient = ClamAvClient.Create(new Uri(clamAvConenctionString));
// Send PING command to ClamAV
await clamAvClient.PingAsync().ConfigureAwait(false);
// Get ClamAV engine and virus database version
VersionResult result = await clamAvClient.GetVersionAsync().ConfigureAwait(false);
logger.LogInformation($"ClamAV version {result.ProgramVersion}, Virus database version {result.VirusDbVersion}");
}
catch (Exception ex)
{
logger.LogInformation($"Failed to read the address because of {ex.Message}. {clamAvConenctionString}");
clamAvClient = null;
}
}
private async Task ScanWithClamAv(string remotePath)
{
ScanResult res = await clamAvClient.ScanRemotePathAsync(remotePath).ConfigureAwait(false);
logger.LogInformation($"> Scan result: Infected={res.Infected}, VirusName={res.VirusName}");
logger.LogInformation(parent.DispatchServiceEvent("avScanResult", new string[] {
res.Infected.ToString(),
res.VirusName
}));
}
}
}

View File

@ -0,0 +1,160 @@
// HeartbeatClient.cs
// Namhyeon Go <abuse@catswords.net>
// https://github.com/gnh1201/welsonjs
using Grpc.Core;
using System.Threading.Tasks;
using System;
using System.Management;
using System.ServiceProcess;
using Grpc.Net.Client;
using Grpc.Net.Client.Web;
using System.Net.Http;
using Microsoft.Extensions.Logging;
namespace WelsonJS.Service
{
public class HeartbeatClient
{
private readonly HeartbeatService.HeartbeatServiceClient _client;
private ILogger logger;
private readonly GrpcChannel _channel;
private int HeartbeatInterval;
private ServiceMain parent;
private string clientId;
private string serverAddress;
public HeartbeatClient(ServiceBase _parent, ILogger _logger)
{
parent = (ServiceMain)_parent;
logger = _logger;
HeartbeatInterval = int.Parse(parent.ReadSettingsValue("HEARTBEAT_INTERVAL") ?? "2000");
try
{
serverAddress = parent.ReadSettingsValue("GRPC_HOST");
if (String.IsNullOrEmpty(serverAddress))
{
throw new Exception("The server address could not be empty.");
}
}
catch (Exception ex)
{
serverAddress = "http://localhost:50051";
logger.LogInformation($"Failed to read the address because of {ex.Message}. Set default: {serverAddress}");
}
var httpClientHandler = new HttpClientHandler();
var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, httpClientHandler);
_channel = GrpcChannel.ForAddress(serverAddress, new GrpcChannelOptions
{
HttpHandler = grpcWebHandler,
Credentials = ChannelCredentials.Insecure
});
_client = new HeartbeatService.HeartbeatServiceClient(_channel);
clientId = GetSystemUUID().ToLower();
logger.LogInformation($"Use the client ID: {clientId}");
}
public async Task StartHeartbeatAsync()
{
while (true)
{
var call = _client.CheckHeartbeat();
try
{
var request = new HeartbeatRequest
{
IsAlive = true
};
await call.RequestStream.WriteAsync(request);
await call.RequestStream.CompleteAsync();
logger.LogInformation("Sent heartbeat");
await Task.Delay(HeartbeatInterval); // Wait for HeartbeatInterval
}
catch (Exception ex)
{
logger.LogInformation("Heartbeat request stream failed: " + ex.Message);
}
// 서버 응답을 수신하는 작업
try
{
while (await call.ResponseStream.MoveNext())
{
var response = call.ResponseStream.Current;
logger.LogInformation("Heartbeat response received: " + response.IsAlive);
}
}
catch (RpcException ex)
{
logger.LogInformation($"gRPC error: {ex.Status.Detail}");
}
catch (Exception ex)
{
logger.LogInformation($"Unexpected error: {ex.Message}");
}
finally
{
// 잠시 대기 후 재연결
await Task.Delay(TimeSpan.FromMilliseconds(HeartbeatInterval));
}
}
}
public async Task StartEventListenerAsync()
{
var eventRequest = new FetchEventsRequest
{
ClientId = clientId
};
while (true)
{
var eventCall = _client.FetchPendingEvents(eventRequest);
try
{
while (await eventCall.ResponseStream.MoveNext())
{
var response = eventCall.ResponseStream.Current;
logger.LogInformation($"Received event from server: {response.EventType} with args: {string.Join(", ", response.Args)}");
}
}
finally
{
await Task.Delay(TimeSpan.FromMilliseconds(HeartbeatInterval));
}
}
}
public async Task ShutdownAsync()
{
await _channel.ShutdownAsync();
}
private string GetSystemUUID()
{
try
{
using (var searcher = new ManagementObjectSearcher("SELECT UUID FROM Win32_ComputerSystemProduct"))
{
foreach (var mo in searcher.Get())
{
return mo["UUID"].ToString();
}
}
}
catch (Exception ex)
{
logger.LogInformation($"An error occurred while retrieving the system UUID: {ex.Message}");
}
return "UNKNOWN";
}
}
}

View File

@ -0,0 +1,62 @@
using Microsoft.Extensions.Logging;
using System.IO;
using System;
namespace WelsonJS.Service.Logging
{
public class FileLogger : ILogger
{
private string loggingDirectory;
private string categoryName;
private static object _lock = new object();
public FileLogger(string _loggingDirectory, string _categoryName = "welsonjs")
{
loggingDirectory = _loggingDirectory;
categoryName = _categoryName;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
//return logLevel == LogLevel.Trace;
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (formatter != null)
{
lock (_lock)
{
try
{
if (!Directory.Exists(loggingDirectory))
{
Directory.CreateDirectory(loggingDirectory);
}
string path = Path.Combine(loggingDirectory, $"{categoryName}_service.{DateTime.Now.ToString("yyyy-MM-dd")}.log");
string nl = Environment.NewLine;
string err = "";
if (exception != null)
{
err = nl + exception.GetType() + ": " + exception.Message + nl + exception.StackTrace + nl;
}
File.AppendAllText(path, logLevel.ToString() + ": [" + DateTime.Now.ToString() + "] " + formatter(state, exception) + nl + err);
}
catch (Exception ex)
{
Console.WriteLine(LogLevel.Warning.ToString() + ": [" + DateTime.Now.ToString() + "] Failed to write a log file. " + ex.Message);
}
}
}
}
}
}

View File

@ -0,0 +1,13 @@
using Microsoft.Extensions.Logging;
namespace WelsonJS.Service.Logging
{
public static class FileLoggerExtensions
{
public static ILoggerFactory AddDirectory(this ILoggerFactory factory, string loggingDirectory)
{
factory.AddProvider(new FileLoggerProvider(loggingDirectory));
return factory;
}
}
}

View File

@ -0,0 +1,24 @@
using Microsoft.Extensions.Logging;
namespace WelsonJS.Service.Logging
{
public class FileLoggerProvider : ILoggerProvider
{
private string loggingDirectory;
public FileLoggerProvider(string _loggingDirectory)
{
loggingDirectory = _loggingDirectory;
}
public ILogger CreateLogger(string categoryName)
{
return new FileLogger(loggingDirectory, categoryName);
}
public void Dispose()
{
// Dispose
}
}
}

View File

@ -0,0 +1,13 @@
using System;
namespace WelsonJS.Service.Model
{
public class FileMatchResult
{
public string Id { get; set; }
public string FilePath { get; set; }
public ulong Offset { get; set; }
public string RuleName { get; set; }
public DateTime LastChecked { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Drawing;
namespace WelsonJS.Service
{
public class ScreenMatchResult
{
public string FileName { get; set; }
public int ScreenNumber { get; set; }
public IntPtr WindowHandle { get; set; }
public string WindowTitle { get; set; }
public string ProcessName { get; set; }
public Point WindowPosition { get; set; }
public Point Position { get; set; }
public string Text { get; set; }
public override string ToString()
{
return $"Template: {FileName}, Screen Number: {ScreenNumber}, Window Title: {WindowTitle}, " +
$"Process Name: {ProcessName}, Window Position: (x: {WindowPosition.X}, y: {WindowPosition.Y}), " +
$"Location: (x: {Position.X}, y: {Position.Y})";
}
}
}

View File

@ -0,0 +1,63 @@
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.ServiceProcess;
using WelsonJS.Service.Logging;
namespace WelsonJS.Service
{
internal static class Program
{
private static ILogger logger;
/// <summary>
/// 해당 애플리케이션의 주 진입점입니다.
/// </summary>
///
static void Main(string[] args)
{
// create the logger
ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
factory.AddDirectory(Path.GetTempPath());
logger = factory.CreateLogger("welsonjs");
// create the service
if (Environment.UserInteractive)
{
Console.WriteLine("WelsonJS Service Application (User Interactive Mode)");
Console.WriteLine("https://github.com/gnh1201/welsonjs");
Console.WriteLine();
Console.WriteLine("Service is running...");
ServiceMain svc = new ServiceMain(args, logger);
svc.TestStartupAndStop();
}
else
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new ServiceMain(args, logger)
};
ServiceBase.Run(ServicesToRun);
}
}
public static string GetAppDataPath()
{
string path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"WelsonJS"
);
Directory.CreateDirectory(path);
if (!Directory.Exists(path))
{
throw new IOException("Failed to create directory: " + path);
}
return path;
}
}
}

View File

@ -0,0 +1,61 @@
namespace WelsonJS.Service
{
partial class ProjectInstaller
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
//
// serviceInstaller1
//
this.serviceInstaller1.Description = "WelsonJS is the framework to build a Windows app on the Windows built-in JavaScri" +
"pt engine.";
this.serviceInstaller1.DisplayName = "WelsonJS.Service";
this.serviceInstaller1.ServiceName = "WelsonJS.Service";
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});
}
#endregion
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
private System.ServiceProcess.ServiceInstaller serviceInstaller1;
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
namespace WelsonJS.Service
{
[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="serviceProcessInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="serviceInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>195, 17</value>
</metadata>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("WelsonJS.Service")]
[assembly: AssemblyDescription("Windows Service for WelsonJS framework based applications")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Catswords")]
[assembly: AssemblyProduct("WelsonJS")]
[assembly: AssemblyCopyright("Catswords OSS, GPLv3 or Ms-RL")]
[assembly: AssemblyTrademark("WelsonJS")]
[assembly: AssemblyCulture("")]
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
[assembly: ComVisible(false)]
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
[assembly: Guid("09f295ee-5edb-4327-abbe-ddccdf5edd9e")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.7.54")]
[assembly: AssemblyFileVersion("0.2.7.54")]

View File

@ -0,0 +1,27 @@
syntax = "proto3";
option csharp_namespace = "WelsonJS.Service";
package heartbeat;
service HeartbeatService {
rpc CheckHeartbeat (stream HeartbeatRequest) returns (stream HeartbeatResponse);
rpc FetchPendingEvents (FetchEventsRequest) returns (stream FetchEventsResponse);
}
message HeartbeatRequest {
bool is_alive = 1;
}
message HeartbeatResponse {
bool is_alive = 1;
}
message FetchEventsRequest {
string client_id = 1;
}
message FetchEventsResponse {
string event_type = 1;
repeated string args = 2;
}

View File

@ -0,0 +1,927 @@
// ScreenMatching.cs
// https://github.com/gnh1201/welsonjs
// https://catswords-oss.rdbl.io/5719744820/8803957194
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Hashing;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Linq;
using Tesseract;
using WelsonJS.Service;
using Microsoft.Extensions.Logging;
public class ScreenMatch
{
// User32.dll API 함수 선언
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")]
private static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("gdi32.dll")]
private static extern bool BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);
// https://stackoverflow.com/questions/60872044/how-to-get-scaling-factor-for-each-monitor-e-g-1-1-25-1-5
[StructLayout(LayoutKind.Sequential)]
private struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public ScreenOrientation dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
private const int SRCCOPY = 0x00CC0020;
// 델리게이트 선언
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
// RECT 구조체 선언
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
private ServiceMain parent;
private ILogger logger;
private List<Bitmap> templateImages;
private string templateDirectoryPath;
private string outputDirectoryPath;
private int templateCurrentIndex = 0;
private double threshold = 0.3;
private string mode;
private bool busy;
private List<string> _params = new List<string>();
private bool isSearchFromEnd = false;
private bool isSaveToFile = false;
private Size sampleSize;
private int sampleAdjustX;
private int sampleAdjustY;
private List<string> sampleAny;
private List<string> sampleClipboard;
private List<string> sampleOcr;
private List<string> sampleNodup;
private Size sampleNodupSize;
private Queue<Bitmap> outdatedSamples;
private string tesseractDataPath;
private string tesseractLanguage;
private void SetBusy(bool busy)
{
this.busy = busy;
logger.LogInformation($"State changed: busy={busy}");
}
private decimal GetScreenScalingFactor(Screen screen)
{
DEVMODE dm = new DEVMODE();
dm.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
EnumDisplaySettings(screen.DeviceName, -1, ref dm);
decimal scalingFactor = Math.Round(Decimal.Divide(dm.dmPelsWidth, screen.Bounds.Width), 2);
if (scalingFactor > 1)
{
logger.LogInformation($"Screen with scaling detected: {scalingFactor}x");
logger.LogWarning("Please check the screen DPI.");
}
return scalingFactor;
}
public class TemplateInfo
{
public string FileName { get; set; }
public int Index { get; set; }
public TemplateInfo(string fileName, int index)
{
FileName = fileName;
Index = index;
}
}
public class SampleInfo
{
public string FileName { get; set; }
public uint Crc32 { get; set; }
public SampleInfo(string fileName, uint crc32)
{
FileName = fileName;
Crc32 = crc32;
}
}
public ScreenMatch(ServiceBase _parent, string workingDirectory, ILogger _logger)
{
parent = (ServiceMain)_parent;
logger = _logger;
SetBusy(false);
templateDirectoryPath = Path.Combine(workingDirectory, "app/assets/img/_templates");
outputDirectoryPath = Path.Combine(workingDirectory, "app/assets/img/_captured");
templateImages = new List<Bitmap>();
// Initialize variables for sampling process
sampleSize = new Size
{
Width = 128,
Height = 128
};
sampleAdjustX = 0;
sampleAdjustY = 0;
sampleAny = new List<string>();
sampleClipboard = new List<string>();
sampleOcr = new List<string>();
sampleNodup = new List<string>();
sampleNodupSize = new Size
{
Width = 180,
Height = 60
};
outdatedSamples = new Queue<Bitmap>();
// Read values from configration file
string screen_time_mode;
string screen_time_params;
try
{
screen_time_mode = parent.ReadSettingsValue("SCREEN_TIME_MODE");
screen_time_params = parent.ReadSettingsValue("SCREEN_TIME_PARAMS");
}
catch (Exception ex)
{
screen_time_mode = null;
screen_time_params = null;
logger.LogInformation($"Failed to read from configration file: {ex.Message}");
}
if (!String.IsNullOrEmpty(screen_time_params))
{
var screen_time_configs = screen_time_params
.Split(',')
.Select(pair => pair.Split('='))
.ToDictionary(
parts => parts[0],
parts => parts.Length > 1 ? parts[1] : parts[0]
);
var config_keys = new string[]
{
"process_name",
"sample_width",
"sample_height",
"sample_adjust_x",
"sample_adjust_y",
"sample_any",
"sample_nodup",
"backward",
"save",
"sample_clipboard",
"sample_ocr"
};
foreach (var config_key in config_keys)
{
string config_value;
screen_time_configs.TryGetValue(config_key, out config_value);
if (config_value != null)
{
switch (config_key)
{
case "backward":
{
isSearchFromEnd = true;
logger.LogInformation("Use the backward search when screen time");
break;
}
case "save":
{
isSaveToFile = true;
logger.LogInformation("Will be save an image file when capture the screens");
break;
}
case "threshold":
{
double.TryParse(config_value, out double t);
threshold = t;
break;
}
case "sample_clipboard":
{
sampleClipboard = new List<string>(config_value.Split(':'));
break;
}
case "sample_ocr":
{
tesseractDataPath = Path.Combine(workingDirectory, "app/assets/tessdata_best");
tesseractLanguage = "eng";
sampleOcr = new List<string>(config_value.Split(':'));
break;
}
case "sample_width":
{
int.TryParse(config_value, out int w);
sampleSize.Width = w;
break;
}
case "sample_height":
{
int.TryParse(config_value, out int h);
sampleSize.Height = h;
break;
}
case "sample_nodup_width":
{
int.TryParse(config_value, out int w);
sampleNodupSize.Width = w;
break;
}
case "sample_nodup_height":
{
int.TryParse(config_value, out int h);
sampleNodupSize.Height = h;
break;
}
case "sample_adjust_x":
{
int.TryParse(config_value, out sampleAdjustX);
break;
}
case "sample_adjust_y":
{
int.TryParse(config_value, out sampleAdjustY);
break;
}
case "sample_any":
{
sampleAny = new List<string>(config_value.Split(':'));
break;
}
case "sample_nodup":
{
sampleNodup = new List<string>(config_value.Split(':'));
break;
}
}
}
}
}
SetMode(screen_time_mode);
LoadTemplateImages();
}
public void SetMode(string mode)
{
if (!String.IsNullOrEmpty(mode))
{
this.mode = mode;
}
else
{
this.mode = "screen";
}
}
public void SetThreshold(double threshold)
{
this.threshold = threshold;
}
public void LoadTemplateImages()
{
string[] files;
try
{
files = Directory.GetFiles(templateDirectoryPath, "*.png");
}
catch (Exception ex)
{
files = new string[]{};
logger.LogInformation($"Failed to read the directory structure: {ex.Message}");
}
foreach (var file in files)
{
string filename = Path.GetFileName(file);
string realpath;
string altpath = parent.GetUserVariablesHandler().GetValue(filename);
if (!String.IsNullOrEmpty(altpath))
{
realpath = altpath;
logger.LogInformation($"Use the alternative image: {realpath}");
}
else
{
realpath = file;
logger.LogInformation($"Use the default image: {realpath}");
}
Bitmap bitmap = new Bitmap(realpath)
{
Tag = filename
};
if (!filename.StartsWith("no_"))
{
if (filename.StartsWith("binary_"))
{
templateImages.Add(ImageQuantize(bitmap));
}
else
{
templateImages.Add(bitmap);
}
}
}
}
// 캡쳐 및 템플릿 매칭 진행
public List<ScreenMatchResult> CaptureAndMatch()
{
List<ScreenMatchResult> results = new List<ScreenMatchResult>();
if (busy)
{
throw new Exception("Waiting done a previous job...");
}
if (templateImages.Count > 0)
{
SetBusy(true);
switch (mode)
{
case "screen": // 화면 기준
results = CaptureAndMatchAllScreens();
SetBusy(false);
break;
case "window": // 윈도우 핸들 기준
results = CaptureAndMatchAllWindows();
SetBusy(false);
break;
default:
SetBusy(false);
throw new Exception($"Unknown capture mode {mode}");
}
}
return results;
}
// 화면을 기준으로 찾기
public List<ScreenMatchResult> CaptureAndMatchAllScreens()
{
var results = new List<ScreenMatchResult>();
for (int i = 0; i < Screen.AllScreens.Length; i++)
{
Screen screen = Screen.AllScreens[i];
Bitmap mainImage = CaptureScreen(screen);
Bitmap templateImage = templateImages[templateCurrentIndex];
string templateName = templateImage.Tag as string;
TemplateInfo nextTemplateInfo = parent.GetNextTemplateInfo();
Size templateSize = new Size
{
Width = templateImage.Width,
Height = templateImage.Height
};
logger.LogInformation($"Trying match the template {templateName} on the screen {i}...");
if (!String.IsNullOrEmpty(nextTemplateInfo.FileName) && templateName != nextTemplateInfo.FileName)
{
logger.LogInformation($"Ignored the template {templateName}");
break;
}
Bitmap out_mainImage;
string out_filename;
if (templateName.StartsWith("binary_"))
{
out_mainImage = ImageQuantize((Bitmap)mainImage.Clone());
out_filename = $"{DateTime.Now:yyyy-MM-dd hh mm ss} binary.png";
}
else
{
out_mainImage = mainImage;
out_filename = $"{DateTime.Now:yyyy-MM-dd hh mm ss}.png";
}
if (isSaveToFile)
{
string out_filepath = Path.Combine(outputDirectoryPath, out_filename);
((Bitmap)out_mainImage.Clone()).Save(out_filepath);
logger.LogInformation($"Screenshot saved: {out_filepath}");
}
// List to store the positions of matched templates in the main image
List<Point> matchPositions;
// If the index value is negative, retrieve and use an outdated image from the queue
if (nextTemplateInfo.Index < 0)
{
logger.LogInformation($"Finding a previous screen of {nextTemplateInfo.FileName}...");
Bitmap outdatedImage = null;
try
{
// Since outdatedSamples is also used to detect duplicate work, we do not delete tasks with Dequeue.
foreach (var image in outdatedSamples)
{
if (image.Tag != null &&
((SampleInfo)image.Tag).FileName == nextTemplateInfo.FileName)
{
outdatedImage = image;
logger.LogInformation($"Found the previous screen of {nextTemplateInfo.FileName}");
break;
}
}
}
catch (Exception ex)
{
logger.LogInformation($"Error finding a previous screen: {ex.Message}");
}
// Find the matching positions of the outdated image in the main image
if (outdatedImage != null) {
matchPositions = FindTemplate(out_mainImage, outdatedImage);
if (matchPositions.Count > 0)
{
logger.LogInformation("Match found with the outdated image");
}
else
{
logger.LogInformation("No match found with the outdated image");
}
}
else
{
logger.LogInformation("No match found an outdated image");
matchPositions = new List<Point>();
}
}
else
{
// If the index is not negative, use the current image for template matching
matchPositions = FindTemplate(out_mainImage, (Bitmap)templateImage.Clone());
}
foreach (Point matchPosition in matchPositions)
{
try
{
string text = sampleAny.Contains(templateName) ?
InspectSample((Bitmap)mainImage.Clone(), matchPosition, templateSize, templateName, sampleSize) : string.Empty;
results.Add(new ScreenMatchResult
{
FileName = templateName,
ScreenNumber = i,
Position = matchPosition,
Text = text
});
break; // Only one
}
catch (Exception ex)
{
logger.LogInformation($"Ignore the match. {ex.Message}");
}
}
}
if (results.Count > 0)
{
logger.LogInformation("Match found");
}
else
{
logger.LogInformation($"No match found");
}
templateCurrentIndex = ++templateCurrentIndex % templateImages.Count;
return results;
}
public Bitmap CropBitmap(Bitmap bitmap, Point matchPosition, Size templateSize, Size sampleSize, int dx = 0, int dy = 0)
{
// Adjust coordinates to the center
int x = matchPosition.X + (templateSize.Width / 2);
int y = matchPosition.Y + (templateSize.Height / 2);
// Set range of crop image
int cropX = Math.Max((x - sampleSize.Width / 2) + dx, 0);
int cropY = Math.Max((y - sampleSize.Height / 2) + dy, 0);
int cropWidth = Math.Min(sampleSize.Width, bitmap.Width - cropX);
int cropHeight = Math.Min(sampleSize.Height, bitmap.Height - cropY);
Rectangle cropArea = new Rectangle(cropX, cropY, cropWidth, cropHeight);
// Crop image
return bitmap.Clone(cropArea, bitmap.PixelFormat);
}
public string InspectSample(Bitmap bitmap, Point matchPosition, Size templateSize, string templateName, Size sampleSize)
{
if (bitmap == null)
{
throw new ArgumentNullException(nameof(bitmap), "Bitmap cannot be null.");
}
if (matchPosition == null || matchPosition == Point.Empty)
{
throw new ArgumentException("matchPosition cannot be empty.");
}
// initialize the text
string text = "";
// Crop image
Bitmap croppedBitmap = CropBitmap(bitmap, matchPosition, templateSize, sampleSize, sampleAdjustX, sampleAdjustY);
// Save to the outdated samples
if (sampleNodup.Contains(templateName))
{
Bitmap croppedNodupBitmap = CropBitmap(bitmap, matchPosition, templateSize, sampleNodupSize);
uint bitmapCrc32 = ComputeBitmapCrc32(croppedNodupBitmap);
croppedNodupBitmap.Tag = new SampleInfo(templateName, bitmapCrc32);
bool bitmapExists = outdatedSamples.Any(x => ((SampleInfo)x.Tag).Crc32 == bitmapCrc32);
if (bitmapExists)
{
throw new InvalidOperationException($"This may be a duplicate request. {templateName}");
}
else
{
outdatedSamples.Enqueue(croppedNodupBitmap);
logger.LogInformation($"Added to the image queue. {templateName}");
}
}
// if use Clipboard
if (sampleClipboard.Contains(templateName))
{
logger.LogInformation($"Trying to use the clipboard... {templateName}");
Thread th = new Thread(new ThreadStart(() =>
{
try
{
Clipboard.SetImage((Bitmap)croppedBitmap.Clone());
logger.LogInformation($"Copied the image to Clipboard");
}
catch (Exception ex)
{
logger.LogInformation($"Failed to copy to the clipboard: {ex.Message}");
}
}));
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
// if use OCR
if (sampleOcr.Contains(templateName))
{
try
{
using (var engine = new TesseractEngine(tesseractDataPath, tesseractLanguage, EngineMode.Default))
{
using (var page = engine.Process(croppedBitmap))
{
text = page.GetText();
logger.LogInformation($"Mean confidence: {page.GetMeanConfidence()}");
logger.LogInformation($"Text (GetText): {text}");
}
}
}
catch (Exception ex)
{
logger.LogInformation($"Failed to OCR: {ex.Message}");
}
}
return text;
}
public Bitmap CaptureScreen(Screen screen)
{
Rectangle screenSize = screen.Bounds;
decimal scalingFactor = GetScreenScalingFactor(screen);
int adjustedWidth = (int)(screenSize.Width * scalingFactor);
int adjustedHeight = (int)(screenSize.Height * scalingFactor);
Bitmap bitmap = new Bitmap(adjustedWidth, adjustedHeight);
using (Graphics bitmapGraphics = Graphics.FromImage(bitmap))
{
bitmapGraphics.CopyFromScreen(screenSize.Left, screenSize.Top, 0, 0, new Size(adjustedWidth, adjustedHeight));
}
return bitmap;
}
// 윈도우 핸들을 기준으로 찾기
public List<ScreenMatchResult> CaptureAndMatchAllWindows()
{
var results = new List<ScreenMatchResult>();
// 모든 윈도우 핸들을 열거
EnumWindows((hWnd, lParam) =>
{
if (IsWindowVisible(hWnd))
{
try
{
string windowTitle = GetWindowTitle(hWnd);
string processName = GetProcessName(hWnd);
GetWindowRect(hWnd, out RECT windowRect);
Point windowPosition = new Point(windowRect.Left, windowRect.Top);
Bitmap windowImage = CaptureWindow(hWnd);
if (windowImage != null)
{
Bitmap image = templateImages[templateCurrentIndex];
string templateName = image.Tag as string;
Size templateSize = new Size
{
Width = image.Width,
Height = image.Height
};
List<Point> matchPositions = FindTemplate(windowImage, image);
matchPositions.ForEach((matchPosition) =>
{
try
{
string text = sampleAny.Contains(templateName) ?
InspectSample((Bitmap)windowImage.Clone(), matchPosition, templateSize, templateName, sampleSize) : string.Empty;
results.Add(new ScreenMatchResult
{
FileName = templateName,
WindowHandle = hWnd,
WindowTitle = windowTitle,
ProcessName = processName,
WindowPosition = windowPosition,
Position = matchPosition,
Text = text
});
}
catch (Exception ex)
{
logger.LogInformation($"Ignore the match. {ex.Message}");
}
});
}
}
catch (Exception ex) {
logger.LogInformation($"Error {ex.Message}");
}
}
return true;
}, IntPtr.Zero);
templateCurrentIndex = ++templateCurrentIndex % templateImages.Count;
return results;
}
public string GetWindowTitle(IntPtr hWnd)
{
int length = GetWindowTextLength(hWnd);
StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
public string GetProcessName(IntPtr hWnd)
{
uint processId;
GetWindowThreadProcessId(hWnd, out processId);
Process process = Process.GetProcessById((int)processId);
return process.ProcessName;
}
public Bitmap CaptureWindow(IntPtr hWnd)
{
GetWindowRect(hWnd, out RECT rect);
int width = rect.Right - rect.Left;
int height = rect.Bottom - rect.Top;
if (width <= 0 || height <= 0)
return null;
Bitmap bitmap = new Bitmap(width, height);
Graphics graphics = Graphics.FromImage(bitmap);
IntPtr hDC = graphics.GetHdc();
IntPtr windowDC = GetDC(hWnd);
bool success = BitBlt(hDC, 0, 0, width, height, windowDC, 0, 0, SRCCOPY);
ReleaseDC(hWnd, windowDC);
graphics.ReleaseHdc(hDC);
return success ? bitmap : null;
}
public List<Point> FindTemplate(Bitmap mainImage, Bitmap templateImage)
{
var matches = new List<Point>();
int mainWidth = mainImage.Width;
int mainHeight = mainImage.Height;
int templateWidth = templateImage.Width;
int templateHeight = templateImage.Height;
int startX = isSearchFromEnd ? mainWidth - templateWidth : 0;
int endX = isSearchFromEnd ? -1 : mainWidth - templateWidth + 1;
int stepX = isSearchFromEnd ? -1 : 1;
int startY = isSearchFromEnd ? mainHeight - templateHeight : 0;
int endY = isSearchFromEnd ? -1 : mainHeight - templateHeight + 1;
int stepY = isSearchFromEnd ? -1 : 1;
for (int x = startX; x != endX; x += stepX)
{
for (int y = startY; y != endY; y += stepY)
{
if (IsTemplateMatch(mainImage, templateImage, x, y, threshold))
{
matches.Add(new Point(x, y));
}
}
}
return matches;
}
private bool IsTemplateMatch(Bitmap mainImage, Bitmap templateImage, int offsetX, int offsetY, double threshold)
{
int templateWidth = templateImage.Width;
int templateHeight = templateImage.Height;
int totalPixels = templateWidth * templateHeight;
int requiredMatches = (int)(totalPixels * threshold);
// When the square root of the canvas size of the image to be matched is less than 10, a complete match is applied.
if (Math.Sqrt(templateWidth * templateHeight) < 10.0)
{
for (int y = 0; y < templateHeight; y++)
{
for (int x = 0; x < templateWidth; x++)
{
if (mainImage.GetPixel(x + offsetX, y + offsetY) != templateImage.GetPixel(x, y))
{
return false;
}
}
}
return true;
}
// Otherwise, randomness is used.
int matchedCount = 0;
Random rand = new Random();
while (matchedCount < requiredMatches)
{
int x = rand.Next(templateWidth);
int y = rand.Next(templateHeight);
if (mainImage.GetPixel(x + offsetX, y + offsetY) != templateImage.GetPixel(x, y))
{
return false;
}
matchedCount++;
}
return true;
}
private Bitmap ImageQuantize(Bitmap image, int levels = 4)
{
Bitmap quantizedImage = new Bitmap(image.Width, image.Height);
if (image.Tag != null)
{
quantizedImage.Tag = image.Tag;
}
int step = 255 / (levels - 1); // step by step..... ooh baby...(?)
for (int y = 0; y < image.Height; y++)
{
for (int x = 0; x < image.Width; x++)
{
// Convert the pixel to grayscale
Color pixelColor = image.GetPixel(x, y);
byte grayValue = (byte)((pixelColor.R + pixelColor.G + pixelColor.B) / 3);
// Convert the grayscale value to the quantize value
byte quantizedValue = (byte)((grayValue / step) * step);
// Renew the colors
Color quantizedColor = Color.FromArgb(quantizedValue, quantizedValue, quantizedValue);
quantizedImage.SetPixel(x, y, quantizedColor);
}
}
return quantizedImage;
}
private uint ComputeBitmapCrc32(Bitmap bitmap)
{
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] bitmapBytes = ms.ToArray();
Crc32 crc32 = new Crc32();
crc32.Append(bitmapBytes);
return BitConverter.ToUInt32(crc32.GetCurrentHash(), 0);
}
}
}

View File

@ -0,0 +1,40 @@
namespace WelsonJS.Service
{
partial class ServiceMain
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
//
// ServiceMain
//
this.ServiceName = "ServiceMain";
}
#endregion
}
}

View File

@ -0,0 +1,496 @@
/*
* WelsonJS.Service
*
* filename:
* ServiceMain.cs
*
* description:
* WelsonJS - Build a Windows app on the Windows built-in JavaScript engine
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
*
* author:
* Namhyeon Go <abuse@catswords.net>
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
* references:
* - https://learn.microsoft.com/en-us/dotnet/framework/windows-services/how-to-debug-windows-service-applications
* - https://stackoverflow.com/questions/6490979/how-to-pass-parameters-to-windows-service
* - https://stackoverflow.com/questions/42812333/pass-an-argument-to-a-windows-service-at-automatic-startup
* - https://learn.microsoft.com/ko-kr/windows/win32/api/winuser/nf-winuser-getsystemmetrics
*/
using System;
using System.ServiceProcess;
using System.Timers;
using System.Runtime.InteropServices;
using MSScriptControl;
using System.IO;
using System.Collections.Generic;
using WelsonJS.TinyINIController;
using System.Collections;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace WelsonJS.Service
{
public partial class ServiceMain : ServiceBase
{
private readonly static string applicationName = "WelsonJS";
private static List<Timer> timers;
private ILogger logger;
private string workingDirectory;
private string scriptName;
private string scriptFilePath;
private string scriptText;
private ScriptControl scriptControl;
private string[] args;
private bool disabledHeartbeat = false;
private bool disabledScreenTime = false;
private bool disabledFileMonitor = false;
private ScreenMatch screenMatcher;
private FileEventMonitor fileEventMonitor;
private IniFile settingsFileHandler;
private UserVariables userVariablesHandler;
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int nIndex);
private static int SM_REMOTESESSION = 0x1000;
public ServiceMain(string[] _args, ILogger _logger)
{
InitializeComponent();
// set arguments and logger
args = _args;
logger = _logger;
// mapping arguments to each variables
var arguments = ParseArguments(this.args);
foreach (KeyValuePair<string, string> entry in arguments)
{
switch (entry.Key)
{
case "working-directory":
workingDirectory = entry.Value;
break;
case "script-name":
scriptName = entry.Value;
break;
case "disable-heartbeat":
disabledHeartbeat = true;
break;
case "disable-screen-time":
disabledScreenTime = true;
break;
case "disable-file-monitor":
disabledFileMonitor = true;
break;
}
}
// load the user variables
userVariablesHandler = new UserVariables(this);
userVariablesHandler.Load();
// set timers
timers = new List<Timer>();
// set working directory
if (string.IsNullOrEmpty(workingDirectory))
{
workingDirectory = Path.Combine(Path.GetTempPath(), applicationName);
logger.LogInformation("Working directory not provided. Using default value: " + workingDirectory);
if (!Directory.Exists(workingDirectory))
{
Directory.CreateDirectory(workingDirectory);
logger.LogInformation("Directory created: " + workingDirectory);
}
}
Directory.SetCurrentDirectory(workingDirectory);
// read settings.ini
string settingsFilePath = Path.Combine(workingDirectory, "settings.ini");
if (File.Exists(settingsFilePath))
{
try
{
settingsFileHandler = new IniFile(settingsFilePath);
}
catch (Exception ex)
{
logger.LogWarning(ex.Message);
}
}
else
{
logger.LogInformation($"Configuration file not found: {settingsFilePath}");
}
// read configrations from settings.ini
if (settingsFileHandler != null)
{
string[] configNames = new string[]
{
"DISABLE_HEARTBEAT",
"DISABLE_SCREEN_TIME",
"DISABLE_FILE_MONITOR"
};
foreach (string configName in configNames)
{
try
{
if ("true" == ReadSettingsValue(configName))
{
switch (configName)
{
case "DISABLE_HEARTBEAT":
disabledHeartbeat = true;
break;
case "DISABLE_SCREEN_TIME":
disabledScreenTime = true;
break;
case "DISABLE_FILE_MONITOR":
disabledFileMonitor = true;
break;
default:
break;
}
}
}
catch (Exception ex)
{
logger.LogInformation($"{configName} is ignored: {ex.Message}");
}
}
}
// set script name
if (string.IsNullOrEmpty(scriptName))
{
scriptName = "defaultService";
logger.LogInformation($"Script name not provided. Using default value: {scriptName}");
}
// set path of the script
scriptFilePath = Path.Combine(workingDirectory, "app.js");
// start the heartbeat
if (!disabledHeartbeat)
{
HeartbeatClient heartbeatClient = new HeartbeatClient(this, logger);
Task.Run(heartbeatClient.StartHeartbeatAsync);
Task.Run(heartbeatClient.StartEventListenerAsync);
}
// set default timer
Timer defaultTimer = new Timer
{
Interval = 60000 // 1 minute
};
defaultTimer.Elapsed += OnElapsedTime;
timers.Add(defaultTimer);
// check this session is the user interactive mode
if (Environment.UserInteractive) {
OnUserInteractiveEnvironment();
}
else
{
logger.LogInformation("Disabled the User Interactive Mode. (e.g., OnScreenTime)");
}
logger.LogInformation(applicationName + " Service Loaded");
}
public string ReadSettingsValue(string key, string defaultValue = null)
{
if (settingsFileHandler != null)
{
return settingsFileHandler.Read(key, "Service") ?? defaultValue;
}
else
{
logger.LogWarning("Unable to read the value. It seems that settings.ini is not configured correctly.");
return defaultValue;
}
}
public UserVariables GetUserVariablesHandler()
{
return userVariablesHandler;
}
internal void TestStartupAndStop()
{
this.OnStart(this.args);
Console.ReadLine();
this.OnStop();
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
// Check exists the entry script file
if (File.Exists(scriptFilePath))
{
logger.LogInformation($"Script file found: {scriptFilePath}");
try
{
// load the script
scriptText = File.ReadAllText(scriptFilePath);
scriptControl = new ScriptControl
{
Language = "JScript",
AllowUI = false
};
scriptControl.Reset();
scriptControl.AddCode(scriptText);
// make the start arguments
string[] startArguments;
string[] _args;
if (Environment.UserInteractive)
{
_args = new string[]
{
$"--env-file={userVariablesHandler.GetEnvFilePath()}",
"--user-interactive"
};
}
else
{
_args = new string[]
{
$"--env-file={userVariablesHandler.GetEnvFilePath()}"
};
}
startArguments = new string[args.Length + _args.Length];
args.CopyTo(startArguments, 0);
for (int i = 0; i < _args.Length; i++)
{
startArguments[args.Length + i] = _args[i];
}
// initialize
logger.LogInformation(DispatchServiceEvent("start", startArguments));
}
catch (Exception ex)
{
logger.LogInformation($"Failed to start because of {ex.Message}");
}
}
else
{
logger.LogInformation($"Script file not found: {scriptFilePath}");
}
// Trace a Sysmon file events (If Sysinternals Sysmon installed)
if (!disabledFileMonitor)
{
fileEventMonitor = new FileEventMonitor(this, workingDirectory, logger);
fileEventMonitor.Start();
logger.LogInformation("File Event Monitor Started");
}
else
{
logger.LogInformation("File Event Monitor is Disabled");
}
// Start all the registered timers
timers.ForEach(timer => timer?.Start());
logger.LogInformation(applicationName + " Service Started");
}
protected override void OnStop()
{
// stop timers
timers.ForEach(timer => timer?.Stop());
// stop the File Event Monitor
fileEventMonitor?.Stop();
// dispatch stop callback
try
{
logger.LogInformation(DispatchServiceEvent("stop"));
scriptControl?.Reset();
}
catch (Exception ex)
{
logger.LogInformation("Exception when stop: " + ex.Message);
}
scriptControl = null;
logger.LogInformation(applicationName + " Service Stopped");
}
private void OnUserInteractiveEnvironment()
{
// check is it a remote desktop session
if (GetSystemMetrics(SM_REMOTESESSION) > 0)
{
disabledScreenTime = true;
logger.LogInformation("This application may not work correctly in a remote desktop session");
}
// set screen timer
if (!disabledScreenTime)
{
screenMatcher = new ScreenMatch(this, workingDirectory, logger);
Timer screenTimer = new Timer
{
Interval = 1000 // 1 seconds
};
screenTimer.Elapsed += OnScreenTime;
timers.Add(screenTimer);
logger.LogInformation("Screen Time Event Enabled");
}
else
{
disabledScreenTime = true;
logger.LogInformation("Screen Time Event Disabled");
}
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
try
{
logger.LogInformation(DispatchServiceEvent("elapsedTime"));
}
catch (Exception ex)
{
logger.LogInformation("Exception when elapsed time: " + ex.Message);
}
}
private void OnScreenTime(object source, ElapsedEventArgs e)
{
try
{
List<ScreenMatchResult> matchedResults = screenMatcher.CaptureAndMatch();
matchedResults.ForEach(result =>
{
logger.LogInformation(DispatchServiceEvent("screenTemplateMatched", new string[]
{
result.FileName,
result.ScreenNumber.ToString(),
result.Position.X.ToString(),
result.Position.Y.ToString()
}));
});
}
catch (Exception ex)
{
logger.LogInformation($"Waiting a next screen time... {ex.Message}");
}
}
private string InvokeScriptMethod(string methodName, string scriptName, string eventType, string[] args)
{
if (scriptControl != null)
{
object[] parameters = new object[] {
scriptName,
eventType,
new ArrayList(args),
args.Length
};
//scriptControl.AddObject("extern_arguments", new ArrayList(args), true);
return scriptControl.Run(methodName, parameters)?.ToString() ?? "void";
}
else
{
logger.LogInformation("InvokeScriptMethod Ignored: " + methodName);
}
return "void";
}
private Dictionary<string, string> ParseArguments(string[] args)
{
var arguments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (string arg in args)
{
if (arg.StartsWith("--"))
{
var index = arg.IndexOf('=');
if (index > 2)
{
var key = arg.Substring(2, index - 2);
var value = arg.Substring(index + 1).Trim('"');
arguments[key] = value;
}
else
{
var key = arg.Substring(2, index - 2);
arguments[key] = "";
}
}
}
return arguments;
}
public ScreenMatch.TemplateInfo GetNextTemplateInfo()
{
string templateName = string.Empty;
int index = 0;
try
{
templateName = DispatchServiceEvent("screenNextTemplate");
// Check if the received value contains an index
string[] parts = templateName.Split(':');
if (parts.Length > 1)
{
templateName = parts[0];
int.TryParse(parts[1], out index);
}
}
catch (Exception ex)
{
logger.LogInformation($"Use all templates because of {ex.Message}");
}
return new ScreenMatch.TemplateInfo(templateName, index);
}
public string DispatchServiceEvent(string eventType, string[] args = null)
{
if (args == null)
{
return InvokeScriptMethod("dispatchServiceEvent", scriptName, eventType, new string[] { });
}
else
{
return InvokeScriptMethod("dispatchServiceEvent", scriptName, eventType, args);
}
}
}
}

View File

@ -0,0 +1,82 @@
using System.Collections.Generic;
using System;
using System.IO;
using System.ServiceProcess;
namespace WelsonJS.Service
{
public class UserVariables
{
private ServiceMain parent;
private Dictionary<string, string> userVariables;
private string envFilePath;
public UserVariables(ServiceBase parent)
{
envFilePath = Path.Combine(Program.GetAppDataPath(), "welsonjs_default.env");
this.parent = (ServiceMain)parent;
}
// Load user-defined variables from the temporary folder in .env format
public void Load()
{
if (File.Exists(envFilePath))
{
try
{
string fileContent = File.ReadAllText(envFilePath);
// Split based on new line characters
string[] keyValuePairs = fileContent.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
userVariables = new Dictionary<string, string>();
foreach (string pair in keyValuePairs)
{
// Split by the first occurrence of '='
int indexOfEquals = pair.IndexOf('=');
if (indexOfEquals != -1)
{
string key = pair.Substring(0, indexOfEquals).Trim();
string value = pair.Substring(indexOfEquals + 1).Trim();
// Remove surrounding quotes if present
if (value.StartsWith("\"") && value.EndsWith("\""))
{
value = value.Substring(1, value.Length - 2); // Remove the first and last character
}
// Unescape double quotes in the value
value = value.Replace("\\\"", "\"");
userVariables[key] = value;
}
else
{
throw new Exception($"Error parsing line: '{pair}'.");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading variable file: {ex.Message}");
userVariables = new Dictionary<string, string>();
}
}
else
{
userVariables = new Dictionary<string, string>();
}
}
public string GetValue(string name)
{
userVariables.TryGetValue(name, out string value);
return value;
}
public string GetEnvFilePath()
{
return envFilePath;
}
}
}

View File

@ -0,0 +1,300 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Grpc.Tools.2.67.0\build\Grpc.Tools.props" Condition="Exists('..\packages\Grpc.Tools.2.67.0\build\Grpc.Tools.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>WelsonJS.Service</RootNamespace>
<AssemblyName>WelsonJS.Service</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<PublishUrl>게시\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="ClamAV.Net, Version=0.1.166.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClamAV.Net.0.1.166\lib\netstandard2.0\ClamAV.Net.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf, Version=3.28.2.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.28.2\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<HintPath>..\packages\Grpc.Core.2.46.6\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core.Api, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<HintPath>..\packages\Grpc.Core.Api.2.66.0\lib\net462\Grpc.Core.Api.dll</HintPath>
</Reference>
<Reference Include="Grpc.Net.Client, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<HintPath>..\packages\Grpc.Net.Client.2.66.0\lib\net462\Grpc.Net.Client.dll</HintPath>
</Reference>
<Reference Include="Grpc.Net.Client.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<HintPath>..\packages\Grpc.Net.Client.Web.2.66.0\lib\netstandard2.0\Grpc.Net.Client.Web.dll</HintPath>
</Reference>
<Reference Include="Grpc.Net.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<HintPath>..\packages\Grpc.Net.Common.2.66.0\lib\netstandard2.0\Grpc.Net.Common.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Extensions.Configuration, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.8.0.0\lib\net462\Microsoft.Extensions.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.Abstractions.8.0.0\lib\net462\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Binder, Version=8.0.0.2, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.Binder.8.0.2\lib\net462\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection, Version=8.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.8.0.1\lib\net462\Microsoft.Extensions.DependencyInjection.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.2, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.8.0.2\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging, Version=8.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.8.0.1\lib\net462\Microsoft.Extensions.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=8.0.0.2, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.8.0.2\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Configuration, Version=8.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Configuration.8.0.1\lib\net462\Microsoft.Extensions.Logging.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Console, Version=8.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Console.8.0.1\lib\net462\Microsoft.Extensions.Logging.Console.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options, Version=8.0.0.2, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Options.8.0.2\lib\net462\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.8.0.0\lib\net462\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Primitives.8.0.0\lib\net462\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="RestSharp, Version=112.1.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.112.1.0\lib\net48\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Data" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=8.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.8.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Hashing, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Hashing.8.0.0\lib\net462\System.IO.Hashing.dll</HintPath>
</Reference>
<Reference Include="System.Management" />
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WinHttpHandler, Version=8.0.0.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.Http.WinHttpHandler.8.0.2\lib\net462\System.Net.Http.WinHttpHandler.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=8.0.0.5, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.8.0.5\lib\net462\System.Text.Json.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Tesseract, Version=5.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Tesseract.5.2.0\lib\net48\Tesseract.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="FileEventMonitor.cs" />
<Compile Include="HeartbeatClient.cs" />
<Compile Include="Logging\FileLogger.cs" />
<Compile Include="Logging\FileLoggerExtensions.cs" />
<Compile Include="Logging\FileLoggerProvider.cs" />
<Compile Include="Model\FileMatchResult.cs" />
<Compile Include="ServiceMain.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ServiceMain.Designer.cs">
<DependentUpon>ServiceMain.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="ProjectInstaller.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ProjectInstaller.Designer.cs">
<DependentUpon>ProjectInstaller.cs</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScreenMatch.cs" />
<Compile Include="Model\ScreenMatchResult.cs" />
<Compile Include="UserVariables.cs" />
</ItemGroup>
<ItemGroup>
<COMReference Include="MSScriptControl">
<Guid>{0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
<Private>True</Private>
</COMReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ProjectInstaller.resx">
<DependentUpon>ProjectInstaller.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WelsonJS.Toolkit\WelsonJS.Toolkit.csproj">
<Project>{d6007282-b4f7-4694-ac67-bb838d91b77a}</Project>
<Name>WelsonJS.Toolkit</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.8">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.8%28x86 및 x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="favicon.ico" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\heartbeat.proto" GrpcServices="Client" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>이 프로젝트는 이 컴퓨터에 없는 NuGet 패키지를 참조합니다. 해당 패키지를 다운로드하려면 NuGet 패키지 복원을 사용하십시오. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=322105를 참조하십시오. 누락된 파일은 {0}입니다.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.2.46.6\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.2.46.6\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Tesseract.5.2.0\build\Tesseract.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Tesseract.5.2.0\build\Tesseract.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Tools.2.67.0\build\Grpc.Tools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.67.0\build\Grpc.Tools.props'))" />
<Error Condition="!Exists('..\packages\Grpc.Tools.2.67.0\build\Grpc.Tools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.67.0\build\Grpc.Tools.targets'))" />
</Target>
<Import Project="..\packages\Grpc.Core.2.46.6\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.2.46.6\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Tesseract.5.2.0\build\Tesseract.targets" Condition="Exists('..\packages\Tesseract.5.2.0\build\Tesseract.targets')" />
<Import Project="..\packages\Grpc.Tools.2.67.0\build\Grpc.Tools.targets" Condition="Exists('..\packages\Grpc.Tools.2.67.0\build\Grpc.Tools.targets')" />
</Project>

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /></startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.2" newVersion="8.0.0.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.1" newVersion="8.0.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.WinHttpHandler" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.2" newVersion="8.0.0.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="DeviceId" publicKeyToken="f755c371b5c59c52" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.7.0.0" newVersion="6.7.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.27.3.0" newVersion="3.27.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Grpc.Core" publicKeyToken="d754f35622e28bad" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Grpc.Core.Api" publicKeyToken="d754f35622e28bad" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Grpc.Net.Client" publicKeyToken="d754f35622e28bad" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Grpc.Net.Client.Web" publicKeyToken="d754f35622e28bad" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Grpc.Net.Common" publicKeyToken="d754f35622e28bad" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.2" newVersion="8.0.0.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="RestSharp" publicKeyToken="598062e77f915f75" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-112.0.0.0" newVersion="112.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.5" newVersion="8.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.2" newVersion="8.0.0.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Configuration.Binder" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.2" newVersion="8.0.0.2" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ClamAV.Net" version="0.1.166" targetFramework="net48" />
<package id="Google.Protobuf" version="3.28.2" targetFramework="net48" />
<package id="Grpc" version="2.46.6" targetFramework="net48" />
<package id="Grpc.Core" version="2.46.6" targetFramework="net48" />
<package id="Grpc.Core.Api" version="2.66.0" targetFramework="net48" />
<package id="Grpc.Net.Client" version="2.66.0" targetFramework="net48" />
<package id="Grpc.Net.Client.Web" version="2.66.0" targetFramework="net48" />
<package id="Grpc.Net.Common" version="2.66.0" targetFramework="net48" />
<package id="Grpc.Tools" version="2.67.0" targetFramework="net48" developmentDependency="true" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.Configuration" version="8.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.Configuration.Abstractions" version="8.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.Configuration.Binder" version="8.0.2" targetFramework="net48" />
<package id="Microsoft.Extensions.DependencyInjection" version="8.0.1" targetFramework="net48" />
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="8.0.2" targetFramework="net48" />
<package id="Microsoft.Extensions.Logging" version="8.0.1" targetFramework="net48" />
<package id="Microsoft.Extensions.Logging.Abstractions" version="8.0.2" targetFramework="net48" />
<package id="Microsoft.Extensions.Logging.Configuration" version="8.0.1" targetFramework="net48" />
<package id="Microsoft.Extensions.Logging.Console" version="8.0.1" targetFramework="net48" />
<package id="Microsoft.Extensions.Options" version="8.0.2" targetFramework="net48" />
<package id="Microsoft.Extensions.Options.ConfigurationExtensions" version="8.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.Primitives" version="8.0.0" targetFramework="net48" />
<package id="RestSharp" version="112.1.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Diagnostics.DiagnosticSource" version="8.0.1" targetFramework="net48" />
<package id="System.IO.Hashing" version="8.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Net.Http.WinHttpHandler" version="8.0.2" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net48" />
<package id="System.Text.Json" version="8.0.5" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
<package id="Tesseract" version="5.2.0" targetFramework="net48" />
</packages>

View File

@ -1,10 +1,14 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31515.178
# Visual Studio Version 17
VisualStudioVersion = 17.8.34322.80
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelsonJS.Toolkit", "WelsonJS.Toolkit\WelsonJS.Toolkit.csproj", "{D6007282-B4F7-4694-AC67-BB838D91B77A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelsonJS.Service", "WelsonJS.Service\WelsonJS.Service.csproj", "{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelsonJS.Launcher", "WelsonJS.Launcher\WelsonJS.Launcher.csproj", "{4074D413-195C-45E9-9E63-0D07914187B8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -15,10 +19,28 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Debug|x86.ActiveCfg = Debug|x86
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Debug|x86.Build.0 = Debug|x86
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Release|Any CPU.Build.0 = Release|Any CPU
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Release|x86.ActiveCfg = Release|Any CPU
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Release|x86.ActiveCfg = Release|x86
{D6007282-B4F7-4694-AC67-BB838D91B77A}.Release|x86.Build.0 = Release|x86
{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}.Debug|x86.ActiveCfg = Debug|x86
{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}.Debug|x86.Build.0 = Debug|x86
{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}.Release|Any CPU.Build.0 = Release|Any CPU
{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}.Release|x86.ActiveCfg = Release|x86
{09F295EE-5EDB-4327-ABBE-DDCCDF5EDD9E}.Release|x86.Build.0 = Release|x86
{4074D413-195C-45E9-9E63-0D07914187B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4074D413-195C-45E9-9E63-0D07914187B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4074D413-195C-45E9-9E63-0D07914187B8}.Debug|x86.ActiveCfg = Debug|x86
{4074D413-195C-45E9-9E63-0D07914187B8}.Debug|x86.Build.0 = Debug|x86
{4074D413-195C-45E9-9E63-0D07914187B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4074D413-195C-45E9-9E63-0D07914187B8}.Release|Any CPU.Build.0 = Release|Any CPU
{4074D413-195C-45E9-9E63-0D07914187B8}.Release|x86.ActiveCfg = Release|x86
{4074D413-195C-45E9-9E63-0D07914187B8}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,114 @@
/*
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* BitmapUtils.cs
*
* description:
* WelsonJS - Build a Windows app on the Windows built-in JavaScript engine
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
*
* author:
* Namhyeon Go <abuse@catswords.net>
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
*/
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace WelsonJS
{
public class BitmapUtils
{
private static Bitmap Load(string filename)
{
return new Bitmap(filename);
}
public static void Crop(string srcfile, string dstfile, int x, int y, int a, int b)
{
Bitmap originalBitmap = Load(srcfile);
Rectangle cropArea = new Rectangle(x, y, a, b);
Bitmap croppedBitmap = originalBitmap.Clone(cropArea, originalBitmap.PixelFormat);
croppedBitmap.Save(dstfile);
}
public static int[] GetSize(string srcfile)
{
Bitmap bitmap = Load(srcfile);
int width = bitmap.Width;
int height = bitmap.Height;
bitmap.Dispose();
return new int[] { width, height };
}
public static int[] GetPixel(string srcfile, int x, int y)
{
Bitmap bitmap = Load(srcfile);
Color pixelColor = bitmap.GetPixel(x, y);
int red = pixelColor.R;
int green = pixelColor.G;
int blue = pixelColor.B;
bitmap.Dispose();
return new int[] { red, green, blue };
}
public static string GetBase64(string srcfile)
{
Bitmap bitmap = Load(srcfile);
MemoryStream memoryStream = new MemoryStream();
ImageFormat imageFormat;
if (srcfile.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase))
{
imageFormat = ImageFormat.Bmp;
}
else if (srcfile.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || srcfile.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase))
{
imageFormat = ImageFormat.Jpeg;
}
else if (srcfile.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
{
imageFormat = ImageFormat.Png;
}
else if (srcfile.EndsWith(".tiff", StringComparison.OrdinalIgnoreCase))
{
imageFormat = ImageFormat.Tiff;
}
else if (srcfile.EndsWith(".gif", StringComparison.OrdinalIgnoreCase))
{
imageFormat = ImageFormat.Gif;
}
else
{
return "";
}
bitmap.Save(memoryStream, imageFormat);
byte[] imageBytes = memoryStream.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
bitmap.Dispose();
memoryStream.Dispose();
return base64String;
}
}
}

View File

@ -1,15 +1,16 @@
/*
* WelsonJS.Toolkit: WelsonJS dotNET native component
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* LZ77.cs
*
* description:
* WelsonJS - Build a Windows app on the Windows built-in JavaScript engine
*
* MsCompress(LZ77) algorithm implementation for WelsonJS
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
*
* author:
* Namhyeon Go <abuse@catswords.net>

View File

@ -0,0 +1,614 @@
/*
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* ARIA.cs
*
* description:
* ARIA(KS X 1213-1, RFC5794, RFC6209) cryptography algorithm implementation (Experimental)
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
* - https://discord.gg/XKG5CjtXEj
*
* authors:
* - Namhyeon Go (@gnh1201) <abuse@catswords.net>
* - @angelkum (blog.naver.com)
* - KISA(Korea Internet & Security Agency) (kisa.or.kr)
* - National Security Research Institute (NSRI)
* - National Intelligence Service (nis.go.kr)
*
* references:
* - https://seed.kisa.or.kr/kisa/Board/19/detailView.do
* - https://blog.naver.com/angelkum/130154153446
* - https://www.ncsc.go.kr:4018/PageLink.do?link=forward:/PageContent.do&tempParam1=&menuNo=060000&subMenuNo=060200&thirdMenuNo=
* - https://www.nis.go.kr/AF/1_7_3_1.do
* - https://datatracker.ietf.org/doc/html/rfc5794
* - https://datatracker.ietf.org/doc/html/rfc6209
* - https://github.com/eGovFrame/egovframework.rte.root/blob/master/Foundation/egovframework.rte.fdl.crypto/src/main/java/egovframework/rte/fdl/cryptography/impl/aria/ARIAEngine.java
* - https://ics.catswords.net/ARIA-specification.pdf
* - https://ics.catswords.net/ARIA-testvector.pdf
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
*/
using System.Security.Cryptography;
using System.Text;
namespace WelsonJS.Cryptography
{
public class ARIA
{
private static readonly uint[,] KRK = new uint[,] {
{0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0},
{0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0},
{0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e}
};
private static readonly byte[] S1 = new byte[256];
private static readonly byte[] S2 = new byte[256];
private static readonly byte[] X1 = new byte[256];
private static readonly byte[] X2 = new byte[256];
private static readonly uint[] TS1 = new uint[256];
private static readonly uint[] TS2 = new uint[256];
private static readonly uint[] TX1 = new uint[256];
private static readonly uint[] TX2 = new uint[256];
// Static initializer. For setting up the tables
static ARIA()
{
uint[] exp = new uint[256];
uint[] log = new uint[256];
exp[0] = 1;
for (int i = 1; i < 256; i++)
{
uint j = (exp[i - 1] << 1) ^ exp[i - 1];
if ((j & 0x100) != 0) j ^= 0x11b;
exp[i] = j;
}
for (int i = 1; i < 255; i++)
log[exp[i]] = (uint)i;
uint[,] A = new uint[,] {
{1, 0, 0, 0, 1, 1, 1, 1},
{1, 1, 0, 0, 0, 1, 1, 1},
{1, 1, 1, 0, 0, 0, 1, 1},
{1, 1, 1, 1, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 0},
{0, 0, 0, 1, 1, 1, 1, 1}
};
uint[,] B = new uint[,] {
{0, 1, 0, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 0, 1},
{1, 1, 0, 1, 0, 1, 1, 1},
{1, 0, 0, 1, 1, 1, 0, 1},
{0, 0, 1, 0, 1, 1, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 1},
{0, 1, 0, 1, 1, 1, 0, 1},
{1, 1, 0, 1, 0, 0, 1, 1}
};
for (int i = 0; i < 256; i++)
{
uint t = 0, p;
if (i == 0)
p = 0;
else
p = exp[255 - log[i]];
for (int j = 0; j < 8; j++)
{
uint s = 0;
for (int k = 0; k < 8; k++)
{
if (((p >> (7 - k)) & 0x01) != 0)
s ^= A[k, j];
}
t = (t << 1) ^ s;
}
t ^= 0x63;
S1[i] = (byte)t;
X1[t] = (byte)i;
}
for (int i = 0; i < 256; i++)
{
uint t = 0, p;
if (i == 0)
p = 0;
else
p = exp[(247 * log[i]) % 255];
for (int j = 0; j < 8; j++)
{
uint s = 0;
for (int k = 0; k < 8; k++)
{
if (((p >> k) & 0x01) != 0)
s ^= B[7 - j, k];
}
t = (t << 1) ^ s;
}
t ^= 0xe2;
S2[i] = (byte)t;
X2[t] = (byte)i;
}
for (int i = 0; i < 256; i++)
{
TS1[i] = (uint)0x00010101 * (S1[i] & (uint)0xff);
TS2[i] = (uint)0x01000101 * (S2[i] & (uint)0xff);
TX1[i] = (uint)0x01010001 * (X1[i] & (uint)0xff);
TX2[i] = (uint)0x01010100 * (X2[i] & (uint)0xff);
}
}
private int keySize = 0;
private int numberOfRounds = 0;
private byte[] masterKey = null;
private uint[] encRoundKeys = null, decRoundKeys = null;
public ARIA(int keySize)
{
SetKeySize(keySize);
}
/**
* Resets the class so that it can be reused for another master key.
*/
private void Reset()
{
keySize = 0;
numberOfRounds = 0;
masterKey = null;
encRoundKeys = null;
decRoundKeys = null;
}
public int GetKeySize()
{
return keySize;
}
private void SetKeySize(int _keySize)
{
Reset();
if (_keySize != 128 && _keySize != 192 && _keySize != 256)
throw new CryptographicException("keySize=" + _keySize);
switch (_keySize)
{
case 128:
numberOfRounds = 12;
break;
case 192:
numberOfRounds = 14;
break;
case 256:
numberOfRounds = 16;
break;
}
keySize = _keySize;
}
private void SetKey(byte[] masterKey)
{
if (masterKey.Length * 8 < keySize)
throw new CryptographicException("masterKey size=" + masterKey.Length);
decRoundKeys = null;
encRoundKeys = null;
masterKey = (byte[])masterKey.Clone();
}
private void SetupEncRoundKeys()
{
if (keySize == 0)
throw new CryptographicException("keySize");
if (masterKey == null)
throw new CryptographicException("masterKey");
if (encRoundKeys == null)
encRoundKeys = new uint[4 * (numberOfRounds + 1)];
decRoundKeys = null;
DoEncKeySetup(masterKey, encRoundKeys, keySize);
}
void SetupDecRoundKeys()
{
if (keySize == 0)
throw new CryptographicException("keySize");
if (encRoundKeys == null)
{
if (masterKey == null)
{
throw new CryptographicException("masterKey");
}
else
{
SetupEncRoundKeys();
}
}
decRoundKeys = (uint[])encRoundKeys.Clone();
DoDecKeySetup(masterKey, decRoundKeys, keySize);
}
public void SetupRoundKeys()
{
SetupDecRoundKeys();
}
private static void DoCrypt(byte[] i, int ioffset, uint[] rk, int nr, byte[] o, int ooffset)
{
uint t0, t1, t2, t3, j = 0;
t0 = ToInt(i[0 + ioffset], i[1 + ioffset], i[2 + ioffset], i[3 + ioffset]);
t1 = ToInt(i[4 + ioffset], i[5 + ioffset], i[6 + ioffset], i[7 + ioffset]);
t2 = ToInt(i[8 + ioffset], i[9 + ioffset], i[10 + ioffset], i[11 + ioffset]);
t3 = ToInt(i[12 + ioffset], i[13 + ioffset], i[14 + ioffset], i[15 + ioffset]);
for (int r = 1; r < nr / 2; r++)
{
t0 ^= rk[j++]; t1 ^= rk[j++]; t2 ^= rk[j++]; t3 ^= rk[j++];
t0 = TS1[(t0 >> 24) & 0xff] ^ TS2[(t0 >> 16) & 0xff] ^ TX1[(t0 >> 8) & 0xff] ^ TX2[t0 & 0xff];
t1 = TS1[(t1 >> 24) & 0xff] ^ TS2[(t1 >> 16) & 0xff] ^ TX1[(t1 >> 8) & 0xff] ^ TX2[t1 & 0xff];
t2 = TS1[(t2 >> 24) & 0xff] ^ TS2[(t2 >> 16) & 0xff] ^ TX1[(t2 >> 8) & 0xff] ^ TX2[t2 & 0xff];
t3 = TS1[(t3 >> 24) & 0xff] ^ TS2[(t3 >> 16) & 0xff] ^ TX1[(t3 >> 8) & 0xff] ^ TX2[t3 & 0xff];
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t1 = Badc(t1); t2 = Cdab(t2); t3 = Dcba(t3);
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t0 ^= rk[j++]; t1 ^= rk[j++]; t2 ^= rk[j++]; t3 ^= rk[j++];
t0 = TX1[(t0 >> 24) & 0xff] ^ TX2[(t0 >> 16) & 0xff] ^ TS1[(t0 >> 8) & 0xff] ^ TS2[t0 & 0xff];
t1 = TX1[(t1 >> 24) & 0xff] ^ TX2[(t1 >> 16) & 0xff] ^ TS1[(t1 >> 8) & 0xff] ^ TS2[t1 & 0xff];
t2 = TX1[(t2 >> 24) & 0xff] ^ TX2[(t2 >> 16) & 0xff] ^ TS1[(t2 >> 8) & 0xff] ^ TS2[t2 & 0xff];
t3 = TX1[(t3 >> 24) & 0xff] ^ TX2[(t3 >> 16) & 0xff] ^ TS1[(t3 >> 8) & 0xff] ^ TS2[t3 & 0xff];
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t3 = Badc(t3); t0 = Cdab(t0); t1 = Dcba(t1);
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
}
t0 ^= rk[j++]; t1 ^= rk[j++]; t2 ^= rk[j++]; t3 ^= rk[j++];
t0 = TS1[(t0 >> 24) & 0xff] ^ TS2[(t0 >> 16) & 0xff] ^ TX1[(t0 >> 8) & 0xff] ^ TX2[t0 & 0xff];
t1 = TS1[(t1 >> 24) & 0xff] ^ TS2[(t1 >> 16) & 0xff] ^ TX1[(t1 >> 8) & 0xff] ^ TX2[t1 & 0xff];
t2 = TS1[(t2 >> 24) & 0xff] ^ TS2[(t2 >> 16) & 0xff] ^ TX1[(t2 >> 8) & 0xff] ^ TX2[t2 & 0xff];
t3 = TS1[(t3 >> 24) & 0xff] ^ TS2[(t3 >> 16) & 0xff] ^ TX1[(t3 >> 8) & 0xff] ^ TX2[t3 & 0xff];
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t1 = Badc(t1); t2 = Cdab(t2); t3 = Dcba(t3);
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t0 ^= rk[j++]; t1 ^= rk[j++]; t2 ^= rk[j++]; t3 ^= rk[j++];
o[0 + ooffset] = (byte)(X1[0xff & (t0 >> 24)] ^ (rk[j] >> 24));
o[1 + ooffset] = (byte)(X2[0xff & (t0 >> 16)] ^ (rk[j] >> 16));
o[2 + ooffset] = (byte)(S1[0xff & (t0 >> 8)] ^ (rk[j] >> 8));
o[3 + ooffset] = (byte)(S2[0xff & (t0)] ^ (rk[j]));
o[4 + ooffset] = (byte)(X1[0xff & (t1 >> 24)] ^ (rk[j + 1] >> 24));
o[5 + ooffset] = (byte)(X2[0xff & (t1 >> 16)] ^ (rk[j + 1] >> 16));
o[6 + ooffset] = (byte)(S1[0xff & (t1 >> 8)] ^ (rk[j + 1] >> 8));
o[7 + ooffset] = (byte)(S2[0xff & (t1)] ^ (rk[j + 1]));
o[8 + ooffset] = (byte)(X1[0xff & (t2 >> 24)] ^ (rk[j + 2] >> 24));
o[9 + ooffset] = (byte)(X2[0xff & (t2 >> 16)] ^ (rk[j + 2] >> 16));
o[10 + ooffset] = (byte)(S1[0xff & (t2 >> 8)] ^ (rk[j + 2] >> 8));
o[11 + ooffset] = (byte)(S2[0xff & (t2)] ^ (rk[j + 2]));
o[12 + ooffset] = (byte)(X1[0xff & (t3 >> 24)] ^ (rk[j + 3] >> 24));
o[13 + ooffset] = (byte)(X2[0xff & (t3 >> 16)] ^ (rk[j + 3] >> 16));
o[14 + ooffset] = (byte)(S1[0xff & (t3 >> 8)] ^ (rk[j + 3] >> 8));
o[15 + ooffset] = (byte)(S2[0xff & (t3)] ^ (rk[j + 3]));
}
public void Encrypt(byte[] i, int ioffset, byte[] o, int ooffset)
{
if (keySize == 0)
throw new CryptographicException("keySize");
if (encRoundKeys == null)
{
if (masterKey == null)
{
throw new CryptographicException("masterKey");
}
else
{
SetupEncRoundKeys();
}
}
DoCrypt(i, ioffset, encRoundKeys, numberOfRounds, o, ooffset);
}
public byte[] Encrypt(byte[] i, int ioffset)
{
byte[] o = new byte[16];
Encrypt(i, ioffset, o, 0);
return o;
}
public void Decrypt(byte[] i, int ioffset, byte[] o, int ooffset)
{
if (keySize == 0)
throw new CryptographicException("keySize");
if (decRoundKeys == null)
{
if (masterKey == null)
{
throw new CryptographicException("masterKey");
}
else
{
SetupDecRoundKeys();
}
}
DoCrypt(i, ioffset, decRoundKeys, numberOfRounds, o, ooffset);
}
public byte[] Decrypt(byte[] i, int ioffset)
{
byte[] o = new byte[16];
Decrypt(i, ioffset, o, 0);
return o;
}
private static void DoEncKeySetup(byte[] mk, uint[] rk, int keyBits)
{
uint t0, t1, t2, t3;
int q, j = 0;
uint[] w0 = new uint[4];
uint[] w1 = new uint[4];
uint[] w2 = new uint[4];
uint[] w3 = new uint[4];
w0[0] = ToInt(mk[0], mk[1], mk[2], mk[3]);
w0[1] = ToInt(mk[4], mk[5], mk[6], mk[7]);
w0[2] = ToInt(mk[8], mk[9], mk[10], mk[11]);
w0[3] = ToInt(mk[12], mk[13], mk[14], mk[15]);
q = (keyBits - 128) / 64;
t0 = w0[0] ^ KRK[q, 0]; t1 = w0[1] ^ KRK[q, 1];
t2 = w0[2] ^ KRK[q, 2]; t3 = w0[3] ^ KRK[q, 3];
t0 = TS1[(t0 >> 24) & 0xff] ^ TS2[(t0 >> 16) & 0xff] ^ TX1[(t0 >> 8) & 0xff] ^ TX2[t0 & 0xff];
t1 = TS1[(t1 >> 24) & 0xff] ^ TS2[(t1 >> 16) & 0xff] ^ TX1[(t1 >> 8) & 0xff] ^ TX2[t1 & 0xff];
t2 = TS1[(t2 >> 24) & 0xff] ^ TS2[(t2 >> 16) & 0xff] ^ TX1[(t2 >> 8) & 0xff] ^ TX2[t2 & 0xff];
t3 = TS1[(t3 >> 24) & 0xff] ^ TS2[(t3 >> 16) & 0xff] ^ TX1[(t3 >> 8) & 0xff] ^ TX2[t3 & 0xff];
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t1 = Badc(t1); t2 = Cdab(t2); t3 = Dcba(t3);
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
if (keyBits > 128)
{
w1[0] = ToInt(mk[16], mk[17], mk[18], mk[19]);
w1[1] = ToInt(mk[20], mk[21], mk[22], mk[23]);
if (keyBits > 192)
{
w1[2] = ToInt(mk[24], mk[25], mk[26], mk[27]);
w1[3] = ToInt(mk[28], mk[29], mk[30], mk[31]);
}
else
{
w1[2] = w1[3] = 0;
}
}
else
{
w1[0] = w1[1] = w1[2] = w1[3] = 0;
}
w1[0] ^= t0; w1[1] ^= t1; w1[2] ^= t2; w1[3] ^= t3;
t0 = w1[0]; t1 = w1[1]; t2 = w1[2]; t3 = w1[3];
q = (q == 2) ? 0 : (q + 1);
t0 ^= KRK[q, 0]; t1 ^= KRK[q, 1]; t2 ^= KRK[q, 2]; t3 ^= KRK[q, 3];
t0 = TX1[(t0 >> 24) & 0xff] ^ TX2[(t0 >> 16) & 0xff] ^ TS1[(t0 >> 8) & 0xff] ^ TS2[t0 & 0xff];
t1 = TX1[(t1 >> 24) & 0xff] ^ TX2[(t1 >> 16) & 0xff] ^ TS1[(t1 >> 8) & 0xff] ^ TS2[t1 & 0xff];
t2 = TX1[(t2 >> 24) & 0xff] ^ TX2[(t2 >> 16) & 0xff] ^ TS1[(t2 >> 8) & 0xff] ^ TS2[t2 & 0xff];
t3 = TX1[(t3 >> 24) & 0xff] ^ TX2[(t3 >> 16) & 0xff] ^ TS1[(t3 >> 8) & 0xff] ^ TS2[t3 & 0xff];
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t3 = Badc(t3); t0 = Cdab(t0); t1 = Dcba(t1);
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t0 ^= w0[0]; t1 ^= w0[1]; t2 ^= w0[2]; t3 ^= w0[3];
w2[0] = t0; w2[1] = t1; w2[2] = t2; w2[3] = t3;
q = (q == 2) ? 0 : (q + 1);
t0 ^= KRK[q, 0]; t1 ^= KRK[q, 1]; t2 ^= KRK[q, 2]; t3 ^= KRK[q, 3];
t0 = TS1[(t0 >> 24) & 0xff] ^ TS2[(t0 >> 16) & 0xff] ^ TX1[(t0 >> 8) & 0xff] ^ TX2[t0 & 0xff];
t1 = TS1[(t1 >> 24) & 0xff] ^ TS2[(t1 >> 16) & 0xff] ^ TX1[(t1 >> 8) & 0xff] ^ TX2[t1 & 0xff];
t2 = TS1[(t2 >> 24) & 0xff] ^ TS2[(t2 >> 16) & 0xff] ^ TX1[(t2 >> 8) & 0xff] ^ TX2[t2 & 0xff];
t3 = TS1[(t3 >> 24) & 0xff] ^ TS2[(t3 >> 16) & 0xff] ^ TX1[(t3 >> 8) & 0xff] ^ TX2[t3 & 0xff];
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t1 = Badc(t1); t2 = Cdab(t2); t3 = Dcba(t3);
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
w3[0] = t0 ^ w1[0]; w3[1] = t1 ^ w1[1]; w3[2] = t2 ^ w1[2]; w3[3] = t3 ^ w1[3];
Gsrk(w0, w1, 19, rk, j); j += 4;
Gsrk(w1, w2, 19, rk, j); j += 4;
Gsrk(w2, w3, 19, rk, j); j += 4;
Gsrk(w3, w0, 19, rk, j); j += 4;
Gsrk(w0, w1, 31, rk, j); j += 4;
Gsrk(w1, w2, 31, rk, j); j += 4;
Gsrk(w2, w3, 31, rk, j); j += 4;
Gsrk(w3, w0, 31, rk, j); j += 4;
Gsrk(w0, w1, 67, rk, j); j += 4;
Gsrk(w1, w2, 67, rk, j); j += 4;
Gsrk(w2, w3, 67, rk, j); j += 4;
Gsrk(w3, w0, 67, rk, j); j += 4;
Gsrk(w0, w1, 97, rk, j); j += 4;
if (keyBits > 128)
{
Gsrk(w1, w2, 97, rk, j); j += 4;
Gsrk(w2, w3, 97, rk, j); j += 4;
}
if (keyBits > 192)
{
Gsrk(w3, w0, 97, rk, j); j += 4;
Gsrk(w0, w1, 109, rk, j);
}
}
/**
* Main bulk of the decryption key setup method. Here we assume that
* the int array rk already contains the encryption round keys.
* @param mk the master key
* @param rk the array which contains the encryption round keys at the
* beginning of the method execution. At the end of method execution
* this will hold the decryption round keys.
* @param keyBits the length of the master key
* @return
*/
private static void DoDecKeySetup(byte[] mk, uint[] rk, int keyBits)
{
int a = 0, z;
uint[] t = new uint[4];
z = 32 + keyBits / 8;
SwapBlocks(rk, 0, z);
a += 4; z -= 4;
for (; a < z; a += 4, z -= 4)
SwapAndDiffuse(rk, a, z, t);
Diff(rk, a, t, 0);
rk[a] = t[0]; rk[a + 1] = t[1]; rk[a + 2] = t[2]; rk[a + 3] = t[3];
}
private static uint ToInt(byte b0, byte b1, byte b2, byte b3)
{
return (uint)((b0 & 0xff) << 24 ^ (b1 & 0xff) << 16 ^ (b2 & 0xff) << 8 ^ b3 & 0xff);
}
private static uint M(uint t)
{
return 0x00010101 * ((t >> 24) & 0xff) ^ 0x01000101 * ((t >> 16) & 0xff) ^
0x01010001 * ((t >> 8) & 0xff) ^ 0x01010100 * (t & 0xff);
}
// private static final int ms(int t) {
// return TS1[(t>>>24)&0xff]^TS2[(t>>>16)&0xff]^TX1[(t>>>8)&0xff]^TX2[t&0xff];
// }
// private static final int mx(int t) {
// return TX1[(t>>>24)&0xff]^TX2[(t>>>16)&0xff]^TS1[(t>>>8)&0xff]^TS2[t&0xff];
// }
private static uint Badc(uint t)
{
return ((t << 8) & 0xff00ff00) ^ ((t >> 8) & 0x00ff00ff);
}
private static uint Cdab(uint t)
{
return ((t << 16) & 0xffff0000) ^ ((t >> 16) & 0x0000ffff);
}
private static uint Dcba(uint t)
{
return (t & 0x000000ff) << 24 ^ (t & 0x0000ff00) << 8 ^ (t & 0x00ff0000) >> 8 ^ (t & 0xff000000) >> 24;
}
private static void Gsrk(uint[] x, uint[] y, int rot, uint[] rk, int offset)
{
int q = 4 - (rot / 32), r = rot % 32, s = 32 - r;
rk[offset] = x[0] ^ y[(q) % 4] >> r ^ y[(q + 3) % 4] << s;
rk[offset + 1] = x[1] ^ y[(q + 1) % 4] >> r ^ y[(q) % 4] << s;
rk[offset + 2] = x[2] ^ y[(q + 2) % 4] >> r ^ y[(q + 1) % 4] << s;
rk[offset + 3] = x[3] ^ y[(q + 3) % 4] >> r ^ y[(q + 2) % 4] << s;
}
private static void Diff(uint[] i, int offset1, uint[] o, int offset2)
{
uint t0, t1, t2, t3;
t0 = M(i[offset1]); t1 = M(i[offset1 + 1]); t2 = M(i[offset1 + 2]); t3 = M(i[offset1 + 3]);
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
t1 = Badc(t1); t2 = Cdab(t2); t3 = Dcba(t3);
t1 ^= t2; t2 ^= t3; t0 ^= t1; t3 ^= t1; t2 ^= t0; t1 ^= t2;
o[offset2] = t0; o[offset2 + 1] = t1; o[offset2 + 2] = t2; o[offset2 + 3] = t3;
}
private static void SwapBlocks(uint[] arr, int offset1, int offset2)
{
uint t;
for (int i = 0; i < 4; i++)
{
t = arr[offset1 + i];
arr[offset1 + i] = arr[offset2 + i];
arr[offset2 + i] = t;
}
}
private static void SwapAndDiffuse(uint[] arr, int offset1, int offset2, uint[] tmp)
{
Diff(arr, offset1, tmp, 0);
Diff(arr, offset2, arr, offset1);
arr[offset2] = tmp[0]; arr[offset2 + 1] = tmp[1];
arr[offset2 + 2] = tmp[2]; arr[offset2 + 3] = tmp[3];
}
public class ECB
{
private static readonly int BLOCK_SIZE = 16;
private ARIA engine = null;
public ECB(byte[] key)
{
Init(key);
}
public ECB(string key)
{
Init(CreateKey(key));
}
private void Init(byte[] key)
{
engine = new ARIA(key.Length * 8);
engine.SetKey(key);
engine.SetupRoundKeys();
}
/// <summary>
/// allowed key size (bit): 128, 192, 256
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private byte[] CreateKey(string key)
{
SHA256 hasher = SHA256.Create();
byte[] hashData = hasher.ComputeHash(Encoding.Default.GetBytes(key));
return hashData;
}
public byte[] Encrypt(byte[] data)
{
byte[] indata = AnsiX923Padding.AddPadding(data, BLOCK_SIZE);
byte[] outdata = new byte[indata.Length];
for (int i = 0; i < indata.Length; i += BLOCK_SIZE)
{
engine.Encrypt(indata, i, outdata, i);
}
return outdata;
}
public byte[] Decrypt(byte[] data)
{
byte[] outdata = new byte[data.Length];
for (int i = 0; i < data.Length; i += BLOCK_SIZE)
{
engine.Decrypt(data, i, outdata, i);
}
return AnsiX923Padding.RemovePadding(outdata, BLOCK_SIZE, true);
}
}
}
}

View File

@ -0,0 +1,132 @@
/*
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* AnsiX923Padding.cs
*
* description:
* AnsiX923Padding implementation
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
* - https://discord.gg/XKG5CjtXEj
*
* authors:
* - Namhyeon Go (@gnh1201) <abuse@catswords.net>
*
* references:
* - https://github.com/eGovFrame/egovframework.rte.root/blob/master/Foundation/egovframework.rte.fdl.crypto/src/main/java/egovframework/rte/fdl/cryptography/impl/aria/AnsiX923Padding.java
* - ChatGPT prompt "AnsiX923Padding with C#" (chatgpt.com)
* - ChatGPT prompt "AnsiX923Padding with C#, Add a flag to decide how to handle possible errors when removing padding." (chatgpt.com)
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
*/
using System;
namespace WelsonJS.Cryptography
{
class AnsiX923Padding
{
/// <summary>
/// Add ANSI X.923 padding to the input data to make it a multiple of the block size.
/// </summary>
/// <param name="data">The data to be padded.</param>
/// <param name="blockSize">The block size to pad to.</param>
/// <returns>Padded data with ANSI X.923 padding.</returns>
public static byte[] AddPadding(byte[] data, int blockSize)
{
int paddingLength = blockSize - (data.Length % blockSize);
// If the data is already a multiple of the block size, no padding is needed
if (paddingLength == blockSize)
{
return data;
}
byte[] paddedData = new byte[data.Length + paddingLength];
// Copy original data into the padded array
Array.Copy(data, paddedData, data.Length);
// Fill with 0x00 bytes, and the last byte is the padding length
for (int i = data.Length; i < paddedData.Length - 1; i++)
{
paddedData[i] = 0x00;
}
// Last byte is the padding length
paddedData[paddedData.Length - 1] = (byte)paddingLength;
return paddedData;
}
/// <summary>
/// Removes ANSI X.923 padding from the given data.
/// </summary>
/// <param name="data">The input data, including padding.</param>
/// <param name="blockSize">The block size used for padding.</param>
/// <param name="ignoreErrors">If true, ignores errors and attempts to process the input data as-is.</param>
/// <returns>The unpadded data as a byte array.</returns>
/// <exception cref="ArgumentException">Thrown if the input data or padding is invalid and ignoreErrors is false.</exception>
public static byte[] RemovePadding(byte[] data, int blockSize, bool ignoreErrors = false)
{
// Check for null or empty data
if (data == null || data.Length == 0)
{
if (ignoreErrors)
{
return new byte[] { };
}
throw new ArgumentException("Input data cannot be null or empty.");
}
// Ensure the data length is a multiple of the block size
if (data.Length % blockSize != 0)
{
if (ignoreErrors)
{
// Return the original data if errors are ignored
return data;
}
throw new ArgumentException("Input data length must be a multiple of the block size.");
}
// Retrieve the padding length from the last byte
int paddingLength = data[data.Length - 1];
// Validate padding length
if (paddingLength <= 0 || paddingLength > blockSize)
{
if (!ignoreErrors)
{
throw new ArgumentException($"Invalid padding length: {paddingLength}. Must be between 1 and {blockSize}.");
}
// Treat padding length as 0 and return the full data
return data;
}
// Validate the padding region (last paddingLength - 1 bytes must be 0x00)
for (int i = data.Length - paddingLength; i < data.Length - 1; i++)
{
if (data[i] != 0x00)
{
if (!ignoreErrors)
{
throw new ArgumentException("Invalid padding detected. Expected padding bytes to be 0x00.");
}
}
}
// Extract unpadded data
byte[] unpaddedData = new byte[data.Length - paddingLength];
Array.Copy(data, unpaddedData, unpaddedData.Length);
return unpaddedData;
}
}
}

View File

@ -0,0 +1,389 @@
/*
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* HIGHT.cs
*
* description:
* HIGHT(ISO/IEC 18033-3) cryptography algorithm implementation
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
* - https://discord.gg/XKG5CjtXEj
*
* authors:
* - Namhyeon Go (@gnh1201) <abuse@catswords.net>
* - @chandong83 (github.com)
* - KISA(Korea Internet & Security Agency) (kisa.or.kr)
* - Korea Unversity (www.korea.ac.kr)
*
* references:
* - https://seed.kisa.or.kr/kisa/algorithm/EgovHightInfo.do
* - https://github.com/chandong83/csharp_crypto_hight_ecb_examples
* - https://blog.naver.com/chandong83/222198351602
* - https://www.iso.org/standard/54531.html
* - https://ics.catswords.net/HIGHT-algorithm-specification-english.pdf
* - https://ics.catswords.net/HIGHT-algorithm-specification-korean.pdf
* - https://ics.catswords.net/HIGHT-sourcecode-explanation.pdf
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
*/
using System;
namespace WelsonJS.Cryptography
{
public class HIGHT
{
private static readonly byte[] hightDelta = {
0x5A,0x6D,0x36,0x1B,0x0D,0x06,0x03,0x41,
0x60,0x30,0x18,0x4C,0x66,0x33,0x59,0x2C,
0x56,0x2B,0x15,0x4A,0x65,0x72,0x39,0x1C,
0x4E,0x67,0x73,0x79,0x3C,0x5E,0x6F,0x37,
0x5B,0x2D,0x16,0x0B,0x05,0x42,0x21,0x50,
0x28,0x54,0x2A,0x55,0x6A,0x75,0x7A,0x7D,
0x3E,0x5F,0x2F,0x17,0x4B,0x25,0x52,0x29,
0x14,0x0A,0x45,0x62,0x31,0x58,0x6C,0x76,
0x3B,0x1D,0x0E,0x47,0x63,0x71,0x78,0x7C,
0x7E,0x7F,0x3F,0x1F,0x0F,0x07,0x43,0x61,
0x70,0x38,0x5C,0x6E,0x77,0x7B,0x3D,0x1E,
0x4F,0x27,0x53,0x69,0x34,0x1A,0x4D,0x26,
0x13,0x49,0x24,0x12,0x09,0x04,0x02,0x01,
0x40,0x20,0x10,0x08,0x44,0x22,0x11,0x48,
0x64,0x32,0x19,0x0C,0x46,0x23,0x51,0x68,
0x74,0x3A,0x5D,0x2E,0x57,0x6B,0x35,0x5A
};
private static readonly byte[] hightF0 = {
0x00,0x86,0x0D,0x8B,0x1A,0x9C,0x17,0x91,
0x34,0xB2,0x39,0xBF,0x2E,0xA8,0x23,0xA5,
0x68,0xEE,0x65,0xE3,0x72,0xF4,0x7F,0xF9,
0x5C,0xDA,0x51,0xD7,0x46,0xC0,0x4B,0xCD,
0xD0,0x56,0xDD,0x5B,0xCA,0x4C,0xC7,0x41,
0xE4,0x62,0xE9,0x6F,0xFE,0x78,0xF3,0x75,
0xB8,0x3E,0xB5,0x33,0xA2,0x24,0xAF,0x29,
0x8C,0x0A,0x81,0x07,0x96,0x10,0x9B,0x1D,
0xA1,0x27,0xAC,0x2A,0xBB,0x3D,0xB6,0x30,
0x95,0x13,0x98,0x1E,0x8F,0x09,0x82,0x04,
0xC9,0x4F,0xC4,0x42,0xD3,0x55,0xDE,0x58,
0xFD,0x7B,0xF0,0x76,0xE7,0x61,0xEA,0x6C,
0x71,0xF7,0x7C,0xFA,0x6B,0xED,0x66,0xE0,
0x45,0xC3,0x48,0xCE,0x5F,0xD9,0x52,0xD4,
0x19,0x9F,0x14,0x92,0x03,0x85,0x0E,0x88,
0x2D,0xAB,0x20,0xA6,0x37,0xB1,0x3A,0xBC,
0x43,0xC5,0x4E,0xC8,0x59,0xDF,0x54,0xD2,
0x77,0xF1,0x7A,0xFC,0x6D,0xEB,0x60,0xE6,
0x2B,0xAD,0x26,0xA0,0x31,0xB7,0x3C,0xBA,
0x1F,0x99,0x12,0x94,0x05,0x83,0x08,0x8E,
0x93,0x15,0x9E,0x18,0x89,0x0F,0x84,0x02,
0xA7,0x21,0xAA,0x2C,0xBD,0x3B,0xB0,0x36,
0xFB,0x7D,0xF6,0x70,0xE1,0x67,0xEC,0x6A,
0xCF,0x49,0xC2,0x44,0xD5,0x53,0xD8,0x5E,
0xE2,0x64,0xEF,0x69,0xF8,0x7E,0xF5,0x73,
0xD6,0x50,0xDB,0x5D,0xCC,0x4A,0xC1,0x47,
0x8A,0x0C,0x87,0x01,0x90,0x16,0x9D,0x1B,
0xBE,0x38,0xB3,0x35,0xA4,0x22,0xA9,0x2F,
0x32,0xB4,0x3F,0xB9,0x28,0xAE,0x25,0xA3,
0x06,0x80,0x0B,0x8D,0x1C,0x9A,0x11,0x97,
0x5A,0xDC,0x57,0xD1,0x40,0xC6,0x4D,0xCB,
0x6E,0xE8,0x63,0xE5,0x74,0xF2,0x79,0xFF
};
private static readonly byte[] hightF1 = {
0x00,0x58,0xB0,0xE8,0x61,0x39,0xD1,0x89,
0xC2,0x9A,0x72,0x2A,0xA3,0xFB,0x13,0x4B,
0x85,0xDD,0x35,0x6D,0xE4,0xBC,0x54,0x0C,
0x47,0x1F,0xF7,0xAF,0x26,0x7E,0x96,0xCE,
0x0B,0x53,0xBB,0xE3,0x6A,0x32,0xDA,0x82,
0xC9,0x91,0x79,0x21,0xA8,0xF0,0x18,0x40,
0x8E,0xD6,0x3E,0x66,0xEF,0xB7,0x5F,0x07,
0x4C,0x14,0xFC,0xA4,0x2D,0x75,0x9D,0xC5,
0x16,0x4E,0xA6,0xFE,0x77,0x2F,0xC7,0x9F,
0xD4,0x8C,0x64,0x3C,0xB5,0xED,0x05,0x5D,
0x93,0xCB,0x23,0x7B,0xF2,0xAA,0x42,0x1A,
0x51,0x09,0xE1,0xB9,0x30,0x68,0x80,0xD8,
0x1D,0x45,0xAD,0xF5,0x7C,0x24,0xCC,0x94,
0xDF,0x87,0x6F,0x37,0xBE,0xE6,0x0E,0x56,
0x98,0xC0,0x28,0x70,0xF9,0xA1,0x49,0x11,
0x5A,0x02,0xEA,0xB2,0x3B,0x63,0x8B,0xD3,
0x2C,0x74,0x9C,0xC4,0x4D,0x15,0xFD,0xA5,
0xEE,0xB6,0x5E,0x06,0x8F,0xD7,0x3F,0x67,
0xA9,0xF1,0x19,0x41,0xC8,0x90,0x78,0x20,
0x6B,0x33,0xDB,0x83,0x0A,0x52,0xBA,0xE2,
0x27,0x7F,0x97,0xCF,0x46,0x1E,0xF6,0xAE,
0xE5,0xBD,0x55,0x0D,0x84,0xDC,0x34,0x6C,
0xA2,0xFA,0x12,0x4A,0xC3,0x9B,0x73,0x2B,
0x60,0x38,0xD0,0x88,0x01,0x59,0xB1,0xE9,
0x3A,0x62,0x8A,0xD2,0x5B,0x03,0xEB,0xB3,
0xF8,0xA0,0x48,0x10,0x99,0xC1,0x29,0x71,
0xBF,0xE7,0x0F,0x57,0xDE,0x86,0x6E,0x36,
0x7D,0x25,0xCD,0x95,0x1C,0x44,0xAC,0xF4,
0x31,0x69,0x81,0xD9,0x50,0x08,0xE0,0xB8,
0xF3,0xAB,0x43,0x1B,0x92,0xCA,0x22,0x7A,
0xB4,0xEC,0x04,0x5C,0xD5,0x8D,0x65,0x3D,
0x76,0x2E,0xC6,0x9E,0x17,0x4F,0xA7,0xFF
};
public class ECB
{
//whitening Key [8] + sub Key[128]
byte[] scheduleKey = new byte[136];
public ECB(byte[] userKey)
{
if (userKey.Length < 16)
{
// Pad the key with 0x00 if its length is less than 16 bytes
byte[] paddedKey = new byte[16];
Array.Copy(userKey, 0, paddedKey, 0, userKey.Length);
userKey = paddedKey;
}
else if (userKey.Length > 16)
{
// If the key is longer than 16 bytes, truncate to 16 bytes
byte[] truncatedKey = new byte[16];
Array.Copy(userKey, truncatedKey, 16);
userKey = truncatedKey;
}
KeySched(userKey);
}
void KeySched(byte[] userKey)
{
for (int i = 0; i < 4; i++)
{
scheduleKey[i] = userKey[i + 12];
scheduleKey[i + 4] = userKey[i];
}
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
scheduleKey[8 + 16 * i + j] = (byte)((userKey[(j - i) & 7] + hightDelta[(16 * i + j)]) & 0xFF);
}
for (int j = 0; j < 8; j++)
{
scheduleKey[8 + 16 * i + j + 8] = (byte)((userKey[((j - i) & 7) + 8] + hightDelta[16 * i + j + 8]) & 0xFF);
}
}
}
void DecryptBlock(byte[] dataIn, byte[] dataOut)
{
byte[] xx = new byte[8];
xx[2] = dataIn[1];
xx[4] = dataIn[3];
xx[6] = dataIn[5];
xx[0] = dataIn[7];
//void HIGHT_DEC(byte[] scheduleKey, byte[] xx, int k, int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7)
void HIGHT_DEC(int k, int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7)
{
xx[i1] = (byte)((xx[i1] - (hightF1[xx[i2]] ^ scheduleKey[4 * k + 2])) & 0xFF);
xx[i3] = (byte)((xx[i3] ^ (hightF0[xx[i4]] + scheduleKey[4 * k + 1])) & 0xFF);
xx[i5] = (byte)((xx[i5] - (hightF1[xx[i6]] ^ scheduleKey[4 * k + 0])) & 0xFF);
xx[i7] = (byte)((xx[i7] ^ (hightF0[xx[i0]] + scheduleKey[4 * k + 3])) & 0xFF);
}
xx[1] = (byte)(dataIn[0] - scheduleKey[4]);
xx[3] = (byte)(dataIn[2] ^ scheduleKey[5]);
xx[5] = (byte)(dataIn[4] - scheduleKey[6]);
xx[7] = (byte)(dataIn[6] ^ scheduleKey[7]);
HIGHT_DEC(33, 7, 6, 5, 4, 3, 2, 1, 0);
HIGHT_DEC(32, 0, 7, 6, 5, 4, 3, 2, 1);
HIGHT_DEC(31, 1, 0, 7, 6, 5, 4, 3, 2);
HIGHT_DEC(30, 2, 1, 0, 7, 6, 5, 4, 3);
HIGHT_DEC(29, 3, 2, 1, 0, 7, 6, 5, 4);
HIGHT_DEC(28, 4, 3, 2, 1, 0, 7, 6, 5);
HIGHT_DEC(27, 5, 4, 3, 2, 1, 0, 7, 6);
HIGHT_DEC(26, 6, 5, 4, 3, 2, 1, 0, 7);
HIGHT_DEC(25, 7, 6, 5, 4, 3, 2, 1, 0);
HIGHT_DEC(24, 0, 7, 6, 5, 4, 3, 2, 1);
HIGHT_DEC(23, 1, 0, 7, 6, 5, 4, 3, 2);
HIGHT_DEC(22, 2, 1, 0, 7, 6, 5, 4, 3);
HIGHT_DEC(21, 3, 2, 1, 0, 7, 6, 5, 4);
HIGHT_DEC(20, 4, 3, 2, 1, 0, 7, 6, 5);
HIGHT_DEC(19, 5, 4, 3, 2, 1, 0, 7, 6);
HIGHT_DEC(18, 6, 5, 4, 3, 2, 1, 0, 7);
HIGHT_DEC(17, 7, 6, 5, 4, 3, 2, 1, 0);
HIGHT_DEC(16, 0, 7, 6, 5, 4, 3, 2, 1);
HIGHT_DEC(15, 1, 0, 7, 6, 5, 4, 3, 2);
HIGHT_DEC(14, 2, 1, 0, 7, 6, 5, 4, 3);
HIGHT_DEC(13, 3, 2, 1, 0, 7, 6, 5, 4);
HIGHT_DEC(12, 4, 3, 2, 1, 0, 7, 6, 5);
HIGHT_DEC(11, 5, 4, 3, 2, 1, 0, 7, 6);
HIGHT_DEC(10, 6, 5, 4, 3, 2, 1, 0, 7);
HIGHT_DEC(9, 7, 6, 5, 4, 3, 2, 1, 0);
HIGHT_DEC(8, 0, 7, 6, 5, 4, 3, 2, 1);
HIGHT_DEC(7, 1, 0, 7, 6, 5, 4, 3, 2);
HIGHT_DEC(6, 2, 1, 0, 7, 6, 5, 4, 3);
HIGHT_DEC(5, 3, 2, 1, 0, 7, 6, 5, 4);
HIGHT_DEC(4, 4, 3, 2, 1, 0, 7, 6, 5);
HIGHT_DEC(3, 5, 4, 3, 2, 1, 0, 7, 6);
HIGHT_DEC(2, 6, 5, 4, 3, 2, 1, 0, 7);
dataOut[1] = (byte)(xx[1] & 0xFF);
dataOut[3] = (byte)(xx[3] & 0xFF);
dataOut[5] = (byte)(xx[5] & 0xFF);
dataOut[7] = (byte)(xx[7] & 0xFF);
dataOut[0] = (byte)((xx[0] - scheduleKey[0]) & 0xFF);
dataOut[2] = (byte)((xx[2] ^ scheduleKey[1]) & 0xFF);
dataOut[4] = (byte)((xx[4] - scheduleKey[2]) & 0xFF);
dataOut[6] = (byte)((xx[6] ^ scheduleKey[3]) & 0xFF);
}
void EncryptBlock(byte[] dataIn, byte[] dataOut)
{
byte[] xx = new byte[8];
xx[1] = dataIn[1];
xx[3] = dataIn[3];
xx[5] = dataIn[5];
xx[7] = dataIn[7];
xx[0] = (byte)((dataIn[0] + scheduleKey[0]) & 0xFF);
xx[2] = (byte)((dataIn[2] ^ scheduleKey[1]));
xx[4] = (byte)((dataIn[4] + scheduleKey[2]) & 0xFF);
xx[6] = (byte)((dataIn[6] ^ scheduleKey[3]));
void HIGHT_ENC(int k, int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7)
{
xx[i0] = (byte)((xx[i0] ^ (hightF0[xx[i1]] + scheduleKey[4 * k + 3])) & 0xFF);
xx[i2] = (byte)((xx[i2] + (hightF1[xx[i3]] ^ scheduleKey[4 * k + 2])) & 0xFF);
xx[i4] = (byte)((xx[i4] ^ (hightF0[xx[i5]] + scheduleKey[4 * k + 1])) & 0xFF);
xx[i6] = (byte)((xx[i6] + (hightF1[xx[i7]] ^ scheduleKey[4 * k + 0])) & 0xFF);
}
HIGHT_ENC(2, 7, 6, 5, 4, 3, 2, 1, 0);
HIGHT_ENC(3, 6, 5, 4, 3, 2, 1, 0, 7);
HIGHT_ENC(4, 5, 4, 3, 2, 1, 0, 7, 6);
HIGHT_ENC(5, 4, 3, 2, 1, 0, 7, 6, 5);
HIGHT_ENC(6, 3, 2, 1, 0, 7, 6, 5, 4);
HIGHT_ENC(7, 2, 1, 0, 7, 6, 5, 4, 3);
HIGHT_ENC(8, 1, 0, 7, 6, 5, 4, 3, 2);
HIGHT_ENC(9, 0, 7, 6, 5, 4, 3, 2, 1);
HIGHT_ENC(10, 7, 6, 5, 4, 3, 2, 1, 0);
HIGHT_ENC(11, 6, 5, 4, 3, 2, 1, 0, 7);
HIGHT_ENC(12, 5, 4, 3, 2, 1, 0, 7, 6);
HIGHT_ENC(13, 4, 3, 2, 1, 0, 7, 6, 5);
HIGHT_ENC(14, 3, 2, 1, 0, 7, 6, 5, 4);
HIGHT_ENC(15, 2, 1, 0, 7, 6, 5, 4, 3);
HIGHT_ENC(16, 1, 0, 7, 6, 5, 4, 3, 2);
HIGHT_ENC(17, 0, 7, 6, 5, 4, 3, 2, 1);
HIGHT_ENC(18, 7, 6, 5, 4, 3, 2, 1, 0);
HIGHT_ENC(19, 6, 5, 4, 3, 2, 1, 0, 7);
HIGHT_ENC(20, 5, 4, 3, 2, 1, 0, 7, 6);
HIGHT_ENC(21, 4, 3, 2, 1, 0, 7, 6, 5);
HIGHT_ENC(22, 3, 2, 1, 0, 7, 6, 5, 4);
HIGHT_ENC(23, 2, 1, 0, 7, 6, 5, 4, 3);
HIGHT_ENC(24, 1, 0, 7, 6, 5, 4, 3, 2);
HIGHT_ENC(25, 0, 7, 6, 5, 4, 3, 2, 1);
HIGHT_ENC(26, 7, 6, 5, 4, 3, 2, 1, 0);
HIGHT_ENC(27, 6, 5, 4, 3, 2, 1, 0, 7);
HIGHT_ENC(28, 5, 4, 3, 2, 1, 0, 7, 6);
HIGHT_ENC(29, 4, 3, 2, 1, 0, 7, 6, 5);
HIGHT_ENC(30, 3, 2, 1, 0, 7, 6, 5, 4);
HIGHT_ENC(31, 2, 1, 0, 7, 6, 5, 4, 3);
HIGHT_ENC(32, 1, 0, 7, 6, 5, 4, 3, 2);
HIGHT_ENC(33, 0, 7, 6, 5, 4, 3, 2, 1);
dataOut[1] = (byte)(xx[2] & 0xFF);
dataOut[3] = (byte)(xx[4] & 0xFF);
dataOut[5] = (byte)(xx[6] & 0xFF);
dataOut[7] = (byte)(xx[0] & 0xFF);
dataOut[0] = (byte)((xx[1] + scheduleKey[4]) & 0xFF);
dataOut[2] = (byte)((xx[3] ^ scheduleKey[5]) & 0xFF);
dataOut[4] = (byte)((xx[5] + scheduleKey[6]) & 0xFF);
dataOut[6] = (byte)((xx[7] ^ scheduleKey[7]) & 0xFF);
}
public byte[] Encrypt(byte[] dataIn)
{
int length;
if (dataIn.Length == 0)
{
return null;
}
if ((dataIn.Length % 8) != 0)
{
length = dataIn.Length + (8 - (dataIn.Length % 8));
}
else
{
length = dataIn.Length;
}
byte[] dataOut = new byte[length];
byte[] tempIn = new byte[8];
byte[] tempOut = new byte[8];
byte[] dataInWithPadding = new byte[length];
Array.Copy(dataIn, dataInWithPadding, dataIn.Length);
for (int i = 0; i < (int)(length / 8); i++)
{
Array.Copy(dataInWithPadding, i * 8, tempIn, 0, 8);
EncryptBlock(tempIn, tempOut);
Array.Copy(tempOut, 0, dataOut, i * 8, 8);
}
return dataOut;
}
public byte[] Decrypt(byte[] dataIn)
{
int length;
if (dataIn.Length == 0)
{
return null;
}
if ((dataIn.Length % 8) != 0)
{
length = dataIn.Length + (8 - (dataIn.Length % 8));
}
else
{
length = dataIn.Length;
}
byte[] dataOut = new byte[length];
byte[] tempIn = new byte[8];
byte[] tempOut = new byte[8];
byte[] dataInWithPadding = new byte[length];
Array.Copy(dataIn, dataInWithPadding, dataIn.Length);
for (int i = 0; i < (int)(length / 8); i++)
{
Array.Copy(dataInWithPadding, i * 8, tempIn, 0, 8);
DecryptBlock(tempIn, tempOut);
Array.Copy(tempOut, 0, dataOut, i * 8, 8);
}
return dataOut;
}
public void Test()
{
byte[] dataIn = new byte[15];
byte[] dataOut = new byte[15];
byte[] dataOut2 = new byte[15];
for (int i = 0; i < 15; i++)
{
dataIn[i] = (byte)i;
}
Console.WriteLine("schedule key data");
Console.WriteLine(string.Format("0x{0:x2}", scheduleKey));
dataOut = Encrypt(dataIn);
dataOut2 = Decrypt(dataOut);
Console.WriteLine("origin data");
Console.WriteLine(string.Format("0x{0:x2}", dataIn));
Console.WriteLine("encryption data");
Console.WriteLine(string.Format("0x{0:x2}", dataOut));
Console.WriteLine("decryption data");
Console.WriteLine(string.Format("0x{0:x2}", dataOut2));
}
}
}
}

View File

@ -0,0 +1,349 @@
/*
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* LEA.cs
*
* description:
* LEA(KS X 3246:2016) cryptography algorithm implementation (Experimental)
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
* - https://discord.gg/XKG5CjtXEj
*
* authors:
* - Namhyeon Go (@gnh1201) <abuse@catswords.net>
* - KISA(Korea Internet & Security Agency) (kisa.or.kr)
* - National Security Research Institute (NSRI)
*
* references:
* - https://seed.kisa.or.kr/kisa/Board/20/detailView.do
* - https://committee.tta.or.kr/data/standard_view.jsp?order=t.kor_standard&by=asc&pk_num=TTAK.KO-12.0223&commit_code=TC5
* - https://ics.catswords.net/LEA%20A%20128-Bit%20Block%20Cipher%20Datasheets-Korean.pdf
* - https://ics.catswords.net/LEA%20A%20128-Bit%20Block%20Cipher%20for%20Fast%20Encryption%20on%20Common%20Processors-English.pdf
* - https://ics.catswords.net/LEA-sourcecode-explanation.pdf
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
*/
using System;
using System.Security.Cryptography;
using System.Text;
namespace WelsonJS.Cryptography
{
public class LEA
{
private const int BLOCKSIZE = 16;
private static readonly uint[] delta = {
0xc3efe9db, 0x44626b02, 0x79e27c8a, 0x78df30ec,
0x715ea49e, 0xc785da0a, 0xe04ef22a, 0xe5c40957
};
private Mode mode;
private int rounds;
private uint[,] roundKeys;
private uint[] block;
public LEA()
{
block = new uint[BLOCKSIZE / 4];
}
public void Init(Mode mode, byte[] mk)
{
this.mode = mode;
GenerateRoundKeys(mk);
}
public void Reset()
{
Array.Clear(block, 0, block.Length);
}
public string GetAlgorithmName()
{
return "LEA";
}
public int GetBlockSize()
{
return BLOCKSIZE;
}
public int ProcessBlock(byte[] input, int inputOffset, byte[] output, int outputOffset)
{
if (input == null || output == null)
throw new ArgumentNullException("Input and output buffers must not be null.");
if (input.Length - inputOffset < BLOCKSIZE)
throw new InvalidOperationException("Input data is too short.");
if (output.Length - outputOffset < BLOCKSIZE)
throw new InvalidOperationException("Output buffer is too short.");
return mode == Mode.ENCRYPT
? EncryptBlock(input, inputOffset, output, outputOffset)
: DecryptBlock(input, inputOffset, output, outputOffset);
}
private int EncryptBlock(byte[] input, int inputOffset, byte[] output, int outputOffset)
{
Pack(input, inputOffset, ref block, 0, 16);
for (int i = 0; i < rounds; ++i)
{
block[3] = ROR((block[2] ^ roundKeys[i, 4]) + (block[3] ^ roundKeys[i, 5]), 3);
block[2] = ROR((block[1] ^ roundKeys[i, 2]) + (block[2] ^ roundKeys[i, 3]), 5);
block[1] = ROL((block[0] ^ roundKeys[i, 0]) + (block[1] ^ roundKeys[i, 1]), 9);
++i;
block[0] = ROR((block[3] ^ roundKeys[i, 4]) + (block[0] ^ roundKeys[i, 5]), 3);
block[3] = ROR((block[2] ^ roundKeys[i, 2]) + (block[3] ^ roundKeys[i, 3]), 5);
block[2] = ROL((block[1] ^ roundKeys[i, 0]) + (block[2] ^ roundKeys[i, 1]), 9);
++i;
block[1] = ROR((block[0] ^ roundKeys[i, 4]) + (block[1] ^ roundKeys[i, 5]), 3);
block[0] = ROR((block[3] ^ roundKeys[i, 2]) + (block[0] ^ roundKeys[i, 3]), 5);
block[3] = ROL((block[2] ^ roundKeys[i, 0]) + (block[3] ^ roundKeys[i, 1]), 9);
++i;
block[2] = ROR((block[1] ^ roundKeys[i, 4]) + (block[2] ^ roundKeys[i, 5]), 3);
block[1] = ROR((block[0] ^ roundKeys[i, 2]) + (block[1] ^ roundKeys[i, 3]), 5);
block[0] = ROL((block[3] ^ roundKeys[i, 0]) + (block[0] ^ roundKeys[i, 1]), 9);
}
Unpack(block, 0, ref output, outputOffset, 4);
return BLOCKSIZE;
}
private int DecryptBlock(byte[] input, int inputOffset, byte[] output, int outputOffset)
{
Pack(input, inputOffset, ref block, 0, 16);
for (int i = rounds - 1; i >= 0; --i)
{
block[0] = (ROR(block[0], 9) - (block[3] ^ roundKeys[i, 0])) ^ roundKeys[i, 1];
block[1] = (ROL(block[1], 5) - (block[0] ^ roundKeys[i, 2])) ^ roundKeys[i, 3];
block[2] = (ROL(block[2], 3) - (block[1] ^ roundKeys[i, 4])) ^ roundKeys[i, 5];
--i;
block[3] = (ROR(block[3], 9) - (block[2] ^ roundKeys[i, 0])) ^ roundKeys[i, 1];
block[0] = (ROL(block[0], 5) - (block[3] ^ roundKeys[i, 2])) ^ roundKeys[i, 3];
block[1] = (ROL(block[1], 3) - (block[0] ^ roundKeys[i, 4])) ^ roundKeys[i, 5];
--i;
block[2] = (ROR(block[2], 9) - (block[1] ^ roundKeys[i, 0])) ^ roundKeys[i, 1];
block[3] = (ROL(block[3], 5) - (block[2] ^ roundKeys[i, 2])) ^ roundKeys[i, 3];
block[0] = (ROL(block[0], 3) - (block[3] ^ roundKeys[i, 4])) ^ roundKeys[i, 5];
--i;
block[1] = (ROR(block[1], 9) - (block[0] ^ roundKeys[i, 0])) ^ roundKeys[i, 1];
block[2] = (ROL(block[2], 5) - (block[1] ^ roundKeys[i, 2])) ^ roundKeys[i, 3];
block[3] = (ROL(block[3], 3) - (block[2] ^ roundKeys[i, 4])) ^ roundKeys[i, 5];
}
Unpack(block, 0, ref output, outputOffset, 4);
return BLOCKSIZE;
}
private void GenerateRoundKeys(byte[] mk)
{
if (mk == null || (mk.Length != 16 && mk.Length != 24 && mk.Length != 32))
throw new ArgumentException("Illegal key size");
uint[] T = new uint[8];
rounds = (mk.Length >> 1) + 16;
roundKeys = new uint[rounds, 6];
Pack(mk, 0, ref T, 0, 16);
if (mk.Length > 16)
{
Pack(mk, 16, ref T, 4, 8);
}
if (mk.Length > 24)
{
Pack(mk, 24, ref T, 6, 8);
}
if (mk.Length == 16)
{
for (int i = 0; i < 24; ++i)
{
uint temp = ROL(delta[i & 3], i);
roundKeys[i, 0] = T[0] = ROL(T[0] + ROL(temp, 0), 1);
roundKeys[i, 1] = roundKeys[i, 3] = roundKeys[i, 5] = T[1] = ROL(T[1] + ROL(temp, 1), 3);
roundKeys[i, 2] = T[2] = ROL(T[2] + ROL(temp, 2), 6);
roundKeys[i, 4] = T[3] = ROL(T[3] + ROL(temp, 3), 11);
}
}
else if (mk.Length == 24)
{
for (int i = 0; i < 28; ++i)
{
uint temp = ROL(delta[i % 6], i);
roundKeys[i, 0] = T[0] = ROL(T[0] + ROL(temp, 0), 1);
roundKeys[i, 1] = T[1] = ROL(T[1] + ROL(temp, 1), 3);
roundKeys[i, 2] = T[2] = ROL(T[2] + ROL(temp, 2), 6);
roundKeys[i, 3] = T[3] = ROL(T[3] + ROL(temp, 3), 11);
roundKeys[i, 4] = T[4] = ROL(T[4] + ROL(temp, 4), 13);
roundKeys[i, 5] = T[5] = ROL(T[5] + ROL(temp, 5), 17);
}
}
else
{
for (int i = 0; i < 32; ++i)
{
uint temp = ROL(delta[i & 7], i & 0x1f);
roundKeys[i, 0] = T[(6 * i + 0) & 7] = ROL(T[(6 * i + 0) & 7] + temp, 1);
roundKeys[i, 1] = T[(6 * i + 1) & 7] = ROL(T[(6 * i + 1) & 7] + ROL(temp, 1), 3);
roundKeys[i, 2] = T[(6 * i + 2) & 7] = ROL(T[(6 * i + 2) & 7] + ROL(temp, 2), 6);
roundKeys[i, 3] = T[(6 * i + 3) & 7] = ROL(T[(6 * i + 3) & 7] + ROL(temp, 3), 11);
roundKeys[i, 4] = T[(6 * i + 4) & 7] = ROL(T[(6 * i + 4) & 7] + ROL(temp, 4), 13);
roundKeys[i, 5] = T[(6 * i + 5) & 7] = ROL(T[(6 * i + 5) & 7] + ROL(temp, 5), 17);
}
}
}
private static uint ROL(uint state, int num)
{
return (state << num) | state >> (32 - num);
}
private static uint ROR(uint state, int num)
{
return (state >> num) | state << (32 - num);
}
public static void Pack(in byte[] input, int inputOffset, ref uint[] output, int outputOffset, int inputLength)
{
if (input == null || output == null)
{
throw new ArgumentNullException();
}
if ((inputLength & 3) != 0)
{
throw new ArgumentException("Length should be a multiple of 4.");
}
if (input.Length < inputOffset + inputLength || output.Length < outputOffset + inputLength / 4)
{
throw new IndexOutOfRangeException();
}
int outputIndex = 0;
for (int inputIdx = 0; inputIdx < input.Length; ++inputIdx, ++outputIndex) {
output[outputIndex] = (uint)(input[inputIdx] & 0xff);
output[outputIndex] |= (uint)((input[++inputIdx] & 0xff) << 8);
output[outputIndex] |= (uint)((input[++inputIdx] & 0xff) << 16);
output[outputIndex] |= (uint)((input[++inputIdx] & 0xff) << 24);
}
}
public static void Unpack(in uint[] input, int inputOffset, ref byte[] output, int outputOffset, int inputLength)
{
if (input == null || output == null)
{
throw new ArgumentNullException();
}
if (input.Length < inputOffset + inputLength || output.Length < outputOffset + inputLength * 4)
{
throw new IndexOutOfRangeException();
}
int outputIdx = outputOffset;
int endInIdx = inputOffset + inputLength;
for (int inputIdx = inputOffset; inputIdx < endInIdx; ++inputIdx, ++outputIdx)
{
output[outputIdx] = (byte)input[inputIdx] ;
output[++outputIdx] = (byte)(input[inputIdx] >> 8);
output[++outputIdx] = (byte)(input[inputIdx] >> 16);
output[++outputIdx] = (byte)(input[inputIdx] >> 24);
}
}
public enum Mode
{
ENCRYPT,
DECRYPT
}
public class ECB
{
private Mode mode;
private LEA engine;
private int blockSize;
ECB(Mode mode, string key)
{
engine = new LEA();
Init(mode, CreateKey(key));
blockSize = engine.GetBlockSize();
}
public string GetAlgorithmName()
{
return engine.GetAlgorithmName() + "/ECB";
}
public void Init(Mode mode, byte[] mk)
{
this.mode = mode;
engine.Init(mode, mk);
}
private byte[] CreateKey(string key)
{
SHA256 hasher = SHA256.Create();
byte[] hashData = hasher.ComputeHash(Encoding.Default.GetBytes(key));
return hashData;
}
public byte[] Encrypt(byte[] data)
{
if (this.mode != Mode.ENCRYPT)
throw new InvalidOperationException("Not initialized for encryption mode.");
byte[] inputData = PKCS5Padding.AddPadding(data, blockSize);
byte[] outputData = new byte[inputData.Length];
for (int i = 0; i < inputData.Length; i += blockSize)
{
engine.ProcessBlock(inputData, i, outputData, i);
}
return outputData;
}
public byte[] Decrypt(byte[] data)
{
if (this.mode != Mode.DECRYPT)
throw new InvalidOperationException("Not initialized for decryption mode.");
byte[] outputData = new byte[data.Length];
for (int i = 0; i < data.Length; i += blockSize)
{
engine.ProcessBlock(data, i, outputData, i);
}
return PKCS5Padding.RemovePadding(outputData, blockSize, true);
}
}
}
}

View File

@ -0,0 +1,118 @@
/*
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* PKCS5Padding.cs
*
* description:
* PKCS5Padding implementation
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
* - https://discord.gg/XKG5CjtXEj
*
* authors:
* - Namhyeon Go (@gnh1201) <abuse@catswords.net>
*
* references:
* - ChatGPT prompt "PKCS5Padding with C#" (chatgpt.com)
* - ChatGPT prompt "PKCS5Padding with C#, Add a flag to decide how to handle possible errors when removing padding." (chatgpt.com)
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
*/
using System;
namespace WelsonJS.Cryptography
{
public class PKCS5Padding
{
/// <summary>
/// Add PKCS#5 padding to the input data to make it a multiple of the block size.
/// </summary>
/// <param name="data">The data to be padded.</param>
/// <param name="blockSize">The block size to pad to.</param>
/// <returns>Padded data with PKCS#5 padding.</returns>
public static byte[] AddPadding(byte[] data, int blockSize)
{
int paddingLength = blockSize - (data.Length % blockSize);
// If the data is already a multiple of the block size, no padding is needed
if (paddingLength == blockSize)
{
return data;
}
byte[] paddedData = new byte[data.Length + paddingLength];
// Copy original data into the padded array
Array.Copy(data, paddedData, data.Length);
// Fill padding with the padding length (PKCS5)
for (int i = data.Length; i < paddedData.Length; i++)
{
paddedData[i] = (byte)paddingLength;
}
return paddedData;
}
/// <summary>
/// Removes PKCS#5 padding from the given data.
/// </summary>
/// <param name="data">The input data, including padding.</param>
/// <param name="blockSize">The block size used for padding.</param>
/// <param name="ignoreErrors">If true, ignores errors and attempts to process the input data as-is.</param>
/// <returns>The unpadded data as a byte array.</returns>
/// <exception cref="ArgumentException">Thrown if the input data or padding is invalid and ignoreErrors is false.</exception>
public static byte[] RemovePadding(byte[] data, int blockSize, bool ignoreErrors = false)
{
// If data length is 0, return empty array
if (data.Length == 0)
{
return new byte[] { };
}
// If data length is smaller than block size, treat it as unpadded
if (data.Length < blockSize)
{
return data;
}
// Check if the last byte is valid padding (PKCS5)
int paddingLength = data[data.Length - 1];
// Validate padding length
if (paddingLength <= 0 || paddingLength > blockSize)
{
if (!ignoreErrors)
{
throw new ArgumentException($"Invalid padding length: {paddingLength}. Must be between 1 and {blockSize}.");
}
return data;
}
// Check if the padding is correct (i.e., all padding bytes must be equal to paddingLength)
for (int i = data.Length - paddingLength; i < data.Length; i++)
{
if (data[i] != paddingLength)
{
if (!ignoreErrors)
{
throw new ArgumentException("Invalid padding detected.");
}
}
}
// Remove the padding
byte[] unpaddedData = new byte[data.Length - paddingLength];
Array.Copy(data, unpaddedData, unpaddedData.Length);
return unpaddedData;
}
}
}

View File

@ -0,0 +1,755 @@
/*
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* SEED.cs
*
* description:
* SEED(ISO/IEC 18033-3) cryptography algorithm implementation (Experimental)
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
* - https://discord.gg/XKG5CjtXEj
*
* author:
* - Namhyeon Go (@gnh1201) <abuse@catswords.net>
* - KISA(Korea Internet & Security Agency) (kisa.or.kr)
*
* references:
* - https://seed.kisa.or.kr/kisa/Board/17/detailView.do
* - https://www.iso.org/standard/54531.html
* - https://ics.catswords.net/SEED%2B128_Specification_english_M.pdf
* - https://ics.catswords.net/SEED_Algorithm_Specification_korean_M.pdf
* - https://ics.catswords.net/SEED_sourcecode_explanation_korean.pdf
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
*/
using System;
namespace WelsonJS.Cryptography
{
public class SEED
{
public enum ENDIAN {
BIG,
LITTLE
};
private static ENDIAN DEFAULT_ENDIAN = ENDIAN.BIG;
// Constants for Key schedule
private const uint KC0 = 0x9e3779b9;
private const uint KC1 = 0x3c6ef373;
private const uint KC2 = 0x78dde6e6;
private const uint KC3 = 0xf1bbcdcc;
private const uint KC4 = 0xe3779b99;
private const uint KC5 = 0xc6ef3733;
private const uint KC6 = 0x8dde6e67;
private const uint KC7 = 0x1bbcdccf;
private const uint KC8 = 0x3779b99e;
private const uint KC9 = 0x6ef3733c;
private const uint KC10 = 0xdde6e678;
private const uint KC11 = 0xbbcdccf1;
private const uint KC12 = 0x779b99e3;
private const uint KC13 = 0xef3733c6;
private const uint KC14 = 0xde6e678d;
private const uint KC15 = 0xbcdccf1b;
private const int ABCD_A = 0;
private const int ABCD_B = 1;
private const int ABCD_C = 2;
private const int ABCD_D = 3;
private const int LR_L0 = 0;
private const int LR_L1 = 1;
private const int LR_R0 = 2;
private const int LR_R1 = 3;
private const int BLOCK_SIZE_SEED = 16;
private const int BLOCK_SIZE_SEED_INT = 4;
// S-BOX
private static readonly uint[] SS0 = new uint[] {
0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038,
0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330,
0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
};
private static readonly uint[] SS1 = new uint[]
{
0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171,
0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
};
private static readonly uint[] SS2 = new uint[]
{
0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808,
0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303,
0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
};
private static uint[] SS3 = new uint[]
{
0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031,
0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
};
private static uint GetUIntFromByteArray(byte[] src, int srcOffset, ENDIAN endian = ENDIAN.BIG)
{
if (src == null || src.Length < srcOffset + 4)
throw new ArgumentException("Invalid source array or offset.");
return (uint)(endian == ENDIAN.BIG
? (src[srcOffset] & 0xFF) << 24 |
(src[srcOffset + 1] & 0xFF) << 16 |
(src[srcOffset + 2] & 0xFF) << 8 |
(src[srcOffset + 3] & 0xFF)
: (src[srcOffset] & 0xFF) |
(src[srcOffset + 1] & 0xFF) << 8 |
(src[srcOffset + 2] & 0xFF) << 16 |
(src[srcOffset + 3] & 0xFF) << 24);
}
private static byte GetByteFromUInt(uint value, int position)
{
if (position < 0 || position >= 4)
throw new ArgumentException("Position must be between 0 and 3.");
return position > 0
? (byte)((value >> (8 * position)) & 0xFF)
: (byte)(value & 0xFF);
}
public static void SetByteToUIntArray(ref uint[] dst, int byteOffset, byte value, ENDIAN endian)
{
if (dst == null || byteOffset < 0 || byteOffset >= dst.Length * 4)
throw new ArgumentOutOfRangeException(nameof(byteOffset), "Invalid byte offset.");
int uintIndex = byteOffset / 4;
int shiftValue = (endian == ENDIAN.BIG)
? (3 - byteOffset % 4) * 8
: (byteOffset % 4) * 8;
uint maskValue = (uint)(0xFF << shiftValue);
uint maskValue2 = ~maskValue;
uint valueToSet = (uint)(value & 0xFF) << shiftValue;
dst[uintIndex] = (dst[uintIndex] & maskValue2) | (valueToSet & maskValue);
}
public static byte GetByteFromUIntArray(uint[] src, int byteOffset, ENDIAN endian)
{
if (src == null || byteOffset < 0 || byteOffset >= src.Length * 4)
throw new ArgumentOutOfRangeException(nameof(byteOffset), "Invalid byte offset.");
int uintIndex = byteOffset / 4;
int shiftValue = (endian == ENDIAN.BIG)
? (3 - byteOffset % 4) * 8
: (byteOffset % 4) * 8;
return (byte)((src[uintIndex] >> shiftValue) & 0xFF);
}
private static uint[] ConvertToUIntArray(byte[] src, int inLen, ENDIAN endian = ENDIAN.BIG)
{
if (src == null)
throw new ArgumentNullException(nameof(src), "source cannot be null.");
if (inLen <= 0 || inLen > src.Length)
throw new ArgumentException("Invalid input length.", nameof(inLen));
int outLen = (inLen + 3) / 4;
uint[] data = new uint[outLen];
for (int i = 0; i < outLen; i++)
{
data[i] = GetUIntFromByteArray(src, i * 4, endian);
}
return data;
}
private static byte[] ConvertToByteArray(uint[] src, int inLen, ENDIAN endian = ENDIAN.BIG)
{
if (src == null)
throw new ArgumentNullException(nameof(src), "source cannot be null.");
if (inLen <= 0 || inLen > src.Length)
throw new ArgumentException("Invalid input length.", nameof(inLen));
int outLen = inLen;
byte[] data = new byte[outLen];
for (int i = 0; i < outLen; i++)
{
data[i] = GetByteFromUIntArray(src, i, endian);
}
return data;
}
private static uint Substitute(uint value)
{
return SS0[GetByteFromUInt(value, 0)] ^
SS1[GetByteFromUInt(value, 1)] ^
SS2[GetByteFromUInt(value, 2)] ^
SS3[GetByteFromUInt(value, 3)];
}
// Round function F and adding output of F to L.
// L0, L1 : left input values at each round
// R0, R1 : right input values at each round
// K : round keys at each round
private static void SeedRound(ref uint[] T, ref uint[] LR, int L0, int L1, int R0, int R1, uint[] K, int K_offset)
{
T[0] = LR[R0] ^ K[K_offset + 0];
T[1] = LR[R1] ^ K[K_offset + 1];
T[1] ^= T[0];
T[1] = Substitute(T[1]);
T[0] += T[1];
T[0] = Substitute(T[0]);
T[1] += T[0];
T[1] = Substitute(T[1]);
T[0] += T[1];
LR[L0] ^= T[0]; LR[L1] ^= T[1];
}
private static uint EndianChange(uint value)
{
return ((value & 0x000000FF) << 24) | // Move the first byte to the fourth byte position
((value & 0x0000FF00) << 8) | // Move the second byte to the third byte position
((value & 0x00FF0000) >> 8) | // Move the third byte to the second byte position
((value & 0xFF000000) >> 24); // Move the fourth byte to the first byte position
}
private static void RoundKeyUpdate0(ref uint[] T, ref uint[] K, int K_offset, ref uint[] ABCD, uint KC)
{
T[0] = ABCD[ABCD_A] + ABCD[ABCD_C] - KC;
T[1] = ABCD[ABCD_B] + KC - ABCD[ABCD_D];
K[K_offset + 0] = Substitute(T[0]);
K[K_offset + 1] = Substitute(T[1]);
T[0] = ABCD[ABCD_A];
ABCD[ABCD_A] = ((ABCD[ABCD_A] >> 8) & 0x00ffffff) ^ (ABCD[ABCD_B] << 24);
ABCD[ABCD_B] = ((ABCD[ABCD_B] >> 8) & 0x00ffffff) ^ (T[0] << 24);
}
private static void RoundKeyUpdate1(ref uint[] T, ref uint[] K, int K_offset, ref uint[] ABCD, uint KC)
{
T[0] = ABCD[ABCD_A] + ABCD[ABCD_C] - KC;
T[1] = ABCD[ABCD_B] + KC - ABCD[ABCD_D];
K[K_offset + 0] = Substitute(T[0]);
K[K_offset + 1] = Substitute(T[1]);
T[0] = ABCD[ABCD_C];
ABCD[ABCD_C] = (ABCD[ABCD_C] << 8) ^ ((ABCD[ABCD_D] >> 24) & 0x000000ff);
ABCD[ABCD_D] = (ABCD[ABCD_D] << 8) ^ ((T[0] >> 24) & 0x000000ff);
}
public class ECB
{
public void EncryptBlock(in uint[] _in, int in_offset, ref uint[] _out, int out_offset, KISA_SEED_KEY ks)
{
uint[] LR = new uint[4]; // Iuput/output values at each rounds
uint[] T = new uint[2]; // Temporary variables for round function F
uint[] K = ks.key_data; // Pointer of round keys
// Set up input values for first round
LR[LR_L0] = _in[in_offset + 0];
LR[LR_L1] = _in[in_offset + 1];
LR[LR_R0] = _in[in_offset + 2];
LR[LR_R1] = _in[in_offset + 3];
// Reorder for big endian
// Because SEED use little endian order in default
if (ENDIAN.BIG != DEFAULT_ENDIAN)
{
LR[LR_L0] = EndianChange(LR[LR_L0]);
LR[LR_L1] = EndianChange(LR[LR_L1]);
LR[LR_R0] = EndianChange(LR[LR_R0]);
LR[LR_R1] = EndianChange(LR[LR_R1]);
}
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 0); // Round 1
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 2); // Round 2
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 4); // Round 3
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 6); // Round 4
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 8); // Round 5
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 10); // Round 6
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 12); // Round 7
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 14); // Round 8
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 16); // Round 9
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 18); // Round 10
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 20); // Round 11
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 22); // Round 12
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 24); // Round 13
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 26); // Round 14
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 28); // Round 15
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 30); // Round 16
if (ENDIAN.BIG != DEFAULT_ENDIAN)
{
LR[LR_L0] = EndianChange(LR[LR_L0]);
LR[LR_L1] = EndianChange(LR[LR_L1]);
LR[LR_R0] = EndianChange(LR[LR_R0]);
LR[LR_R1] = EndianChange(LR[LR_R1]);
}
// Copying output values from last round to pbData
_out[out_offset + 0] = LR[LR_R0];
_out[out_offset + 1] = LR[LR_R1];
_out[out_offset + 2] = LR[LR_L0];
_out[out_offset + 3] = LR[LR_L1];
}
public void DecryptBlock(in uint[] _in, int in_offset, ref uint[] _out, int out_offset, KISA_SEED_KEY ks)
{
uint[] LR = new uint[4]; // Iuput/output values at each rounds
uint[] T = new uint[2]; // Temporary variables for round function F
uint[] K = ks.key_data; // Pointer of round keys
// Set up input values for first round
LR[LR_L0] = _in[in_offset + 0];
LR[LR_L1] = _in[in_offset + 1];
LR[LR_R0] = _in[in_offset + 2];
LR[LR_R1] = _in[in_offset + 3];
// Reorder for big endian
if (ENDIAN.BIG != DEFAULT_ENDIAN)
{
LR[LR_L0] = EndianChange(LR[LR_L0]);
LR[LR_L1] = EndianChange(LR[LR_L1]);
LR[LR_R0] = EndianChange(LR[LR_R0]);
LR[LR_R1] = EndianChange(LR[LR_R1]);
}
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 30); // Round 1
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 28); // Round 2
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 26); // Round 3
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 24); // Round 4
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 22); // Round 5
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 20); // Round 6
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 18); // Round 7
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 16); // Round 8
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 14); // Round 9
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 12); // Round 10
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 10); // Round 11
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 8); // Round 12
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 6); // Round 13
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 4); // Round 14
SeedRound(ref T, ref LR, LR_L0, LR_L1, LR_R0, LR_R1, K, 2); // Round 15
SeedRound(ref T, ref LR, LR_R0, LR_R1, LR_L0, LR_L1, K, 0); // Round 16
if (ENDIAN.BIG != DEFAULT_ENDIAN)
{
LR[LR_L0] = EndianChange(LR[LR_L0]);
LR[LR_L1] = EndianChange(LR[LR_L1]);
LR[LR_R0] = EndianChange(LR[LR_R0]);
LR[LR_R1] = EndianChange(LR[LR_R1]);
}
// Copy output values from last round to pbData
_out[out_offset + 0] = LR[LR_R0];
_out[out_offset + 1] = LR[LR_R1];
_out[out_offset + 2] = LR[LR_L0];
_out[out_offset + 3] = LR[LR_L1];
}
public void Init(KISA_SEED_INFO pInfo, KISA_ENC_DEC enc, byte[] pbszUserKey)
{
uint[] ABCD = new uint[4]; // Iuput/output values at each rounds
uint[] T = new uint[2]; // Temporary variable
uint[] K;
if (pInfo == null || pbszUserKey == null)
throw new ArgumentException("Invalid arguments");
K = pInfo.seed_key.key_data; // Pointer of round keys
pInfo.encrypt = enc.value;
pInfo.last_block_flag = pInfo.buffer_length = 0;
// Set up input values for Key Schedule
ABCD[ABCD_A] = GetUIntFromByteArray(pbszUserKey, 0 * 4, DEFAULT_ENDIAN);
ABCD[ABCD_B] = GetUIntFromByteArray(pbszUserKey, 1 * 4, DEFAULT_ENDIAN);
ABCD[ABCD_C] = GetUIntFromByteArray(pbszUserKey, 2 * 4, DEFAULT_ENDIAN);
ABCD[ABCD_D] = GetUIntFromByteArray(pbszUserKey, 3 * 4, DEFAULT_ENDIAN);
// Reorder for big endian
if (ENDIAN.BIG != DEFAULT_ENDIAN)
{
ABCD[ABCD_A] = EndianChange(ABCD[ABCD_A]);
ABCD[ABCD_B] = EndianChange(ABCD[ABCD_B]);
ABCD[ABCD_C] = EndianChange(ABCD[ABCD_C]);
ABCD[ABCD_D] = EndianChange(ABCD[ABCD_D]);
}
// i-th round keys( K_i,0 and K_i,1 ) are denoted as K[2*(i-1)] and K[2*i-1], respectively
RoundKeyUpdate0(ref T, ref K, 0, ref ABCD, KC0); // K_1,0 and K_1,1
RoundKeyUpdate1(ref T, ref K, 2, ref ABCD, KC1); // K_2,0 and K_2,1
RoundKeyUpdate0(ref T, ref K, 4, ref ABCD, KC2); // K_3,0 and K_3,1
RoundKeyUpdate1(ref T, ref K, 6, ref ABCD, KC3); // K_4,0 and K_4,1
RoundKeyUpdate0(ref T, ref K, 8, ref ABCD, KC4); // K_5,0 and K_5,1
RoundKeyUpdate1(ref T, ref K, 10, ref ABCD, KC5); // K_6,0 and K_6,1
RoundKeyUpdate0(ref T, ref K, 12, ref ABCD, KC6); // K_7,0 and K_7,1
RoundKeyUpdate1(ref T, ref K, 14, ref ABCD, KC7); // K_8,0 and K_8,1
RoundKeyUpdate0(ref T, ref K, 16, ref ABCD, KC8); // K_9,0 and K_9,1
RoundKeyUpdate1(ref T, ref K, 18, ref ABCD, KC9); // K_10,0 and K_10,1
RoundKeyUpdate0(ref T, ref K, 20, ref ABCD, KC10); // K_11,0 and K_11,1
RoundKeyUpdate1(ref T, ref K, 22, ref ABCD, KC11); // K_12,0 and K_12,1
RoundKeyUpdate0(ref T, ref K, 24, ref ABCD, KC12); // K_13,0 and K_13,1
RoundKeyUpdate1(ref T, ref K, 26, ref ABCD, KC13); // K_14,0 and K_14,1
RoundKeyUpdate0(ref T, ref K, 28, ref ABCD, KC14); // K_15,0 and K_15,1
T[0] = ABCD[ABCD_A] + ABCD[ABCD_C] - KC15;
T[1] = ABCD[ABCD_B] - ABCD[ABCD_D] + KC15;
K[30] = SS0[GetByteFromUInt(T[0], 0) & 0x0ff] ^ SS1[GetByteFromUInt(T[0], 1) & 0x0ff] ^ // K_16,0
SS2[GetByteFromUInt(T[0], 2) & 0x0ff] ^ SS3[GetByteFromUInt(T[0], 3) & 0x0ff];
K[31] = SS0[GetByteFromUInt(T[1], 0) & 0x0ff] ^ SS1[GetByteFromUInt(T[1], 1) & 0x0ff] ^ // K_16,1
SS2[GetByteFromUInt(T[1], 2) & 0x0ff] ^ SS3[GetByteFromUInt(T[1], 3) & 0x0ff];
}
public void Process(KISA_SEED_INFO pInfo, in uint[] _in, int inLen, ref uint[] _out, ref int[] outLen)
{
int nCurrentCount = BLOCK_SIZE_SEED;
int in_offset = 0;
int out_offset = 0;
if (pInfo == null || _in == null || _out == null || inLen <= 0)
throw new ArgumentException("Invalid arguments.");
if (KISA_ENC_DEC._KISA_ENCRYPT == pInfo.encrypt)
{
while (nCurrentCount <= inLen)
{
EncryptBlock(_in, in_offset, ref _out, out_offset, pInfo.seed_key);
nCurrentCount += BLOCK_SIZE_SEED;
in_offset += BLOCK_SIZE_SEED_INT;
out_offset += BLOCK_SIZE_SEED_INT;
}
outLen[0] = nCurrentCount - BLOCK_SIZE_SEED;
pInfo.buffer_length = inLen - outLen[0];
Array.Copy(_in, in_offset, pInfo.ecb_buffer, 0, pInfo.buffer_length);
}
else
{
while (nCurrentCount <= inLen)
{
DecryptBlock(_in, in_offset, ref _out, out_offset, pInfo.seed_key);
nCurrentCount += BLOCK_SIZE_SEED;
in_offset += BLOCK_SIZE_SEED_INT;
out_offset += BLOCK_SIZE_SEED_INT;
}
outLen[0] = nCurrentCount - BLOCK_SIZE_SEED;
Array.Copy(_out, out_offset - BLOCK_SIZE_SEED_INT, pInfo.ecb_last_block, 0, BLOCK_SIZE_SEED);
}
}
public bool Close(KISA_SEED_INFO pInfo, uint[] _out, int out_offset, ref int[] outLen)
{
int nPaddngLen;
outLen[0] = 0;
if (_out == null)
return false;
if (KISA_ENC_DEC._KISA_ENCRYPT == pInfo.encrypt)
{
nPaddngLen = BLOCK_SIZE_SEED - pInfo.buffer_length;
for (int i = pInfo.buffer_length; i < BLOCK_SIZE_SEED; i++)
{
SetByteToUIntArray(ref pInfo.ecb_buffer, i, (byte)nPaddngLen, DEFAULT_ENDIAN);
}
EncryptBlock(pInfo.ecb_buffer, 0, ref _out, (out_offset) / 4, pInfo.seed_key);
outLen[0] = BLOCK_SIZE_SEED;
}
else
{
nPaddngLen = GetByteFromUIntArray(pInfo.ecb_last_block, BLOCK_SIZE_SEED - 1, DEFAULT_ENDIAN);
if (nPaddngLen > 0 && nPaddngLen <= BLOCK_SIZE_SEED)
{
for (int i = nPaddngLen; i > 0; i--)
{
SetByteToUIntArray(ref _out, out_offset - i, (byte)0x00, DEFAULT_ENDIAN);
}
outLen[0] = nPaddngLen;
}
else
{
return false;
}
}
return true;
}
public byte[] Encrypt(byte[] pbszUserKey, byte[] pbData, int offset, int length)
{
KISA_SEED_INFO info = new KISA_SEED_INFO();
uint[] _out;
uint[] data;
byte[] cdata;
int outLen;
int[] nRetOutLen = new int[] { 0 };
int[] nPaddingLen = new int[] { 0 };
byte[] pbszPlainText = new byte[length];
Array.Copy(pbData, offset, pbszPlainText, 0, length);
int nPlainTextLen = length;
int nPlainTextPadding = (BLOCK_SIZE_SEED - (nPlainTextLen) % BLOCK_SIZE_SEED);
byte[] newpbszPlainText = new byte[nPlainTextLen + nPlainTextPadding];
Array.Copy(pbszPlainText, newpbszPlainText, nPlainTextLen);
byte[] pbszCipherText = new byte[nPlainTextLen + nPlainTextPadding];
Init(info, KISA_ENC_DEC.KISA_ENCRYPT, pbszUserKey);
outLen = ((nPlainTextLen / 16) + 1) * 4;
_out = new uint[outLen];
data = ConvertToUIntArray(newpbszPlainText, nPlainTextLen);
Process(info, data, nPlainTextLen, ref _out, ref nRetOutLen);
Close(info, _out, nRetOutLen[0], ref nPaddingLen);
cdata = ConvertToByteArray(_out, nRetOutLen[0] + nPaddingLen[0]);
Array.Copy(cdata, pbszCipherText, nRetOutLen[0] + nPaddingLen[0]);
data = null;
cdata = null;
_out = null;
return pbszCipherText;
}
public byte[] Decrypt(byte[] pbszUserKey, byte[] pbData, int offset, int length)
{
byte[] result = new byte[] { };
KISA_SEED_INFO info = new KISA_SEED_INFO();
uint[] _out;
uint[] data;
byte[] cdata;
int outLen = 0;
int[] nRetOutLen = new int[] { 0 };
int[] nPaddingLen = new int[] { 0 };
byte[] pbszCipherText = pbData;
int nCipherTextLen = length;
if (nCipherTextLen % BLOCK_SIZE_SEED > 0)
{
return result;
}
byte[] newpbszCipherText = new byte[nCipherTextLen];
Array.Copy(pbszCipherText, newpbszCipherText, nCipherTextLen);
byte[] pbszPlainText = new byte[nCipherTextLen];
Init(info, KISA_ENC_DEC.KISA_DECRYPT, pbszUserKey);
outLen = (nCipherTextLen / 16) * 4;
_out = new uint[outLen];
data = ConvertToUIntArray(newpbszCipherText, nCipherTextLen);
Process(info, data, nCipherTextLen, ref _out, ref nRetOutLen);
if (Close(info, _out, nRetOutLen[0], ref nPaddingLen))
{
cdata = ConvertToByteArray(_out, nRetOutLen[0] - nPaddingLen[0]);
Array.Copy(cdata, pbszPlainText, nRetOutLen[0] - nPaddingLen[0]);
int message_length = nRetOutLen[0] - nPaddingLen[0];
if (message_length < 0)
{
message_length = 0;
}
result = new byte[message_length];
Array.Copy(pbszPlainText, 0, result, 0, message_length);
data = null;
cdata = null;
_out = null;
}
return result;
}
}
public static void SetDefaultEndian(ENDIAN endian)
{
DEFAULT_ENDIAN = endian;
}
public class KISA_ENC_DEC
{
public const int _KISA_DECRYPT = 0;
public const int _KISA_ENCRYPT = 1;
public int value;
public KISA_ENC_DEC(int value)
{
this.value = value;
}
public static KISA_ENC_DEC KISA_ENCRYPT = new KISA_ENC_DEC(_KISA_ENCRYPT);
public static KISA_ENC_DEC KISA_DECRYPT = new KISA_ENC_DEC(_KISA_DECRYPT);
}
public class KISA_SEED_KEY
{
public uint[] key_data = new uint[32];
public void Init()
{
for (int i = 0; i < key_data.Length; i++)
{
key_data[i] = 0;
}
}
}
public class KISA_SEED_INFO
{
public int encrypt;
public KISA_SEED_KEY seed_key = new KISA_SEED_KEY();
public uint[] ecb_buffer = new uint[4];
public int buffer_length;
public uint[] ecb_last_block = new uint[4];
public int last_block_flag;
public KISA_SEED_INFO()
{
encrypt = 0;
seed_key.Init();
ecb_buffer[0] = ecb_buffer[1] = ecb_buffer[2] = ecb_buffer[3] = 0;
buffer_length = 0;
ecb_last_block[0] = ecb_last_block[1] = ecb_last_block[2] = ecb_last_block[3] = 0;
last_block_flag = 0;
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* WelsonJS.Toolkit: WelsonJS dotNET native component
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* NamedSharedMemory.cs
@ -10,6 +10,7 @@
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
*
* author:
* Namhyeon Go <abuse@catswords.net>
@ -30,7 +31,7 @@ namespace WelsonJS
private IntPtr hFile;
private IntPtr hFileMappingObject;
private string lpName;
private static Dictionary<string, NamedSharedMemory> memDict = new Dictionary<string, NamedSharedMemory>();
private static Dictionary<string, NamedSharedMemory> memoryMap = new Dictionary<string, NamedSharedMemory>();
[Flags]
public enum FileProtection : uint
@ -62,7 +63,7 @@ namespace WelsonJS
FILE_MAP_ALL_ACCESS = 0xF001F
}
public static class FileMappingNative
public class FileMappingNative
{
public const int INVALID_HANDLE_VALUE = -1;
@ -95,10 +96,10 @@ namespace WelsonJS
public bool Open()
{
if (memDict.ContainsKey(lpName))
if (memoryMap.ContainsKey(lpName))
{
hFile = memDict[lpName].hFile;
hFileMappingObject = memDict[lpName].hFileMappingObject;
hFile = memoryMap[lpName].hFile;
hFileMappingObject = memoryMap[lpName].hFileMappingObject;
return true;
}
@ -106,7 +107,7 @@ namespace WelsonJS
{
hFile = FileMappingNative.CreateFileMapping((IntPtr)(-1), IntPtr.Zero, FileProtection.PAGE_READWRITE, 0u, 1024u, lpName);
hFileMappingObject = FileMappingNative.MapViewOfFile(hFile, FileMapAccess.FILE_MAP_ALL_ACCESS, 0u, 0u, 1024u);
memDict.Add(lpName, this);
memoryMap.Add(lpName, this);
}
catch
{
@ -123,13 +124,28 @@ namespace WelsonJS
public string ReadText()
{
return Marshal.PtrToStringAnsi(hFileMappingObject);
try
{
if (hFile == IntPtr.Zero || hFileMappingObject == IntPtr.Zero)
{
throw new Exception("Could not access the shared memory");
}
return Marshal.PtrToStringAnsi(hFileMappingObject);
}
catch (Exception e)
{
return "Exception: " + e.Message;
}
}
public bool WriteText(string text, int size = 1024)
{
try
{
if (hFile == IntPtr.Zero || hFileMappingObject == IntPtr.Zero)
{
throw new Exception("Could not access the shared memory");
}
byte[] bytes = Encoding.ASCII.GetBytes(text);
byte[] array = new byte[size + 1];
Array.Copy(bytes, array, bytes.Length);
@ -161,17 +177,15 @@ namespace WelsonJS
{
try
{
if (hFileMappingObject != IntPtr.Zero)
if (hFile == IntPtr.Zero || hFileMappingObject == IntPtr.Zero)
{
FileMappingNative.UnmapViewOfFile(hFileMappingObject);
hFileMappingObject = IntPtr.Zero;
throw new Exception("Could not access the shared memory");
}
if (hFile != IntPtr.Zero)
{
FileMappingNative.CloseHandle(hFile);
hFile = IntPtr.Zero;
}
FileMappingNative.UnmapViewOfFile(hFileMappingObject);
hFileMappingObject = IntPtr.Zero;
FileMappingNative.CloseHandle(hFile);
hFile = IntPtr.Zero;
}
catch
{

View File

@ -0,0 +1,90 @@
/*
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* ProcessUtils.cs
*
* description:
* WelsonJS - Build a Windows app on the Windows built-in JavaScript engine
*
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
*
* author:
* Namhyeon Go <abuse@catswords.net>
*
* license:
* GPLv3 or MS-RL(Microsoft Reciprocal License)
*
*/
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
namespace WelsonJS
{
public class ProcessUtils
{
public static List<Process> ProcessList = new List<Process>();
public static string OpenFileDialog()
{
string filepath = string.Empty;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "All files (*.*)|*.*";
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filepath = openFileDialog.FileName;
}
}
return filepath;
}
public static int Open(string filepath)
{
int processId = -1;
if (string.IsNullOrEmpty(filepath))
{
filepath = OpenFileDialog();
if (string.IsNullOrEmpty(filepath))
{
return processId;
}
}
try
{
Process process = new Process();
process.StartInfo.FileName = filepath;
process.Start();
ProcessList.Add(process);
}
catch {
processId = -1;
}
return processId;
}
public static bool Close(int processId)
{
try
{
Process.GetProcessById(processId).CloseMainWindow();
}
catch
{
return false;
}
return true;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* WelsonJS.Toolkit: WelsonJS dotNET native component
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* Prompt.cs
@ -10,6 +10,7 @@
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
*
* author:
* Namhyeon Go <abuse@catswords.net>
@ -34,7 +35,7 @@ namespace WelsonJS
Text = caption,
StartPosition = FormStartPosition.CenterScreen
};
Label textLabel = new Label() { Left = 50, Top = 20, Text = text };
Label textLabel = new Label() { Left = 50, Top = 20, Width = 400, Text = text };
TextBox textBox = new TextBox() { Left = 50, Top = 50, Width = 400 };
Button confirmation = new Button() { Text = "Ok", Left = 350, Width = 100, Top = 70, DialogResult = DialogResult.OK };
confirmation.Click += (sender, e) => { prompt.Close(); };

View File

@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("WelsonJS.Toolkit")]
[assembly: AssemblyDescription("WelsonJS dotNET native component")]
[assembly: AssemblyDescription("Toolkit for WelsonJS framework based applications")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Catswords Research, Co.")]
[assembly: AssemblyProduct("WelsonJS.Toolkit")]
[assembly: AssemblyCopyright("Catswords Research, Co. (Licensed under GPLv3 or MS-RL)")]
[assembly: AssemblyCompany("Catswords")]
[assembly: AssemblyProduct("WelsonJS")]
[assembly: AssemblyCopyright("Catswords OSS, GPLv3 or Ms-RL")]
[assembly: AssemblyTrademark("WelsonJS")]
[assembly: AssemblyCulture("")]
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.2.7.54")]
[assembly: AssemblyFileVersion("0.2.7.54")]

View File

@ -0,0 +1,28 @@
using System.Collections.Generic;
using System.Text;
namespace WelsonJS.Serialization
{
public class KVSerializer
{
private static Dictionary<string, string> dict = new Dictionary<string, string>();
public void Add(string key, string value)
{
dict[key] = value;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach (var x in dict)
{
sb.Append($"{x.Key}={x.Value}; ");
}
if (sb.Length > 0) sb.Length -= 2;
return sb.ToString();
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
// TinyINIController
// Original source code: https://github.com/niklyadov/tiny-ini-file-class
namespace WelsonJS.TinyINIController
{
public class IniFile
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
static extern long WritePrivateProfileString(string section, string key, string value, string FilePath);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
static extern int GetPrivateProfileString(string section, string key, string Default, StringBuilder RetVal, int Size, string FilePath);
private readonly FileInfo FileInfo;
//private readonly string exe = Assembly.GetExecutingAssembly().GetName().Name;
private readonly string defaultSection = "Default";
private readonly FileAccess fileAccess;
public IniFile(string path = null, FileAccess access = FileAccess.ReadWrite)
{
fileAccess = access;
FileInfo = new FileInfo(path ?? defaultSection);
}
public string Read(string key, string section = null)
{
var RetVal = new StringBuilder(65025);
if (fileAccess != FileAccess.Write)
{
GetPrivateProfileString(section ?? defaultSection, key, "", RetVal, 65025, FileInfo.FullName);
}
else
{
throw new Exception("Can`t read file! No access!");
}
return RetVal.ToString();
}
public void Write(string key, string value, string section = null)
{
if (fileAccess != FileAccess.Read)
{
WritePrivateProfileString(section ?? defaultSection, key, value, FileInfo.FullName);
}
else
{
throw new Exception("Can`t write to file! No access!");
}
}
public void DeleteKey(string key, string section = null)
{
Write(key, null, section ?? defaultSection);
}
public void DeleteSection(string section = null)
{
Write(null, null, section ?? defaultSection);
}
public bool KeyExists(string key, string section = null)
{
return Read(key, section).Length > 0;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* WelsonJS.Toolkit: WelsonJS dotNET native component
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* Toolkit.cs
@ -10,6 +10,7 @@
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
*
* author:
* Namhyeon Go <abuse@catswords.net>
@ -30,7 +31,10 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using WelsonJS.Cryptography;
using WelsonJS.Serialization;
namespace WelsonJS
{
@ -190,15 +194,91 @@ namespace WelsonJS
return false;
}
public void CompressLZ77(string input)
[ComVisible(true)]
public string GetFilePathFromDialog()
{
Compression.LZ77.Compress(input);
return ProcessUtils.OpenFileDialog();
}
[ComVisible(true)]
public string DecompressLZ77(string compressData)
public int OpenProcess(string filepath)
{
return Compression.LZ77.Decompress(compressData);
return ProcessUtils.Open(filepath);
}
[ComVisible(true)]
public bool CloseProcess(int processID)
{
return ProcessUtils.Close(processID);
}
[ComVisible(true)]
public string CompressLZ77(string data)
{
return Compression.LZ77.Compress(data);
}
[ComVisible(true)]
public string DecompressLZ77(string compressedData)
{
return Compression.LZ77.Decompress(compressedData);
}
[ComVisible(true)]
public string EncryptString(string key, string data)
{
byte[] userKey = Encoding.ASCII.GetBytes(key);
byte[] dataIn = Encoding.UTF8.GetBytes(data);
HIGHT.ECB cipher = new HIGHT.ECB(userKey);
return Convert.ToBase64String(cipher.Encrypt(dataIn));
}
[ComVisible(true)]
public string DecryptString(string key, string encryptedData)
{
byte[] userKey = Encoding.ASCII.GetBytes(key);
byte[] dataIn = Convert.FromBase64String(encryptedData);
HIGHT.ECB cipher = new HIGHT.ECB(userKey);
return Encoding.UTF8.GetString(cipher.Decrypt(dataIn)).Trim('\0');
}
[ComVisible(true)]
public string GetImageSize(string srcfile)
{
int[] result = BitmapUtils.GetSize(srcfile);
var serializer = new KVSerializer();
serializer.Add("width", result[0].ToString());
serializer.Add("height", result[1].ToString());
return serializer.ToString();
}
[ComVisible(true)]
public string GetImagePixel(string srcfile)
{
int[] result = BitmapUtils.GetSize(srcfile);
var serializer = new KVSerializer();
serializer.Add("red", result[0].ToString());
serializer.Add("green", result[1].ToString());
serializer.Add("blue", result[2].ToString());
return serializer.ToString();
}
[ComVisible(true)]
public string GetImageBase64(string srcfile)
{
return BitmapUtils.GetBase64(srcfile);
}
[ComVisible(true)]
public void CropImage(string srcfile, string dstfile, int x, int y, int a, int b)
{
BitmapUtils.Crop(srcfile, dstfile, x, y, a, b);
}
}
}

View File

@ -41,21 +41,76 @@
<PropertyGroup>
<AssemblyOriginatorKeyFile>welsonjs.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon>
<PackageIcon>icon.png</PackageIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="BitmapUtils.cs" />
<Compile Include="Compression\LZ77.cs" />
<Compile Include="Cryptography\AnsiX923Padding.cs" />
<Compile Include="Cryptography\ARIA.cs" />
<Compile Include="Cryptography\HIGHT.cs" />
<Compile Include="Cryptography\LEA.cs" />
<Compile Include="Cryptography\PKCS5Padding.cs" />
<Compile Include="Cryptography\SEED.cs" />
<Compile Include="NamedSharedMemory.cs" />
<Compile Include="ProcessUtils.cs" />
<Compile Include="Prompt.cs" />
<Compile Include="Serialization\KVSerializer.cs" />
<Compile Include="TinyINIController\IniFile.cs" />
<Compile Include="Toolkit.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Window.cs" />
</ItemGroup>
<ItemGroup>
<None Include="welsonjs.snk" />
<None Include="WelsonJS.Toolkit.nuspec" />
<None Include="assets/img/logo.png" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<Content Include="favicon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>$id$</id>
<version>0.2.7.49</version>
<title>$title$</title>
<authors>Namhyeon Go, Catswords OSS</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">GPL-3.0-only</license>
<icon>logo.png</icon>
<readme>README.md</readme>
<projectUrl>https://github.com/gnh1201/welsonjs</projectUrl>
<description>Native toolkit for WelsonJS framework-based RPA applications.</description>
<releaseNotes>Updated release</releaseNotes>
<copyright>$copyright$</copyright>
<tags>rpa com scripting library javascript ini window-handle named-shared-memory</tags>
</metadata>
<files>
<file src="assets\img\logo.png" />
<file src="assets\docs\README.md" />
</files>
</package>

View File

@ -1,5 +1,5 @@
/*
* WelsonJS.Toolkit: WelsonJS dotNET native component
* WelsonJS.Toolkit: WelsonJS native component
*
* filename:
* Window.cs
@ -10,6 +10,7 @@
* website:
* - https://github.com/gnh1201/welsonjs
* - https://catswords.social/@catswords_oss
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
*
* author:
* Namhyeon Go <abuse@catswords.net>

View File

@ -0,0 +1,17 @@
# WelsonJS.Toolkit
WelsonJS.Toolkit is a native toolkit for WelsonJS. Of course, it can also be used in other projects.
This library supports COM and provides the following features:
* Access and control Windows handles
* Send keyboard and mouse click commands to Windows handles
* Use Named Shared Memory
* Read and modify INI files
* Encryption (HIGHT)
* Compression (LZ77)
* Bitmap handling
For more details, refer to the [WelsonJS Documentation](https://catswords-oss.rdbl.io/5719744820/5330609327).
Source code available: https://github.com/gnh1201/welsonjs

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Some files were not shown because too many files have changed in this diff Show More