33 Commits

Author SHA1 Message Date
Bruce
2c6391804e Update style. 2026-04-10 14:18:04 +08:00
Bruce
fa65d40f3e Update font use. 2026-04-10 14:13:24 +08:00
Bruce
2fd73eab85 Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-10 14:08:22 +08:00
modernw
9111c019ff Update README.md 2026-04-10 14:00:51 +08:00
Bruce
200262d3ca Fix bugs. 2026-04-10 13:58:15 +08:00
Bruce
0f7c4be17e Revert "update."
This reverts commit c28c09973e.
2026-04-10 12:16:59 +08:00
Bruce
ded9ea9293 try to fix bugs. 2026-04-10 12:16:12 +08:00
Bruce
f563f97f12 Try to fix bugs. 2026-04-10 10:50:22 +08:00
Bruce
19757502ae fix bugs. 2026-04-09 22:16:47 +08:00
Bruce
c28c09973e update. 2026-04-09 21:37:00 +08:00
Bruce
8dd01a67e9 Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-09 21:36:48 +08:00
Bruce
84a28db8cf Update locale resources. 2026-04-09 18:04:40 +08:00
modernw
b315782df6 Add special thanks section to README
Added a section for special thanks and contributor acknowledgment.
2026-04-09 15:39:16 +08:00
Bruce
9ba3b875da Update special thanks. 2026-04-09 14:10:57 +08:00
Bruce
9ae2e886bd Update special thanks. 2026-04-09 14:09:58 +08:00
Bruce
0926da3f27 Update license. 2026-04-09 13:34:09 +08:00
Bruce
4355ce4d13 Update help text. 2026-04-09 12:57:35 +08:00
Bruce
90d16151f4 pkgcli: add the confirm before remove. 2026-04-09 12:30:14 +08:00
Bruce
4bddb96052 Pkgcli: add the confirm before install. 2026-04-09 12:29:46 +08:00
Bruce
368efeb2f0 Update pkgcli. 2026-04-09 12:07:44 +08:00
Bruce
8e8a0453c4 Update PkgCLI. 2026-04-08 23:42:55 +08:00
Bruce
e58b47926c Canceled the settings of console input encoding. 2026-04-08 23:39:09 +08:00
Bruce
6d40668c1a Update version. 2026-04-08 23:35:14 +08:00
Bruce
71c8d76593 Fix bugs.
Update PkgCLI.
2026-04-08 23:32:11 +08:00
Bruce
c4eaa4ad45 Change the styles of ContentDialog. 2026-04-06 20:43:20 +08:00
Bruce
9edccede4e Update ContentDialog Styles. 2026-04-06 18:52:40 +08:00
Bruce
1d7359ebdd Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-06 18:46:56 +08:00
Bruce
fafff1bc5c Update locale strings.
Add a new project.
Remove the datas for test.
2026-04-06 18:46:51 +08:00
modernw
be599991b8 Update README to clarify AI assistance and GitHub usage 2026-04-06 18:43:19 +08:00
Bruce
48954e5206 Update item. 2026-04-06 15:18:27 +08:00
Bruce
a7c22adc05 Update libs used. 2026-04-06 13:29:14 +08:00
Bruce
be643a9935 Not use WinJS 3.0. 2026-04-06 13:13:54 +08:00
Bruce
64f3958d7f Update reader. 2026-04-06 13:09:20 +08:00
110 changed files with 20685 additions and 174793 deletions

View File

@@ -77,197 +77,281 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reader", "Reader\Reader.csp
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pugixml", "pugixml\pugixml.vcxproj", "{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pugixml", "pugixml\pugixml.vcxproj", "{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PkgCLI", "PkgCLI\PkgCLI.csproj", "{8D333AF6-E901-4301-B3EE-923088E81062}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM Debug|ARM = Debug|ARM
Debug|x86 = Debug|x86 Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM Release|ARM = Release|ARM
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|Any CPU.ActiveCfg = Debug|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|ARM.ActiveCfg = Debug|ARM {A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|ARM.ActiveCfg = Debug|ARM
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|ARM.Build.0 = Debug|ARM {A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|ARM.Build.0 = Debug|ARM
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|x86.ActiveCfg = Debug|Win32 {A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|x86.ActiveCfg = Debug|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|x86.Build.0 = Debug|Win32 {A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|x86.Build.0 = Debug|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|Any CPU.ActiveCfg = Release|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|ARM.ActiveCfg = Release|ARM {A7753282-AA16-43D9-8ACA-7065239DD702}.Release|ARM.ActiveCfg = Release|ARM
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|ARM.Build.0 = Release|ARM {A7753282-AA16-43D9-8ACA-7065239DD702}.Release|ARM.Build.0 = Release|ARM
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.ActiveCfg = Release|Win32 {A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.ActiveCfg = Release|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.Build.0 = Release|Win32 {A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.Build.0 = Release|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|Any CPU.ActiveCfg = Debug|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|ARM.ActiveCfg = Debug|ARM {8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|ARM.ActiveCfg = Debug|ARM
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|ARM.Build.0 = Debug|ARM {8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|ARM.Build.0 = Debug|ARM
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|x86.ActiveCfg = Debug|Win32 {8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|x86.ActiveCfg = Debug|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|x86.Build.0 = Debug|Win32 {8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|x86.Build.0 = Debug|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|Any CPU.ActiveCfg = Release|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|ARM.ActiveCfg = Release|ARM {8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|ARM.ActiveCfg = Release|ARM
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|ARM.Build.0 = Release|ARM {8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|ARM.Build.0 = Release|ARM
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|x86.ActiveCfg = Release|Win32 {8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|x86.ActiveCfg = Release|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|x86.Build.0 = Release|Win32 {8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|x86.Build.0 = Release|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|Any CPU.ActiveCfg = Debug|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|ARM.ActiveCfg = Debug|ARM {798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|ARM.ActiveCfg = Debug|ARM
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|ARM.Build.0 = Debug|ARM {798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|ARM.Build.0 = Debug|ARM
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|x86.ActiveCfg = Debug|Win32 {798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|x86.ActiveCfg = Debug|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|x86.Build.0 = Debug|Win32 {798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|x86.Build.0 = Debug|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|Any CPU.ActiveCfg = Release|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|ARM.ActiveCfg = Release|ARM {798ED492-EECE-457D-8FD8-129DA93CE126}.Release|ARM.ActiveCfg = Release|ARM
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|ARM.Build.0 = Release|ARM {798ED492-EECE-457D-8FD8-129DA93CE126}.Release|ARM.Build.0 = Release|ARM
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|x86.ActiveCfg = Release|Win32 {798ED492-EECE-457D-8FD8-129DA93CE126}.Release|x86.ActiveCfg = Release|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|x86.Build.0 = Release|Win32 {798ED492-EECE-457D-8FD8-129DA93CE126}.Release|x86.Build.0 = Release|Win32
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|ARM.ActiveCfg = Debug|Any CPU {EF4012D4-EF08-499C-B803-177739350B2D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|ARM.Build.0 = Debug|Any CPU {EF4012D4-EF08-499C-B803-177739350B2D}.Debug|ARM.Build.0 = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|x86.ActiveCfg = Debug|Any CPU {EF4012D4-EF08-499C-B803-177739350B2D}.Debug|x86.ActiveCfg = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|x86.Build.0 = Debug|Any CPU {EF4012D4-EF08-499C-B803-177739350B2D}.Debug|x86.Build.0 = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|Any CPU.Build.0 = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|ARM.ActiveCfg = Release|Any CPU {EF4012D4-EF08-499C-B803-177739350B2D}.Release|ARM.ActiveCfg = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|ARM.Build.0 = Release|Any CPU {EF4012D4-EF08-499C-B803-177739350B2D}.Release|ARM.Build.0 = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.ActiveCfg = Release|Any CPU {EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.ActiveCfg = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.Build.0 = Release|Any CPU {EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.Build.0 = Release|Any CPU
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|Any CPU.ActiveCfg = Debug|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|ARM.ActiveCfg = Debug|ARM {E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|ARM.ActiveCfg = Debug|ARM
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|ARM.Build.0 = Debug|ARM {E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|ARM.Build.0 = Debug|ARM
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x86.ActiveCfg = Debug|Win32 {E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x86.ActiveCfg = Debug|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x86.Build.0 = Debug|Win32 {E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x86.Build.0 = Debug|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|Any CPU.ActiveCfg = Release|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|ARM.ActiveCfg = Release|ARM {E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|ARM.ActiveCfg = Release|ARM
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|ARM.Build.0 = Release|ARM {E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|ARM.Build.0 = Release|ARM
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.ActiveCfg = Release|Win32 {E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.ActiveCfg = Release|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.Build.0 = Release|Win32 {E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.Build.0 = Release|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|Any CPU.ActiveCfg = Debug|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|ARM.ActiveCfg = Debug|ARM {F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|ARM.ActiveCfg = Debug|ARM
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|ARM.Build.0 = Debug|ARM {F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|ARM.Build.0 = Debug|ARM
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x86.ActiveCfg = Debug|Win32 {F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x86.ActiveCfg = Debug|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x86.Build.0 = Debug|Win32 {F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x86.Build.0 = Debug|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|Any CPU.ActiveCfg = Release|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|ARM.ActiveCfg = Release|ARM {F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|ARM.ActiveCfg = Release|ARM
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|ARM.Build.0 = Release|ARM {F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|ARM.Build.0 = Release|ARM
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x86.ActiveCfg = Release|Win32 {F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x86.ActiveCfg = Release|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x86.Build.0 = Release|Win32 {F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x86.Build.0 = Release|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|Any CPU.ActiveCfg = Debug|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|ARM.ActiveCfg = Debug|ARM {AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|ARM.ActiveCfg = Debug|ARM
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|ARM.Build.0 = Debug|ARM {AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|ARM.Build.0 = Debug|ARM
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|x86.ActiveCfg = Debug|Win32 {AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|x86.ActiveCfg = Debug|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|x86.Build.0 = Debug|Win32 {AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|x86.Build.0 = Debug|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|Any CPU.ActiveCfg = Release|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|ARM.ActiveCfg = Release|ARM {AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|ARM.ActiveCfg = Release|ARM
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|ARM.Build.0 = Release|ARM {AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|ARM.Build.0 = Release|ARM
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|x86.ActiveCfg = Release|Win32 {AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|x86.ActiveCfg = Release|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|x86.Build.0 = Release|Win32 {AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|x86.Build.0 = Release|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|Any CPU.ActiveCfg = Debug|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|ARM.ActiveCfg = Debug|ARM {3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|ARM.ActiveCfg = Debug|ARM
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|ARM.Build.0 = Debug|ARM {3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|ARM.Build.0 = Debug|ARM
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|x86.ActiveCfg = Debug|Win32 {3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|x86.ActiveCfg = Debug|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|x86.Build.0 = Debug|Win32 {3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|x86.Build.0 = Debug|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|Any CPU.ActiveCfg = Release|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|ARM.ActiveCfg = Release|ARM {3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|ARM.ActiveCfg = Release|ARM
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|ARM.Build.0 = Release|ARM {3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|ARM.Build.0 = Release|ARM
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|x86.ActiveCfg = Release|Win32 {3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|x86.ActiveCfg = Release|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|x86.Build.0 = Release|Win32 {3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|x86.Build.0 = Release|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|Any CPU.ActiveCfg = Debug|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|ARM.ActiveCfg = Debug|ARM {18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|ARM.ActiveCfg = Debug|ARM
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|ARM.Build.0 = Debug|ARM {18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|ARM.Build.0 = Debug|ARM
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|x86.ActiveCfg = Debug|Win32 {18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|x86.ActiveCfg = Debug|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|x86.Build.0 = Debug|Win32 {18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|x86.Build.0 = Debug|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|Any CPU.ActiveCfg = Release|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|ARM.ActiveCfg = Release|ARM {18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|ARM.ActiveCfg = Release|ARM
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|ARM.Build.0 = Release|ARM {18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|ARM.Build.0 = Release|ARM
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|x86.ActiveCfg = Release|Win32 {18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|x86.ActiveCfg = Release|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|x86.Build.0 = Release|Win32 {18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|x86.Build.0 = Release|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|Any CPU.ActiveCfg = Debug|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|ARM.ActiveCfg = Debug|ARM {7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|ARM.ActiveCfg = Debug|ARM
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|ARM.Build.0 = Debug|ARM {7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|ARM.Build.0 = Debug|ARM
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|x86.ActiveCfg = Debug|Win32 {7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|x86.ActiveCfg = Debug|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|x86.Build.0 = Debug|Win32 {7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|x86.Build.0 = Debug|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|Any CPU.ActiveCfg = Release|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|ARM.ActiveCfg = Release|ARM {7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|ARM.ActiveCfg = Release|ARM
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|ARM.Build.0 = Release|ARM {7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|ARM.Build.0 = Release|ARM
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|x86.ActiveCfg = Release|Win32 {7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|x86.ActiveCfg = Release|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|x86.Build.0 = Release|Win32 {7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|x86.Build.0 = Release|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|Any CPU.ActiveCfg = Debug|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|ARM.ActiveCfg = Debug|ARM {33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|ARM.ActiveCfg = Debug|ARM
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|ARM.Build.0 = Debug|ARM {33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|ARM.Build.0 = Debug|ARM
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|x86.ActiveCfg = Debug|Win32 {33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|x86.ActiveCfg = Debug|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|x86.Build.0 = Debug|Win32 {33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|x86.Build.0 = Debug|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|Any CPU.ActiveCfg = Release|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|ARM.ActiveCfg = Release|ARM {33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|ARM.ActiveCfg = Release|ARM
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|ARM.Build.0 = Release|ARM {33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|ARM.Build.0 = Release|ARM
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|x86.ActiveCfg = Release|Win32 {33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|x86.ActiveCfg = Release|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|x86.Build.0 = Release|Win32 {33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|x86.Build.0 = Release|Win32
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|ARM.ActiveCfg = Debug|Any CPU {512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|ARM.Build.0 = Debug|Any CPU {512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|ARM.Build.0 = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|x86.ActiveCfg = Debug|Any CPU {512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|x86.ActiveCfg = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|x86.Build.0 = Debug|Any CPU {512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|x86.Build.0 = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|Any CPU.Build.0 = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|ARM.ActiveCfg = Release|Any CPU {512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|ARM.ActiveCfg = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|ARM.Build.0 = Release|Any CPU {512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|ARM.Build.0 = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|x86.ActiveCfg = Release|Any CPU {512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|x86.ActiveCfg = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|x86.Build.0 = Release|Any CPU {512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|x86.Build.0 = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|ARM.ActiveCfg = Debug|Any CPU {8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|ARM.Build.0 = Debug|Any CPU {8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|ARM.Build.0 = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|x86.ActiveCfg = Debug|Any CPU {8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|x86.ActiveCfg = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|x86.Build.0 = Debug|Any CPU {8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|x86.Build.0 = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|Any CPU.Build.0 = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|ARM.ActiveCfg = Release|Any CPU {8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|ARM.ActiveCfg = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|ARM.Build.0 = Release|Any CPU {8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|ARM.Build.0 = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|x86.ActiveCfg = Release|Any CPU {8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|x86.ActiveCfg = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|x86.Build.0 = Release|Any CPU {8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|x86.Build.0 = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|ARM.ActiveCfg = Debug|Any CPU {BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|ARM.ActiveCfg = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|ARM.Build.0 = Debug|Any CPU {BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|ARM.Build.0 = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|x86.ActiveCfg = Debug|Any CPU {BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|x86.ActiveCfg = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|x86.Build.0 = Debug|Any CPU {BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|x86.Build.0 = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|Any CPU.Build.0 = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|ARM.ActiveCfg = Release|Any CPU {BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|ARM.ActiveCfg = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|ARM.Build.0 = Release|Any CPU {BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|ARM.Build.0 = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|x86.ActiveCfg = Release|Any CPU {BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|x86.ActiveCfg = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|x86.Build.0 = Release|Any CPU {BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|x86.Build.0 = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|ARM.ActiveCfg = Debug|Any CPU {FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|ARM.Build.0 = Debug|Any CPU {FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|ARM.Build.0 = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|x86.ActiveCfg = Debug|Any CPU {FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|x86.ActiveCfg = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|x86.Build.0 = Debug|Any CPU {FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|x86.Build.0 = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|Any CPU.Build.0 = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|ARM.ActiveCfg = Release|Any CPU {FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|ARM.ActiveCfg = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|ARM.Build.0 = Release|Any CPU {FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|ARM.Build.0 = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|x86.ActiveCfg = Release|Any CPU {FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|x86.ActiveCfg = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|x86.Build.0 = Release|Any CPU {FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|x86.Build.0 = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|ARM.ActiveCfg = Debug|Any CPU {3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|ARM.Build.0 = Debug|Any CPU {3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|ARM.Build.0 = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|x86.ActiveCfg = Debug|Any CPU {3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|x86.ActiveCfg = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|x86.Build.0 = Debug|Any CPU {3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|x86.Build.0 = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|Any CPU.Build.0 = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|ARM.ActiveCfg = Release|Any CPU {3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|ARM.ActiveCfg = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|ARM.Build.0 = Release|Any CPU {3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|ARM.Build.0 = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|x86.ActiveCfg = Release|Any CPU {3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|x86.ActiveCfg = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|ARM.ActiveCfg = Debug|Any CPU {4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|ARM.Build.0 = Debug|Any CPU {4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|ARM.Build.0 = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|x86.ActiveCfg = Debug|Any CPU {4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|x86.ActiveCfg = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|x86.Build.0 = Debug|Any CPU {4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|x86.Build.0 = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|Any CPU.Build.0 = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|ARM.ActiveCfg = Release|Any CPU {4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|ARM.ActiveCfg = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|ARM.Build.0 = Release|Any CPU {4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|ARM.Build.0 = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|x86.ActiveCfg = Release|Any CPU {4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|x86.ActiveCfg = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|x86.Build.0 = Release|Any CPU {4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|x86.Build.0 = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|ARM.ActiveCfg = Debug|Any CPU {DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|ARM.ActiveCfg = Debug|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|ARM.Build.0 = Debug|Any CPU {DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|ARM.Build.0 = Debug|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|x86.ActiveCfg = Debug|x86 {DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|x86.ActiveCfg = Debug|x86
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|x86.Build.0 = Debug|x86 {DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|x86.Build.0 = Debug|x86
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|Any CPU.Build.0 = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|ARM.ActiveCfg = Release|Any CPU {DC074727-72E4-43C5-BAAF-E0D548104797}.Release|ARM.ActiveCfg = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|ARM.Build.0 = Release|Any CPU {DC074727-72E4-43C5-BAAF-E0D548104797}.Release|ARM.Build.0 = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|x86.ActiveCfg = Release|x86 {DC074727-72E4-43C5-BAAF-E0D548104797}.Release|x86.ActiveCfg = Release|x86
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|x86.Build.0 = Release|x86 {DC074727-72E4-43C5-BAAF-E0D548104797}.Release|x86.Build.0 = Release|x86
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|Any CPU.ActiveCfg = Debug|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|ARM.ActiveCfg = Debug|ARM {E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|ARM.ActiveCfg = Debug|ARM
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|ARM.Build.0 = Debug|ARM {E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|ARM.Build.0 = Debug|ARM
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|x86.ActiveCfg = Debug|Win32 {E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|x86.ActiveCfg = Debug|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|x86.Build.0 = Debug|Win32 {E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|x86.Build.0 = Debug|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|Any CPU.ActiveCfg = Release|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|ARM.ActiveCfg = Release|ARM {E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|ARM.ActiveCfg = Release|ARM
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|ARM.Build.0 = Release|ARM {E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|ARM.Build.0 = Release|ARM
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|x86.ActiveCfg = Release|Win32 {E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|x86.ActiveCfg = Release|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|x86.Build.0 = Release|Win32 {E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|x86.Build.0 = Release|Win32
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|ARM.ActiveCfg = Debug|Any CPU {C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|ARM.Build.0 = Debug|Any CPU {C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|ARM.Build.0 = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|x86.ActiveCfg = Debug|Any CPU {C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|x86.ActiveCfg = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|x86.Build.0 = Debug|Any CPU {C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|x86.Build.0 = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|Any CPU.Build.0 = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|ARM.ActiveCfg = Release|Any CPU {C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|ARM.ActiveCfg = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|ARM.Build.0 = Release|Any CPU {C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|ARM.Build.0 = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|x86.ActiveCfg = Release|Any CPU {C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|x86.ActiveCfg = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|x86.Build.0 = Release|Any CPU {C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|x86.Build.0 = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|ARM.ActiveCfg = Debug|Any CPU {F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|ARM.ActiveCfg = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|ARM.Build.0 = Debug|Any CPU {F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|ARM.Build.0 = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|x86.ActiveCfg = Debug|Any CPU {F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|x86.ActiveCfg = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|x86.Build.0 = Debug|Any CPU {F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|x86.Build.0 = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|Any CPU.Build.0 = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|ARM.ActiveCfg = Release|Any CPU {F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|ARM.ActiveCfg = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|ARM.Build.0 = Release|Any CPU {F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|ARM.Build.0 = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|x86.ActiveCfg = Release|Any CPU {F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|x86.ActiveCfg = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|x86.Build.0 = Release|Any CPU {F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|x86.Build.0 = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|ARM.ActiveCfg = Debug|Any CPU {26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|ARM.Build.0 = Debug|Any CPU {26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|ARM.Build.0 = Debug|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|x86.ActiveCfg = Debug|x86 {26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|x86.ActiveCfg = Debug|x86
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|x86.Build.0 = Debug|x86 {26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|x86.Build.0 = Debug|x86
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|Any CPU.Build.0 = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|ARM.ActiveCfg = Release|Any CPU {26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|ARM.ActiveCfg = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|ARM.Build.0 = Release|Any CPU {26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|ARM.Build.0 = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|x86.ActiveCfg = Release|x86 {26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|x86.ActiveCfg = Release|x86
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|x86.Build.0 = Release|x86 {26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|x86.Build.0 = Release|x86
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|Any CPU.ActiveCfg = Debug|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|ARM.ActiveCfg = Debug|ARM {B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|ARM.ActiveCfg = Debug|ARM
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|ARM.Build.0 = Debug|ARM {B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|ARM.Build.0 = Debug|ARM
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|x86.ActiveCfg = Debug|Win32 {B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|x86.ActiveCfg = Debug|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|x86.Build.0 = Debug|Win32 {B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|x86.Build.0 = Debug|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|Any CPU.ActiveCfg = Release|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|ARM.ActiveCfg = Release|ARM {B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|ARM.ActiveCfg = Release|ARM
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|ARM.Build.0 = Release|ARM {B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|ARM.Build.0 = Release|ARM
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|x86.ActiveCfg = Release|Win32 {B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|x86.ActiveCfg = Release|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|x86.Build.0 = Release|Win32 {B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|x86.Build.0 = Release|Win32
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|ARM.Build.0 = Debug|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|x86.ActiveCfg = Debug|x86
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|x86.Build.0 = Debug|x86
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|Any CPU.Build.0 = Release|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|ARM.ActiveCfg = Release|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|ARM.Build.0 = Release|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|x86.ActiveCfg = Release|x86
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|x86.Build.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -348,8 +348,18 @@ namespace AppxPackage
{ {
get get
{ {
string value; string value = null;
if (!TryGetValue (key, out value)) var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind)
{ {
value = string.Empty; value = string.Empty;
base [key] = value; base [key] = value;
@@ -370,8 +380,18 @@ namespace AppxPackage
} }
public string At (string key) public string At (string key)
{ {
string value; string value = null;
if (!TryGetValue (key, out value)) throw new KeyNotFoundException ($"PRBaseApplication.At: key \"{key}\" not found"); var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind) throw new KeyNotFoundException ($"MRApplication: cannot find key \"{key}\"");
if (!EnablePri ()) return value; if (!EnablePri ()) return value;
if (PriFileHelper.IsMsResourcePrefix (value)) if (PriFileHelper.IsMsResourcePrefix (value))
{ {
@@ -383,8 +403,18 @@ namespace AppxPackage
} }
public string NewAt (string key, bool toPriString) public string NewAt (string key, bool toPriString)
{ {
string value; string value = null;
if (!TryGetValue (key, out value)) var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind)
{ {
value = string.Empty; value = string.Empty;
base [key] = value; base [key] = value;

View File

@@ -31,11 +31,25 @@ namespace AppxPackage
"Square71x71Logo", "Square71x71Logo",
"StartPage", "StartPage",
"Tall150x310Logo", "Tall150x310Logo",
"VisualGroup",
"WideLogo", "WideLogo",
"Wide310x150Logo", "Wide310x150Logo",
"Executable" "Executable"
}; };
public static readonly string [] ImageFilePathItems = new string []
{
"LockScreenLogo",
"Logo",
"SmallLogo",
"Square150x150Logo",
"Square30x30Logo",
"Square310x310Logo",
"Square44x44Logo",
"Square70x70Logo",
"Square71x71Logo",
"Tall150x310Logo",
"WideLogo",
"Wide310x150Logo"
};
public static bool IsFilePathKey (string key) public static bool IsFilePathKey (string key)
{ {
foreach (var i in FilePathItems) foreach (var i in FilePathItems)
@@ -293,7 +307,7 @@ namespace AppxPackage
return obj.Trim ().ToLowerInvariant ().GetHashCode (); return obj.Trim ().ToLowerInvariant ().GetHashCode ();
} }
} }
private HashSet <string> set = new HashSet<string> (new TrimIgnoreCaseComparer ()); private HashSet<string> set = new HashSet<string> (new TrimIgnoreCaseComparer ());
public Dictionary<PriResourceKey, string> FileResourceAllValues (string resid, ZipOutputStream zos) public Dictionary<PriResourceKey, string> FileResourceAllValues (string resid, ZipOutputStream zos)
{ {
var comparer = new TrimIgnoreCaseComparer (); var comparer = new TrimIgnoreCaseComparer ();
@@ -716,12 +730,29 @@ namespace AppxPackage
return true; return true;
return false; return false;
} }
protected bool IsImageFilePathKey (string key)
{
foreach (var i in ConstData.ImageFilePathItems)
if ((i?.Trim ()?.ToLower () ?? "") == (key?.Trim ()?.ToLower () ?? ""))
return true;
return false;
}
public new string this [string key] public new string this [string key]
{ {
get get
{ {
string value; string value = null;
if (!TryGetValue (key, out value)) var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind)
{ {
value = string.Empty; value = string.Empty;
base [key] = value; base [key] = value;
@@ -742,8 +773,18 @@ namespace AppxPackage
} }
public string At (string key) public string At (string key)
{ {
string value; string value = null;
if (!TryGetValue (key, out value)) throw new KeyNotFoundException ($"PRBaseApplication.At: key \"{key}\" not found"); var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind) throw new KeyNotFoundException ($"MRApplication: cannot find key \"{key}\"");
if (!EnablePri ()) return value; if (!EnablePri ()) return value;
if (PriFileHelper.IsMsResourcePrefix (value)) if (PriFileHelper.IsMsResourcePrefix (value))
{ {
@@ -755,8 +796,18 @@ namespace AppxPackage
} }
public string NewAt (string key, bool toPriString) public string NewAt (string key, bool toPriString)
{ {
string value; string value = null;
if (!TryGetValue (key, out value)) var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind)
{ {
value = string.Empty; value = string.Empty;
base [key] = value; base [key] = value;
@@ -767,7 +818,7 @@ namespace AppxPackage
string pri = PriGetRes (value); string pri = PriGetRes (value);
return string.IsNullOrEmpty (pri) ? value : pri; return string.IsNullOrEmpty (pri) ? value : pri;
} }
if (IsFilePathKey (key) && !string.IsNullOrEmpty (value)) if (IsImageFilePathKey (key) && !string.IsNullOrEmpty (value))
{ {
string pri = PriGetRes (value); string pri = PriGetRes (value);
return string.IsNullOrEmpty (pri) ? value : pri; return string.IsNullOrEmpty (pri) ? value : pri;
@@ -777,7 +828,7 @@ namespace AppxPackage
public string NewAtBase64 (string key) public string NewAtBase64 (string key)
{ {
string value = NewAt (key, true); string value = NewAt (key, true);
if (!IsFilePathKey (key) || string.IsNullOrEmpty (value)) return ""; if (!IsImageFilePathKey (key) || string.IsNullOrEmpty (value)) return "";
switch (PackageReadHelper.GetPackageType (m_hReader)) switch (PackageReadHelper.GetPackageType (m_hReader))
{ {
case 1: // PKGTYPE_APPX case 1: // PKGTYPE_APPX
@@ -1759,6 +1810,753 @@ namespace AppxPackage
UsePri = parsePri; UsePri = parsePri;
} }
} }
public bool SaveJsonFileCS (string savefilepath)
{
try
{
#region
using (var fs = File.Create (savefilepath))
{
using (var zos = new ZipOutputStream (fs))
{
zos.SetLevel (9);
bool parsePri = UsePri;
bool usePri = EnablePri;
try
{
UsePri = false;
EnablePri = false;
object packageInfo = null;
#region file
var typestr = "unknown";
switch (Type)
{
case PackageType.Appx: typestr = "appx"; break;
case PackageType.Bundle: typestr = "bundle"; break;
default:
case PackageType.Unknown: typestr = "unknown"; break;
}
var rolestr = "unknown";
switch (Role)
{
case PackageRole.Application: rolestr = "application"; break;
case PackageRole.Framework: rolestr = "framework"; break;
case PackageRole.Resource: rolestr = "resource"; break;
default:
case PackageRole.Unknown: rolestr = "unknown"; break;
}
var pkgfile = new {
path = FilePath,
valid = IsValid,
type = typestr,
role = rolestr
};
#endregion
#region id
var id = Identity;
var pkgid = new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.ToString (),
realVersion = id.RealVersion.ToString (),
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case Architecture.ARM: return "arm";
case Architecture.ARM64: return "arm64";
case Architecture.Neutral: return "neutral";
case Architecture.x64: return "x64";
case Architecture.x86: return "x86";
default:
case Architecture.Unknown: return "unknown";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId
};
#endregion
#region prerequistes
var preq = Prerequisites;
var pkgpreq = new {
osMinVersion = preq.OSMinVersion.ToString (),
osMaxVersionTested = preq.OSMaxVersionTested.ToString (),
osMinVersionDescription = preq.OSMinVersionDescription,
osMaxVersionTestedDescription = preq.OSMaxVersionDescription
};
#endregion
#region resources
var res = Resources;
var pkgres = new {
languages = res.Languages,
scales = res.Scales,
dxFeatureLevels = res.DXFeatures.Select (d => {
switch (d)
{
case DXFeatureLevel.Level9: return 9;
case DXFeatureLevel.Level10: return 10;
case DXFeatureLevel.Level11: return 11;
case DXFeatureLevel.Level12: return 12;
default:
case DXFeatureLevel.Unspecified: return -1;
}
}).ToList ()
};
#endregion
#region capabilities
var caps = Capabilities;
var pkgcaps = new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
};
#endregion
#region dependencies
var deps = Dependencies;
var pkgdeps = Dependencies.Select (d => new {
name = d.Name,
publisher = d.Publisher,
minVersion = d.Version.ToString ()
}).ToList ();
#endregion
using (var priAllRes = new PriAllValuesReader (this))
{
priAllRes.Init ();
#region prop
var prop = Properties;
var dispname = prop.DisplayName;
var dispNameDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (dispname))
dispNameDict = priAllRes.LocaleResourceAllValues (dispname);
dispNameDict ["root"] = dispname;
var desc = prop.Description;
var descDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (desc))
descDict = priAllRes.LocaleResourceAllValues (desc);
descDict ["root"] = desc;
var disppub = prop.Publisher;
var dispPubDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (disppub))
dispPubDict = priAllRes.LocaleResourceAllValues (disppub);
dispPubDict ["root"] = disppub;
var logoList = priAllRes.FileResourceAllValues (prop.Logo, zos)
.Select (kv => {
string contrast = "";
switch (kv.Key.Contrast)
{
case PriResourceKey.PriContrast.None: contrast = ""; break;
case PriResourceKey.PriContrast.Black: contrast = "black"; break;
case PriResourceKey.PriContrast.White: contrast = "white"; break;
case PriResourceKey.PriContrast.High: contrast = "high"; break;
case PriResourceKey.PriContrast.Low: contrast = "low"; break;
}
if (kv.Key.IsTargetSize)
{
return new {
targetSize = kv.Key.Value,
contrast = contrast,
name = kv.Value
};
}
else if (kv.Key.IsScale)
{
return new {
scale = kv.Key.Value,
contrast = contrast,
name = kv.Value
};
}
else if (kv.Key.IsString)
{
return new {
language = kv.Key.Value,
name = kv.Value
};
}
else
{
return (dynamic)null; // 不满足条件时返回 null
}
})
.Where (item => item != null) // 过滤掉 null
.ToList ();
var pkgprop = new {
displayName = dispNameDict,
publisherDisplayName = dispPubDict,
description = descDict,
logo = logoList,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
};
#endregion
#region apps
var apps = Applications;
var pkgapps = new List<object> ();
foreach (var app in apps)
{
dynamic obj = new ExpandoObject ();
var dict = (IDictionary<string, object>)obj;
foreach (var kv in app)
{
if (Utils.AppFileProperties.Contains (kv.Key, StringComparer.OrdinalIgnoreCase))
{
dict [Utils.PascalToCamel (kv.Key)] = priAllRes.FileResourceAllValues (kv.Value, zos)
.Select (skv => {
string contrast = "";
switch (skv.Key.Contrast)
{
case PriResourceKey.PriContrast.None: contrast = ""; break;
case PriResourceKey.PriContrast.Black: contrast = "black"; break;
case PriResourceKey.PriContrast.White: contrast = "white"; break;
case PriResourceKey.PriContrast.High: contrast = "high"; break;
case PriResourceKey.PriContrast.Low: contrast = "low"; break;
}
if (skv.Key.IsTargetSize)
{
return new {
targetSize = skv.Key.Value,
contrast = contrast,
name = skv.Value
};
}
else if (skv.Key.IsScale)
{
return new {
scale = skv.Key.Value,
contrast = contrast,
name = skv.Value
};
}
else if (skv.Key.IsString)
{
return new {
language = skv.Key.Value,
name = skv.Value
};
}
else
{
return (dynamic)null; // 不满足条件时返回 null
}
}).Where (item => item != null).ToList ();
}
else
{
if (PriFileHelper.IsMsResourcePrefix (kv.Value))
{
var itemDict = new Dictionary<string, string> ();
itemDict = priAllRes.LocaleResourceAllValues (kv.Value);
itemDict ["root"] = kv.Value;
dict [Utils.PascalToCamel (kv.Key)] = itemDict;
}
else
{
dict [Utils.PascalToCamel (kv.Key)] = kv.Value;
}
}
}
pkgapps.Add (obj);
}
#endregion
packageInfo = new {
file = pkgfile,
identity = pkgid,
properties = pkgprop,
resources = pkgres,
prerequisites = pkgpreq,
applications = pkgapps,
capabilities = pkgcaps,
dependencies = pkgdeps
};
}
var jsonstr = Newtonsoft.Json.JsonConvert.SerializeObject (packageInfo, Newtonsoft.Json.Formatting.None);
var ze = new ZipEntry ("info.json");
ze.DateTime = DateTime.Now;
zos.PutNextEntry (ze);
var bytes = Encoding.UTF8.GetBytes (jsonstr);
zos.Write (bytes, 0, bytes.Length);
zos.CloseEntry ();
return true;
}
finally
{
EnablePri = usePri;
UsePri = parsePri;
}
}
}
#endregion
}
catch (Exception ex)
{
throw ex;
return false;
}
}
public bool SaveXmlFileCS (string savefilepath)
{
try
{
#region
using (var fs = File.Create (savefilepath))
{
using (var zos = new ZipOutputStream (fs))
{
zos.SetLevel (9);
bool parsePri = UsePri;
bool usePri = EnablePri;
try
{
UsePri = false;
EnablePri = false;
var xml = new XmlDocument ();
var decl = xml.CreateXmlDeclaration ("1.0", "utf-8", "yes");
xml.AppendChild (decl);
var root = xml.CreateElement ("Package");
xml.AppendChild (root);
#region file
var typestr = "unknown";
switch (Type)
{
case PackageType.Appx: typestr = "appx"; break;
case PackageType.Bundle: typestr = "bundle"; break;
default:
case PackageType.Unknown: typestr = "unknown"; break;
}
var rolestr = "unknown";
switch (Role)
{
case PackageRole.Application: rolestr = "application"; break;
case PackageRole.Framework: rolestr = "framework"; break;
case PackageRole.Resource: rolestr = "resource"; break;
default:
case PackageRole.Unknown: rolestr = "unknown"; break;
}
{
var nodefile = xml.CreateElement ("File");
var nodefilepath = xml.CreateElement ("Path");
nodefilepath.InnerText = FilePath;
var nodefilevalid = xml.CreateElement ("Valid");
nodefilevalid.InnerText = IsValid ? "true" : "false";
var nodefiletype = xml.CreateElement ("Type");
nodefiletype.InnerText = typestr;
var nodefilerole = xml.CreateElement ("Role");
nodefilerole.InnerText = rolestr;
nodefile.AppendChild (nodefilepath);
nodefile.AppendChild (nodefilevalid);
nodefile.AppendChild (nodefiletype);
nodefile.AppendChild (nodefilerole);
root.AppendChild (nodefile);
}
#endregion
#region id
var id = Identity;
{
var nodeid = xml.CreateElement ("Identity");
var nodeidname = xml.CreateElement ("Name");
nodeidname.InnerText = id.Name;
var nodeidpub = xml.CreateElement ("Publisher");
nodeidpub.InnerText = id.Publisher;
var nodeidver = xml.CreateElement ("Version");
nodeidver.InnerText = id.Version.ToString ();
var nodeidrealver = xml.CreateElement ("RealVersion");
nodeidrealver.InnerText = id.RealVersion.ToString ();
var nodeidarchs = xml.CreateElement ("ProcessorArchitectures");
foreach (var a in id.ProcessArchitecture)
{
var astr = "";
switch (a)
{
case Architecture.ARM: astr = "arm"; break;
case Architecture.ARM64: astr = "arm64"; break;
case Architecture.Neutral: astr = "neutral"; break;
case Architecture.x64: astr = "x64"; break;
case Architecture.x86: astr = "x86"; break;
default:
case Architecture.Unknown: astr = "unknown"; break;
}
var nodeidarch = xml.CreateElement ("ProcessorArchitecture");
nodeidarch.SetAttribute ("Value", astr);
nodeidarchs.AppendChild (nodeidarch);
}
var nodeidfamily = xml.CreateElement ("FamilyName");
nodeidfamily.InnerText = id.FamilyName;
var nodeidfull = xml.CreateElement ("FullName");
nodeidfull.InnerText = id.FullName;
var nodeidresid = xml.CreateElement ("ResourceId");
nodeidresid.InnerText = id.ResourceId;
nodeid.AppendChild (nodeidname);
nodeid.AppendChild (nodeidpub);
nodeid.AppendChild (nodeidver);
nodeid.AppendChild (nodeidrealver);
nodeid.AppendChild (nodeidarchs);
nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidresid);
root.AppendChild (nodeid);
}
#endregion
using (var priAllRes = new PriAllValuesReader (this))
{
priAllRes.Init ();
#region prop
var prop = Properties;
var dispname = prop.DisplayName;
var dispNameDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (dispname))
dispNameDict = priAllRes.LocaleResourceAllValues (dispname);
dispNameDict ["root"] = dispname;
var desc = prop.Description;
var descDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (desc))
descDict = priAllRes.LocaleResourceAllValues (desc);
descDict ["root"] = desc;
var disppub = prop.Publisher;
var dispPubDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (disppub))
dispPubDict = priAllRes.LocaleResourceAllValues (disppub);
dispPubDict ["root"] = disppub;
{
var nodeprop = xml.CreateElement ("Properties");
var nodepropname = xml.CreateElement ("DisplayName");
foreach (var kv in dispNameDict)
{
var nodelocale = xml.CreateElement ("LocaleResource");
nodelocale.SetAttribute ("Lang", kv.Key);
nodelocale.InnerText = kv.Value;
nodepropname.AppendChild (nodelocale);
}
var nodeproppub = xml.CreateElement ("PublisherDisplayName");
foreach (var kv in dispPubDict)
{
var nodelocale = xml.CreateElement ("LocaleResource");
nodelocale.SetAttribute ("Lang", kv.Key);
nodelocale.InnerText = kv.Value;
nodeproppub.AppendChild (nodelocale);
}
var nodepropdesc = xml.CreateElement ("Description");
foreach (var kv in descDict)
{
var nodelocale = xml.CreateElement ("LocaleResource");
nodelocale.SetAttribute ("Lang", kv.Key);
nodelocale.InnerText = kv.Value;
nodepropdesc.AppendChild (nodelocale);
}
var nodeproplogo = xml.CreateElement ("Logo");
foreach (var kv in priAllRes.FileResourceAllValues (prop.Logo, zos))
{
#region logo
var key = kv.Key;
var value = kv.Value;
var nodefile = xml.CreateElement ("File");
var attrName = xml.CreateAttribute ("Name");
attrName.Value = value;
nodefile.Attributes.Append (attrName);
if (key.Contrast != PriResourceKey.PriContrast.None)
{
string contrast = "";
switch (key.Contrast)
{
case PriResourceKey.PriContrast.Black: contrast = "black"; break;
case PriResourceKey.PriContrast.White: contrast = "white"; break;
case PriResourceKey.PriContrast.High: contrast = "high"; break;
case PriResourceKey.PriContrast.Low: contrast = "low"; break;
}
var attrContrast = xml.CreateAttribute ("Contrast");
attrContrast.Value = contrast;
nodefile.Attributes.Append (attrContrast);
}
if (key.IsTargetSize)
{
var attr = xml.CreateAttribute ("TargetSize");
attr.Value = key.Value.ToString ();
nodefile.Attributes.Append (attr);
}
else if (key.IsScale)
{
var attr = xml.CreateAttribute ("Scale");
attr.Value = key.Value.ToString ();
nodefile.Attributes.Append (attr);
}
else if (key.IsString)
{
var attr = xml.CreateAttribute ("Language");
attr.Value = key.Value.ToString ();
nodefile.Attributes.Append (attr);
}
nodeproplogo.AppendChild (nodefile);
#endregion
}
var nodepropfrw = xml.CreateElement ("Framework");
nodepropfrw.InnerText = prop.Framework ? "true" : "false";
var nodepropres = xml.CreateElement ("ResourcePackage");
nodepropres.InnerText = prop.ResourcePackage ? "true" : "false";
nodeprop.AppendChild (nodepropname);
nodeprop.AppendChild (nodeproppub);
nodeprop.AppendChild (nodepropdesc);
nodeprop.AppendChild (nodeproplogo);
nodeprop.AppendChild (nodepropfrw);
nodeprop.AppendChild (nodepropres);
root.AppendChild (nodeprop);
}
#endregion
#region apps
// Applications 节点
XmlElement nodeApplications = xml.CreateElement ("Applications");
foreach (var app in Applications)
{
XmlElement nodeApp = xml.CreateElement ("Application");
// AppUserModelId 作为属性
string aumidObj = app ["AppUserModelId"];
if (aumidObj == null || aumidObj.Trim ().Length == 0) aumidObj = app ["AppUserModelID"];
nodeApp.SetAttribute ("AppUserModelId", aumidObj);
foreach (var kv in app)
{
string key = kv.Key;
string value = kv.Value;
// 跳过 AppUserModelId因为已经作为属性
if (string.Equals (key, "AppUserModelId", StringComparison.OrdinalIgnoreCase))
continue;
XmlElement nodeProp = xml.CreateElement (key);
// 文件资源类型
if (Utils.AppFileProperties.Contains (key, StringComparer.OrdinalIgnoreCase))
{
foreach (var skv in priAllRes.FileResourceAllValues (value, zos))
{
var fileKey = skv.Key;
var fileValue = skv.Value;
XmlElement nodeFile = xml.CreateElement ("File");
// Name 必有
XmlAttribute attrName = xml.CreateAttribute ("Name");
attrName.Value = fileValue;
nodeFile.Attributes.Append (attrName);
// Contrast 可选
if (fileKey.Contrast != PriResourceKey.PriContrast.None)
{
string contrast = "";
switch (fileKey.Contrast)
{
case PriResourceKey.PriContrast.Black: contrast = "black"; break;
case PriResourceKey.PriContrast.White: contrast = "white"; break;
case PriResourceKey.PriContrast.High: contrast = "high"; break;
case PriResourceKey.PriContrast.Low: contrast = "low"; break;
}
if (!string.IsNullOrEmpty (contrast))
{
XmlAttribute attrContrast = xml.CreateAttribute ("Contrast");
attrContrast.Value = contrast;
nodeFile.Attributes.Append (attrContrast);
}
}
// TargetSize
if (fileKey.IsTargetSize)
{
XmlAttribute attrTS = xml.CreateAttribute ("TargetSize");
attrTS.Value = fileKey.Value.ToString ();
nodeFile.Attributes.Append (attrTS);
}
// Scale
else if (fileKey.IsScale)
{
XmlAttribute attrS = xml.CreateAttribute ("Scale");
attrS.Value = fileKey.Value.ToString ();
nodeFile.Attributes.Append (attrS);
}
// Language
else if (fileKey.IsString)
{
XmlAttribute attrL = xml.CreateAttribute ("Lang");
attrL.Value = fileKey.Value.ToString ();
nodeFile.Attributes.Append (attrL);
}
nodeProp.AppendChild (nodeFile);
}
}
// 多语言资源
else if (PriFileHelper.IsMsResourcePrefix (value))
{
Dictionary<string, string> localeDict = priAllRes.LocaleResourceAllValues (value);
localeDict ["root"] = value.ToString ();
foreach (KeyValuePair<string, string> lkv in localeDict)
{
XmlElement nodeLocale = xml.CreateElement ("LocaleResource");
nodeLocale.SetAttribute ("Lang", lkv.Key);
nodeLocale.InnerText = lkv.Value;
nodeProp.AppendChild (nodeLocale);
}
}
else
{
nodeProp.InnerText = value.ToString ();
}
nodeApp.AppendChild (nodeProp);
}
nodeApplications.AppendChild (nodeApp);
}
root.AppendChild (nodeApplications);
#endregion
}
#region prerequistes
var preq = Prerequisites;
{
var nodepreq = xml.CreateElement ("Prerequisites");
var nodeosmin = xml.CreateElement ("OSMinVersion");
nodeosmin.InnerText = preq.OSMinVersion.ToString ();
nodeosmin.SetAttribute ("Description", preq.OSMinVersionDescription);
var nodeosmaxt = xml.CreateElement ("OSMaxVersionTested");
nodeosmaxt.InnerText = preq.OSMaxVersionTested.ToString ();
nodeosmaxt.SetAttribute ("Description", preq.OSMaxVersionDescription);
nodepreq.AppendChild (nodeosmin);
nodepreq.AppendChild (nodeosmaxt);
root.AppendChild (nodepreq);
}
#endregion
#region resources
XmlElement nodeResources = xml.CreateElement ("Resources");
var res = Resources;
if (res.Languages != null)
{
foreach (var lang in res.Languages)
{
XmlElement nodeRes = xml.CreateElement ("Resource");
XmlAttribute attrLang = xml.CreateAttribute ("Language");
attrLang.Value = lang;
nodeRes.Attributes.Append (attrLang);
nodeResources.AppendChild (nodeRes);
}
}
if (res.Scales != null)
{
foreach (var scale in res.Scales)
{
XmlElement nodeRes = xml.CreateElement ("Resource");
XmlAttribute attrScale = xml.CreateAttribute ("Scale");
attrScale.Value = scale.ToString ();
nodeRes.Attributes.Append (attrScale);
nodeResources.AppendChild (nodeRes);
}
}
if (res.DXFeatures != null)
{
foreach (var d in res.DXFeatures)
{
int level = -1;
switch (d)
{
case DXFeatureLevel.Level9: level = 9; break;
case DXFeatureLevel.Level10: level = 10; break;
case DXFeatureLevel.Level11: level = 11; break;
case DXFeatureLevel.Level12: level = 12; break;
case DXFeatureLevel.Unspecified:
default: level = -1; break;
}
XmlElement nodeRes = xml.CreateElement ("Resource");
XmlAttribute attrDX = xml.CreateAttribute ("DXFeatureLevel");
attrDX.Value = level.ToString ();
nodeRes.Attributes.Append (attrDX);
nodeResources.AppendChild (nodeRes);
}
}
root.AppendChild (nodeResources);
#endregion
#region capabilities
XmlElement nodeCapabilities = xml.CreateElement ("Capabilities");
var caps = Capabilities;
if (caps.Capabilities != null)
{
foreach (var cap in caps.Capabilities)
{
XmlElement nodeCap = xml.CreateElement ("Capability");
XmlAttribute attrName = xml.CreateAttribute ("Name");
attrName.Value = cap;
nodeCap.Attributes.Append (attrName);
nodeCapabilities.AppendChild (nodeCap);
}
}
if (caps.DeviceCapabilities != null)
{
foreach (var devCap in caps.DeviceCapabilities)
{
XmlElement nodeDevCap = xml.CreateElement ("DeviceCapability");
XmlAttribute attrName = xml.CreateAttribute ("Name");
attrName.Value = devCap;
nodeDevCap.Attributes.Append (attrName);
nodeCapabilities.AppendChild (nodeDevCap);
}
}
root.AppendChild (nodeCapabilities);
#endregion
#region dependencies
XmlElement nodeDependencies = xml.CreateElement ("Dependencies");
var deps = Dependencies;
if (deps != null)
{
foreach (var dep in deps)
{
XmlElement nodeDep = xml.CreateElement ("Dependency");
XmlAttribute attrName = xml.CreateAttribute ("Name");
attrName.Value = dep.Name ?? "";
nodeDep.Attributes.Append (attrName);
XmlAttribute attrPublisher = xml.CreateAttribute ("Publisher");
attrPublisher.Value = dep.Publisher ?? "";
nodeDep.Attributes.Append (attrPublisher);
XmlAttribute attrMinVersion = xml.CreateAttribute ("MinVersion");
attrMinVersion.Value = dep.Version != null ? dep.Version.ToString () : "";
nodeDep.Attributes.Append (attrMinVersion);
nodeDependencies.AppendChild (nodeDep);
}
}
root.AppendChild (nodeDependencies);
#endregion
var ze = new ZipEntry ("info.xml");
ze.DateTime = DateTime.Now;
zos.PutNextEntry (ze);
byte [] bytes;
using (var ms = new MemoryStream ())
{
var settings = new XmlWriterSettings {
Encoding = Encoding.UTF8,
Indent = true,
OmitXmlDeclaration = false
};
using (var writer = XmlWriter.Create (ms, settings))
{
xml.Save (writer);
}
bytes = ms.ToArray ();
}
zos.Write (bytes, 0, bytes.Length);
zos.CloseEntry ();
return true;
}
finally
{
EnablePri = usePri;
UsePri = parsePri;
}
}
}
#endregion
}
catch (Exception ex)
{
throw ex;
return false;
}
}
public void SaveJsonFile (string savefilepath, object resolve, object reject) public void SaveJsonFile (string savefilepath, object resolve, object reject)
{ {
try try
@@ -2039,7 +2837,7 @@ namespace AppxPackage
} }
catch (Exception ex) catch (Exception ex)
{ {
if (reject != null) JSHelper.CallJS (reject, ex); if (reject != null) JSHelper.CallJS (reject, new DataUtils._I_Exception (ex));
} }
} }
public void SaveJsonFileAsync (string savefilepath, object resolve, object reject) public void SaveJsonFileAsync (string savefilepath, object resolve, object reject)
@@ -2458,7 +3256,7 @@ namespace AppxPackage
#endregion #endregion
#region dependencies #region dependencies
XmlElement nodeDependencies = xml.CreateElement ("Dependencies"); XmlElement nodeDependencies = xml.CreateElement ("Dependencies");
var deps = Dependencies; var deps = Dependencies;
if (deps != null) if (deps != null)
{ {
foreach (var dep in deps) foreach (var dep in deps)
@@ -2510,7 +3308,7 @@ namespace AppxPackage
} }
catch (Exception ex) catch (Exception ex)
{ {
if (reject != null) JSHelper.CallJS (reject, ex); if (reject != null) JSHelper.CallJS (reject, new DataUtils._I_Exception (ex));
} }
} }
public void SaveXmlFileAsync (string savefilepath, object resolve, object reject) public void SaveXmlFileAsync (string savefilepath, object resolve, object reject)

View File

@@ -936,6 +936,7 @@ namespace Bridge
public _I_Notice Notice => new _I_Notice (); public _I_Notice Notice => new _I_Notice ();
public _I_Process Process => proc; public _I_Process Process => proc;
public _I_Web Web => new _I_Web (); public _I_Web Web => new _I_Web ();
public _I_Utilities Utilities => new _I_Utilities ();
public string CmdArgs public string CmdArgs
{ {
get get

816
DataUtils/Calendar.cs Normal file
View File

@@ -0,0 +1,816 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Linq;
using System.Reflection;
namespace DataUtils
{
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_Calendar
{
private DateTime _utcDateTime; // 存储 UTC 时间(所有算术的基础)
private Calendar _calendar; // 当前日历系统
private TimeZoneInfo _timeZone; // 当前时区
private bool _is24HourClock; // true = 24小时制false = 12小时制
private List<string> _languages; // 语言优先级列表
private string _numeralSystem = "Latn"; // 数字系统(简化实现,仅存储)
private const long TicksPerNanosecond = 100; // 1 tick = 100 ns
// 缓存的本地时间(根据时区从 _utcDateTime 转换得到)
private DateTime _localDateTime;
// 更新本地时间(当 UTC 时间或时区改变时调用)
private void UpdateLocalDateTime ()
{
_localDateTime = TimeZoneInfo.ConvertTimeFromUtc (_utcDateTime, _timeZone);
}
// 当本地时间被修改后,同步回 UTC 时间
private void UpdateUtcDateTime ()
{
_utcDateTime = TimeZoneInfo.ConvertTimeToUtc (_localDateTime, _timeZone);
}
// 辅助:日历字段的读取
private int GetCalendarField (Func<Calendar, DateTime, int> fieldGetter)
{
return fieldGetter (_calendar, _localDateTime);
}
// 辅助:日历字段的设置(返回新的本地时间)
private DateTime SetCalendarField (DateTime currentLocal, Func<Calendar, DateTime, int, DateTime> fieldSetter, int value)
{
return fieldSetter (_calendar, currentLocal, value);
}
// 根据日历标识符创建日历实例
private static Calendar CreateCalendar (string calendarId)
{
switch (calendarId)
{
case "GregorianCalendar":
return new GregorianCalendar ();
case "HebrewCalendar":
return new HebrewCalendar ();
case "HijriCalendar":
return new HijriCalendar ();
case "JapaneseCalendar":
return new JapaneseCalendar ();
case "KoreanCalendar":
return new KoreanCalendar ();
case "TaiwanCalendar":
return new TaiwanCalendar ();
case "ThaiBuddhistCalendar":
return new ThaiBuddhistCalendar ();
case "UmAlQuraCalendar":
return new UmAlQuraCalendar ();
// 可根据需要增加更多日历
default:
return new GregorianCalendar ();
}
}
private _I_Language GetFormatCulture ()
{
if (_languages == null || _languages.Count == 0)
return new _I_Language (CultureInfo.CurrentCulture.Name);
try
{
return new _I_Language (_languages [0]);
}
catch
{
return new _I_Language (CultureInfo.CurrentCulture.Name);
}
}
private List<object> JsArrayToList (object jsArray)
{
var result = new List<object> ();
if (jsArray == null)
return result;
// JS Array 有 length 属性和数字索引器
var type = jsArray.GetType ();
int length = (int)type.InvokeMember (
"length",
BindingFlags.GetProperty,
null,
jsArray,
null);
for (int i = 0; i < length; i++)
{
object value = type.InvokeMember (
i.ToString (),
BindingFlags.GetProperty,
null,
jsArray,
null);
result.Add (value);
}
return result;
}
public _I_Calendar ()
: this (new List<string> { CultureInfo.CurrentCulture.Name },
"GregorianCalendar", "24HourClock", TimeZoneInfo.Local.Id)
{
}
public _I_Calendar (object languages)
: this (languages, "GregorianCalendar", "24HourClock", TimeZoneInfo.Local.Id)
{
}
public _I_Calendar (object languages, string calendar, string clock)
: this (languages, calendar, clock, TimeZoneInfo.Local.Id)
{
}
public _I_Calendar (object languages, string calendar, string clock, string timeZoneId)
{
_languages = languages == null ? new List<string> () : new List<string> (JsArrayToList (languages).Select (e => e as string));
if (_languages.Count == 0)
_languages.Add (CultureInfo.CurrentCulture.Name);
_calendar = CreateCalendar (calendar);
_is24HourClock = (clock == "24HourClock");
_timeZone = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId);
_utcDateTime = DateTime.UtcNow;
UpdateLocalDateTime ();
}
public int Day
{
get
{
return _calendar.GetDayOfMonth (_localDateTime);
}
set
{
int currentDay = _calendar.GetDayOfMonth (_localDateTime);
if (value == currentDay) return;
// 通过加减天数来设置日期
DateTime newLocal = _calendar.AddDays (_localDateTime, value - currentDay);
_localDateTime = newLocal;
UpdateUtcDateTime ();
}
}
public int DayOfWeek
{
get
{
// 返回 0-60 表示星期日
return (int)_calendar.GetDayOfWeek (_localDateTime);
}
}
public int Era
{
get
{
return _calendar.GetEra (_localDateTime);
}
set
{
// 更改纪元较复杂,简化:仅当值不同时不做任何操作(可根据需求实现)
// 这里忽略设置,或者可以抛出 NotSupportedException
if (value != Era)
throw new NotSupportedException ("Setting Era directly is not supported in this implementation.");
}
}
public int FirstDayInThisMonth
{
get { return 1; }
}
public int FirstEra
{
get { return _calendar.GetEra (_calendar.MinSupportedDateTime); }
}
public int FirstHourInThisPeriod
{
get
{
if (_is24HourClock)
return 0;
else
return (Period == 0) ? 1 : 13;
}
}
public int FirstMinuteInThisHour
{
get { return 0; }
}
public int FirstMonthInThisYear
{
get { return 1; }
}
public int FirstPeriodInThisDay
{
get { return 0; } // 0 = AM
}
public int FirstSecondInThisMinute
{
get { return 0; }
}
public int FirstYearInThisEra
{
get
{
DateTime eraStart = _calendar.MinSupportedDateTime;
int targetEra = Era;
while (_calendar.GetEra (eraStart) != targetEra && eraStart < DateTime.MaxValue)
{
eraStart = _calendar.AddYears (eraStart, 1);
}
return _calendar.GetYear (eraStart);
}
}
public int Hour
{
get
{
int hour24 = _calendar.GetHour (_localDateTime);
if (_is24HourClock)
return hour24;
int hour12 = hour24 % 12;
return (hour12 == 0) ? 12 : hour12;
}
set
{
if (_is24HourClock)
{
if (value < 0 || value > 23)
throw new ArgumentOutOfRangeException (nameof (value), "Hour must be between 0 and 23 for 24-hour clock.");
DateTime newLocal = _localDateTime.Date.AddHours (value).AddMinutes (Minute).AddSeconds (Second);
_localDateTime = newLocal;
}
else
{
if (value < 1 || value > 12)
throw new ArgumentOutOfRangeException (nameof (value), "Hour must be between 1 and 12 for 12-hour clock.");
int hour24 = value % 12;
if (Period == 1) hour24 += 12;
DateTime newLocal = _localDateTime.Date.AddHours (hour24).AddMinutes (Minute).AddSeconds (Second);
_localDateTime = newLocal;
}
UpdateUtcDateTime ();
}
}
public bool IsDaylightSavingTime
{
get { return _timeZone.IsDaylightSavingTime (_localDateTime); }
}
public _I_List Languages
{
get { return new _I_List (_languages.AsReadOnly ().Select (e => (object)e), true) ; }
}
public int LastDayInThisMonth
{
get { return _calendar.GetDaysInMonth (_calendar.GetYear (_localDateTime), _calendar.GetMonth (_localDateTime)); }
}
public int LastEra
{
get { return _calendar.GetEra (_calendar.MaxSupportedDateTime); }
}
public int LastHourInThisPeriod
{
get
{
if (_is24HourClock)
return 23;
else
return (Period == 0) ? 11 : 23;
}
}
public int LastMinuteInThisHour
{
get { return 59; }
}
public int LastMonthInThisYear
{
get { return _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime)); }
}
public int LastPeriodInThisDay
{
get { return 1; } // 1 = PM
}
public int LastSecondInThisMinute
{
get { return 59; }
}
public int LastYearInThisEra
{
get
{
DateTime eraEnd = _calendar.MaxSupportedDateTime;
int targetEra = Era;
while (_calendar.GetEra (eraEnd) != targetEra && eraEnd > DateTime.MinValue)
{
eraEnd = _calendar.AddYears (eraEnd, -1);
}
return _calendar.GetYear (eraEnd);
}
}
public int Minute
{
get { return _calendar.GetMinute (_localDateTime); }
set
{
if (value < 0 || value > 59)
throw new ArgumentOutOfRangeException (nameof (value), "Minute must be between 0 and 59.");
DateTime newLocal = _localDateTime.AddMinutes (value - _calendar.GetMinute (_localDateTime));
_localDateTime = newLocal;
UpdateUtcDateTime ();
}
}
public int Month
{
get { return _calendar.GetMonth (_localDateTime); }
set
{
if (value < 1 || value > _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime)))
throw new ArgumentOutOfRangeException (nameof (value), "Month is out of range for current year.");
DateTime newLocal = SetCalendarField (_localDateTime, (cal, dt, val) => cal.AddMonths (dt, val - cal.GetMonth (dt)), value);
_localDateTime = newLocal;
UpdateUtcDateTime ();
}
}
public int Nanosecond
{
get
{
long ticksInSecond = _localDateTime.Ticks % TimeSpan.TicksPerSecond;
return (int)(ticksInSecond * 100); // 1 tick = 100 ns
}
set
{
if (value < 0 || value > 999999999)
throw new ArgumentOutOfRangeException (nameof (value), "Nanosecond must be between 0 and 999,999,999.");
long ticks = (_localDateTime.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond + (value / 100);
_localDateTime = new DateTime (ticks, _localDateTime.Kind);
UpdateUtcDateTime ();
}
}
public int NumberOfDaysInThisMonth
{
get { return LastDayInThisMonth; }
}
public int NumberOfEras
{
get { return _calendar.Eras.Length; }
}
public int NumberOfHoursInThisPeriod
{
get { return _is24HourClock ? 24 : 12; }
}
public int NumberOfMinutesInThisHour
{
get { return 60; }
}
public int NumberOfMonthsInThisYear
{
get { return _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime)); }
}
public int NumberOfPeriodsInThisDay
{
get { return 2; }
}
public int NumberOfSecondsInThisMinute
{
get { return 60; }
}
public int NumberOfYearsInThisEra
{
get { return LastYearInThisEra - FirstYearInThisEra + 1; }
}
public string NumeralSystem
{
get { return _numeralSystem; }
set { _numeralSystem = value; } // 简化:未实现实际数字转换
}
public int Period
{
get
{
int hour24 = _calendar.GetHour (_localDateTime);
return (hour24 >= 12) ? 1 : 0;
}
set
{
if (value != 0 && value != 1)
throw new ArgumentOutOfRangeException (nameof (value), "Period must be 0 (AM) or 1 (PM).");
int currentPeriod = Period;
if (currentPeriod == value) return;
// 切换 AM/PM加减 12 小时
DateTime newLocal = _localDateTime.AddHours (value == 0 ? -12 : 12);
_localDateTime = newLocal;
UpdateUtcDateTime ();
}
}
public string ResolvedLanguage
{
get
{
if (_languages != null && _languages.Count > 0)
return _languages [0];
return CultureInfo.CurrentCulture.Name;
}
}
public int Second
{
get { return _calendar.GetSecond (_localDateTime); }
set
{
if (value < 0 || value > 59)
throw new ArgumentOutOfRangeException (nameof (value), "Second must be between 0 and 59.");
DateTime newLocal = _localDateTime.AddSeconds (value - _calendar.GetSecond (_localDateTime));
_localDateTime = newLocal;
UpdateUtcDateTime ();
}
}
public int Year
{
get { return _calendar.GetYear (_localDateTime); }
set
{
if (value < _calendar.GetYear (_calendar.MinSupportedDateTime) || value > _calendar.GetYear (_calendar.MaxSupportedDateTime))
throw new ArgumentOutOfRangeException (nameof (value), "Year is out of range for this calendar.");
DateTime newLocal = SetCalendarField (_localDateTime, (cal, dt, val) => cal.AddYears (dt, val - cal.GetYear (dt)), value);
_localDateTime = newLocal;
UpdateUtcDateTime ();
}
}
public void AddDays (int days)
{
_localDateTime = _calendar.AddDays (_localDateTime, days);
UpdateUtcDateTime ();
}
public void AddEras (int eras)
{
// 简化:每个纪元按 1000 年估算(实际应基于日历的纪元范围)
// 大多数情况下不应频繁使用此方法
_localDateTime = _calendar.AddYears (_localDateTime, eras * 1000);
UpdateUtcDateTime ();
}
public void AddHours (int hours)
{
_localDateTime = _localDateTime.AddHours (hours);
UpdateUtcDateTime ();
}
public void AddMinutes (int minutes)
{
_localDateTime = _localDateTime.AddMinutes (minutes);
UpdateUtcDateTime ();
}
public void AddMonths (int months)
{
_localDateTime = _calendar.AddMonths (_localDateTime, months);
UpdateUtcDateTime ();
}
public void AddNanoseconds (int nanoseconds)
{
long ticksToAdd = nanoseconds / 100;
_localDateTime = _localDateTime.AddTicks (ticksToAdd);
UpdateUtcDateTime ();
}
public void AddPeriods (int periods)
{
_localDateTime = _localDateTime.AddHours (periods * 12);
UpdateUtcDateTime ();
}
public void AddSeconds (int seconds)
{
_localDateTime = _localDateTime.AddSeconds (seconds);
UpdateUtcDateTime ();
}
public void AddWeeks (int weeks)
{
AddDays (weeks * 7);
}
public void AddYears (int years)
{
_localDateTime = _calendar.AddYears (_localDateTime, years);
UpdateUtcDateTime ();
}
public void ChangeCalendarSystem (string calendarId)
{
Calendar newCalendar = CreateCalendar (calendarId);
// 注意:日历改变不会改变绝对时间,但会影响组件(年、月、日等)
// 只需替换日历实例_localDateTime 保持不变(但解释方式变了)
_calendar = newCalendar;
}
public void ChangeClock (string clock)
{
_is24HourClock = (clock == "24HourClock");
}
public void ChangeTimeZone (string timeZoneId)
{
_timeZone = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId);
UpdateLocalDateTime (); // 重新计算本地时间UTC 不变)
}
public _I_Calendar Clone ()
{
var clone = new _I_Calendar (_languages, GetCalendarSystem (), GetClock (), GetTimeZone ());
clone.SetDateTime (GetDateTime ());
return clone;
}
public int Compare (_I_Calendar other)
{
if (other == null) return 1;
return DateTime.Compare (this.GetDateTime (), other.GetDateTime ());
}
public static DateTime JsDateToDateTime (object jsDate)
{
if (jsDate == null)
throw new ArgumentNullException (nameof (jsDate));
Type type = jsDate.GetType ();
double milliseconds = (double)type.InvokeMember (
"getTime",
BindingFlags.InvokeMethod,
null,
jsDate,
null);
DateTimeOffset epoch = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
DateTimeOffset dateTimeOffset = epoch.AddMilliseconds (milliseconds);
return dateTimeOffset.UtcDateTime;
}
public int CompareDateTime (object other)
{
return DateTime.Compare (this.GetDateTime (), JsDateToDateTime (other));
}
public void CopyTo (_I_Calendar other)
{
if (other == null) throw new ArgumentNullException (nameof (other));
other._utcDateTime = this._utcDateTime;
other._localDateTime = this._localDateTime;
other._calendar = this._calendar;
other._timeZone = this._timeZone;
other._is24HourClock = this._is24HourClock;
other._languages = new List<string> (this._languages);
other._numeralSystem = this._numeralSystem;
}
public string DayAsPaddedString (int minDigits)
{
return Day.ToString ().PadLeft (minDigits, '0');
}
public string DayAsString ()
{
return Day.ToString ();
}
public string DayOfWeekAsSoloString ()
{
return DayOfWeekAsString ();
}
public string DayOfWeekAsSoloString (int idealLength)
{
// 简化:忽略 idealLength
return DayOfWeekAsString ();
}
public string DayOfWeekAsString ()
{
return _localDateTime.ToString ("dddd", GetFormatCulture ());
}
public string DayOfWeekAsString (int idealLength)
{
return DayOfWeekAsString ();
}
public string EraAsString ()
{
// 简化:返回纪元索引的字符串
return Era.ToString ();
}
public string EraAsString (int idealLength)
{
return EraAsString ();
}
public string GetCalendarSystem ()
{
if (_calendar is GregorianCalendar) return "GregorianCalendar";
if (_calendar is HebrewCalendar) return "HebrewCalendar";
if (_calendar is HijriCalendar) return "HijriCalendar";
if (_calendar is JapaneseCalendar) return "JapaneseCalendar";
if (_calendar is KoreanCalendar) return "KoreanCalendar";
if (_calendar is TaiwanCalendar) return "TaiwanCalendar";
if (_calendar is ThaiBuddhistCalendar) return "ThaiBuddhistCalendar";
if (_calendar is UmAlQuraCalendar) return "UmAlQuraCalendar";
return "GregorianCalendar";
}
public string GetClock ()
{
return _is24HourClock ? "24HourClock" : "12HourClock";
}
public DateTime GetDateTime ()
{
// 返回 UTC 时间
return _utcDateTime;
}
public string GetTimeZone ()
{
return _timeZone.Id;
}
public string HourAsPaddedString (int minDigits)
{
return Hour.ToString ().PadLeft (minDigits, '0');
}
public string HourAsString ()
{
return Hour.ToString ();
}
public string MinuteAsPaddedString (int minDigits)
{
return Minute.ToString ().PadLeft (minDigits, '0');
}
public string MinuteAsString ()
{
return Minute.ToString ();
}
public string MonthAsNumericString ()
{
return Month.ToString ();
}
public string MonthAsPaddedNumericString (int minDigits)
{
return Month.ToString ().PadLeft (minDigits, '0');
}
public string MonthAsSoloString ()
{
return _localDateTime.ToString ("MMMM", GetFormatCulture ());
}
public string MonthAsSoloString (int idealLength)
{
return MonthAsSoloString ();
}
public string MonthAsString ()
{
return _localDateTime.ToString ("MMM", GetFormatCulture ());
}
public string MonthAsString (int idealLength)
{
return MonthAsString ();
}
public string NanosecondAsPaddedString (int minDigits)
{
return Nanosecond.ToString ().PadLeft (minDigits, '0');
}
public string NanosecondAsString ()
{
return Nanosecond.ToString ();
}
public string PeriodAsString ()
{
return PeriodAsString (0);
}
public string PeriodAsString (int idealLength)
{
return _localDateTime.ToString ("tt", GetFormatCulture ());
}
public string SecondAsPaddedString (int minDigits)
{
return Second.ToString ().PadLeft (minDigits, '0');
}
public string SecondAsString ()
{
return Second.ToString ();
}
public void SetDateTime (DateTime value)
{
_utcDateTime = value.ToUniversalTime ();
UpdateLocalDateTime ();
}
public void SetToMax ()
{
SetDateTime (DateTime.MaxValue);
}
public void SetToMin ()
{
SetDateTime (DateTime.MinValue);
}
public void SetToNow ()
{
SetDateTime (DateTime.UtcNow);
}
public string TimeZoneAsString ()
{
return TimeZoneAsString (0);
}
public string TimeZoneAsString (int idealLength)
{
// 简化:返回标准显示名称
return _timeZone.DisplayName;
}
public string YearAsPaddedString (int minDigits)
{
return Year.ToString ().PadLeft (minDigits, '0');
}
public string YearAsString ()
{
return Year.ToString ();
}
public string YearAsTruncatedString (int remainingDigits)
{
string yearStr = Year.ToString ();
if (yearStr.Length <= remainingDigits)
return yearStr;
return yearStr.Substring (yearStr.Length - remainingDigits);
}
}
}

View File

@@ -45,6 +45,8 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Calendar.cs" />
<Compile Include="DateTimeFormat.cs" />
<Compile Include="Download.cs" /> <Compile Include="Download.cs" />
<Compile Include="Enumerable.cs" /> <Compile Include="Enumerable.cs" />
<Compile Include="HResult.cs" /> <Compile Include="HResult.cs" />

494
DataUtils/DateTimeFormat.cs Normal file
View File

@@ -0,0 +1,494 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace DataUtils
{
public enum YearFormat
{
None = 0,
Default = 1,
Abbreviated = 2,
Full = 3,
}
public enum MonthFormat
{
None = 0,
Default = 1,
Abbreviated = 2,
Full = 3,
Numeric = 4,
}
public enum DayFormat
{
None = 0,
Default = 1,
}
public enum DayOfWeekFormat
{
None = 0,
Default = 1,
Abbreviated = 2,
Full = 3,
}
public enum HourFormat
{
None = 0,
Default = 1,
}
public enum MinuteFormat
{
None = 0,
Default = 1,
}
public enum SecondFormat
{
None = 0,
Default = 1,
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_DateTimeFormatter
{
// ---------- 私有字段 ----------
private string _formatTemplate; // 原始模板字符串
private string _formatPattern; // 实际用于 .NET 格式化的模式
private List<string> _languages; // 语言优先级列表
private string _geographicRegion; // 地理区域
private string _calendar = "GregorianCalendar";
private string _clock = "24HourClock";
private string _numeralSystem = "Latn";
private CultureInfo _culture; // 解析后的 CultureInfo
private string _resolvedLanguage; // 实际使用的语言
private string _resolvedGeographicRegion; // 实际使用的区域
// 存储构造时传入的枚举值(用于 IncludeXXX 属性)
private YearFormat _yearFormat = YearFormat.None;
private MonthFormat _monthFormat = MonthFormat.None;
private DayFormat _dayFormat = DayFormat.None;
private DayOfWeekFormat _dayOfWeekFormat = DayOfWeekFormat.None;
private HourFormat _hourFormat = HourFormat.None;
private MinuteFormat _minuteFormat = MinuteFormat.None;
private SecondFormat _secondFormat = SecondFormat.None;
// ---------- 辅助方法 ----------
private static string MapTemplateToPattern (string template, CultureInfo culture, string clock)
{
if (string.IsNullOrEmpty (template))
return string.Empty;
switch (template.ToLowerInvariant ())
{
case "longdate":
return culture.DateTimeFormat.LongDatePattern;
case "shortdate":
return culture.DateTimeFormat.ShortDatePattern;
case "longtime":
return culture.DateTimeFormat.LongTimePattern;
case "shorttime":
return culture.DateTimeFormat.ShortTimePattern;
case "dayofweek":
return culture.DateTimeFormat.ShortestDayNames? [0] ?? "dddd"; // 近似
case "dayofweek.full":
return "dddd";
case "dayofweek.abbreviated":
return "ddd";
case "day":
return "dd";
case "month":
return "MMMM";
case "month.full":
return "MMMM";
case "month.abbreviated":
return "MMM";
case "month.numeric":
return "MM";
case "year":
return "yyyy";
case "year.full":
return "yyyy";
case "year.abbreviated":
return "yy";
case "hour":
return clock == "24HourClock" ? "HH" : "hh";
case "minute":
return "mm";
case "second":
return "ss";
case "timezone":
return "zzz";
default:
// 如果不是预定义模板,则当作自定义模式直接返回
return template;
}
}
// 根据枚举组合构建格式模式
private static string BuildPatternFromEnums (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek,
HourFormat hour, MinuteFormat minute, SecondFormat second,
string clock, CultureInfo culture)
{
var parts = new List<string> ();
// 日期部分
if (dayOfWeek != DayOfWeekFormat.None)
{
if (dayOfWeek == DayOfWeekFormat.Abbreviated)
parts.Add ("ddd");
else // Full or Default
parts.Add ("dddd");
}
if (year != YearFormat.None)
{
if (year == YearFormat.Abbreviated)
parts.Add ("yy");
else
parts.Add ("yyyy");
}
if (month != MonthFormat.None)
{
switch (month)
{
case MonthFormat.Numeric:
parts.Add ("MM");
break;
case MonthFormat.Abbreviated:
parts.Add ("MMM");
break;
case MonthFormat.Full:
parts.Add ("MMMM");
break;
default:
parts.Add ("MM");
break;
}
}
if (day != DayFormat.None)
{
parts.Add ("dd");
}
string datePart = string.Join (" ", parts);
// 时间部分
var timeParts = new List<string> ();
if (hour != HourFormat.None)
{
if (clock == "24HourClock")
timeParts.Add ("HH");
else
timeParts.Add ("hh");
}
if (minute != MinuteFormat.None)
{
timeParts.Add ("mm");
}
if (second != SecondFormat.None)
{
timeParts.Add ("ss");
}
string timePart = timeParts.Count > 0 ? string.Join (":", timeParts) : "";
if (!string.IsNullOrEmpty (datePart) && !string.IsNullOrEmpty (timePart))
return datePart + " " + timePart;
if (!string.IsNullOrEmpty (datePart))
return datePart;
return timePart;
}
// 将 JS Date 对象转换为 DateTime
private DateTime ConvertJsDateToDateTime (object jsDate)
{
if (jsDate == null)
throw new ArgumentNullException (nameof (jsDate));
Type type = jsDate.GetType ();
// 调用 getTime() 获取毫秒数 (double)
double milliseconds = (double)type.InvokeMember (
"getTime",
BindingFlags.InvokeMethod,
null,
jsDate,
null);
// 手动计算 Unix 纪元转换(兼容低版本 .NET
DateTime epoch = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime utcDateTime = epoch.AddMilliseconds (milliseconds);
// 返回本地时间(可根据需求调整)
return utcDateTime.ToLocalTime ();
}
// 初始化文化信息
private void InitializeCulture ()
{
string lang = (_languages != null && _languages.Count > 0) ? _languages [0] : CultureInfo.CurrentCulture.Name;
try
{
_culture = new CultureInfo (lang);
_resolvedLanguage = _culture.Name;
}
catch
{
_culture = CultureInfo.CurrentCulture;
_resolvedLanguage = _culture.Name;
}
_resolvedGeographicRegion = _geographicRegion ?? _culture.Name;
// 根据区域和语言更新格式模式(如果使用模板)
if (!string.IsNullOrEmpty (_formatTemplate))
{
_formatPattern = MapTemplateToPattern (_formatTemplate, _culture, _clock);
}
else if (_yearFormat != YearFormat.None || _monthFormat != MonthFormat.None ||
_dayFormat != DayFormat.None || _dayOfWeekFormat != DayOfWeekFormat.None ||
_hourFormat != HourFormat.None || _minuteFormat != MinuteFormat.None ||
_secondFormat != SecondFormat.None)
{
_formatPattern = BuildPatternFromEnums (_yearFormat, _monthFormat, _dayFormat, _dayOfWeekFormat,
_hourFormat, _minuteFormat, _secondFormat, _clock, _culture);
}
}
// ---------- 构造函数 ----------
public _I_DateTimeFormatter (string formatTemplate)
: this (formatTemplate, null, null, null, null)
{
}
public _I_DateTimeFormatter (string formatTemplate, IEnumerable<string> languages)
: this (formatTemplate, languages, null, null, null)
{
}
public _I_DateTimeFormatter (string formatTemplate, IEnumerable<string> languages, string geographicRegion, string calendar, string clock)
{
_formatTemplate = formatTemplate;
_languages = languages == null ? new List<string> () : new List<string> (languages);
_geographicRegion = geographicRegion;
if (!string.IsNullOrEmpty (calendar))
_calendar = calendar;
if (!string.IsNullOrEmpty (clock))
_clock = clock;
InitializeCulture ();
}
public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek)
: this (year, month, day, dayOfWeek, HourFormat.None, MinuteFormat.None, SecondFormat.None, null, null, null, null)
{
}
public _I_DateTimeFormatter (HourFormat hour, MinuteFormat minute, SecondFormat second)
: this (YearFormat.None, MonthFormat.None, DayFormat.None, DayOfWeekFormat.None, hour, minute, second, null, null, null, null)
{
}
public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek,
HourFormat hour, MinuteFormat minute, SecondFormat second,
IEnumerable<string> languages)
: this (year, month, day, dayOfWeek, hour, minute, second, languages, null, null, null)
{
}
public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek,
HourFormat hour, MinuteFormat minute, SecondFormat second,
IEnumerable<string> languages, string geographicRegion, string calendar, string clock)
{
_yearFormat = year;
_monthFormat = month;
_dayFormat = day;
_dayOfWeekFormat = dayOfWeek;
_hourFormat = hour;
_minuteFormat = minute;
_secondFormat = second;
_languages = languages == null ? new List<string> () : new List<string> (languages);
_geographicRegion = geographicRegion;
if (!string.IsNullOrEmpty (calendar))
_calendar = calendar;
if (!string.IsNullOrEmpty (clock))
_clock = clock;
InitializeCulture ();
}
// ---------- 属性 ----------
public string Calendar
{
get { return _calendar; }
set
{
_calendar = value;
// 日历更改可能需要重新初始化模式,这里简化处理
}
}
public string Clock
{
get { return _clock; }
set
{
_clock = value;
InitializeCulture (); // 重新生成模式(因为小时格式可能变化)
}
}
public string GeographicRegion
{
get { return _geographicRegion; }
set
{
_geographicRegion = value;
InitializeCulture ();
}
}
public int IncludeDay
{
get { return (int)_dayFormat; }
}
public int IncludeDayOfWeek
{
get { return (int)_dayOfWeekFormat; }
}
public int IncludeHour
{
get { return (int)_hourFormat; }
}
public int IncludeMinute
{
get { return (int)_minuteFormat; }
}
public int IncludeMonth
{
get { return (int)_monthFormat; }
}
public int IncludeSecond
{
get { return (int)_secondFormat; }
}
public int IncludeYear
{
get { return (int)_yearFormat; }
}
public _I_List Languages
{
get { return new _I_List (_languages.AsReadOnly ().Select (e => (object)e), true); }
}
public static _I_DateTimeFormatter LongDate
{
get
{
return new _I_DateTimeFormatter ("longdate");
}
}
public static _I_DateTimeFormatter LongTime
{
get
{
return new _I_DateTimeFormatter ("longtime");
}
}
public string NumeralSystem
{
get { return _numeralSystem; }
set { _numeralSystem = value; }
}
public _I_List Patterns
{
get
{
return new _I_List (new List<string> { _formatPattern }.AsReadOnly ().Select (e => (object)e), true);
}
}
public string ResolvedGeographicRegion
{
get { return _resolvedGeographicRegion; }
}
public string ResolvedLanguage
{
get { return _resolvedLanguage; }
}
public static _I_DateTimeFormatter ShortDate
{
get
{
return new _I_DateTimeFormatter ("shortdate");
}
}
public static _I_DateTimeFormatter ShortTime
{
get
{
return new _I_DateTimeFormatter ("shorttime");
}
}
public string Template
{
get
{
if (!string.IsNullOrEmpty (_formatTemplate))
return _formatTemplate;
// 从枚举组合生成模板描述(简化)
return _formatPattern;
}
}
// ---------- 方法 ----------
public string FormatC (DateTime dateTime)
{
return dateTime.ToString (_formatPattern, _culture);
}
public string FormatC (DateTime dateTime, string timeZoneId)
{
if (!string.IsNullOrEmpty (timeZoneId))
{
try
{
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId);
DateTime targetTime = TimeZoneInfo.ConvertTime (dateTime, tzi);
return targetTime.ToString (_formatPattern, _culture);
}
catch
{
// 时区无效,回退到原始时间
return dateTime.ToString (_formatPattern, _culture);
}
}
return dateTime.ToString (_formatPattern, _culture);
}
// 为方便 JS 调用,提供接受 object 的重载(自动识别 JS Date
public string Format (object jsDate)
{
DateTime dt = ConvertJsDateToDateTime (jsDate);
return FormatC (dt);
}
public string FormatWithTimeZone (object jsDate, string timeZoneId)
{
DateTime dt = ConvertJsDateToDateTime (jsDate);
return FormatC (dt, timeZoneId);
}
}
}

View File

@@ -10,7 +10,7 @@ namespace DataUtils
{ {
[ComVisible (true)] [ComVisible (true)]
[InterfaceType (ComInterfaceType.InterfaceIsDual)] [InterfaceType (ComInterfaceType.InterfaceIsDual)]
public interface _I_Enumerable public interface _I_Enumerable: IDisposable
{ {
int Length { get; set; } int Length { get; set; }
object this [int index] { get; set; } object this [int index] { get; set; }
@@ -33,6 +33,9 @@ namespace DataUtils
int IndexOfKey (int key); // 按内部 key 查找 int IndexOfKey (int key); // 按内部 key 查找
void Move (int index, int newIndex); // 移动元素 void Move (int index, int newIndex); // 移动元素
void PushAll (object [] items); // 一次性 push 多个 void PushAll (object [] items); // 一次性 push 多个
object Get (int index);
object Set (int index, object value);
object At (int index);
} }
public class _I_List: _I_Enumerable, IList public class _I_List: _I_Enumerable, IList
{ {
@@ -43,6 +46,9 @@ namespace DataUtils
IsReadOnly = readOnly; IsReadOnly = readOnly;
IsSynchronized = sync; IsSynchronized = sync;
} }
public _I_List (bool readOnly = false, bool fixedSize = false, bool sync = true) :
this (null, readOnly, fixedSize, sync)
{ }
protected List<object> _list; protected List<object> _list;
protected object _lock = new object (); protected object _lock = new object ();
public object this [int index] { get { return _list [index]; } set { _list [index] = value; } } public object this [int index] { get { return _list [index]; } set { _list [index] = value; } }
@@ -155,5 +161,13 @@ namespace DataUtils
return first; return first;
} }
public void Unshift (object value) => _list.Insert (0, value); public void Unshift (object value) => _list.Insert (0, value);
public void Dispose ()
{
_list?.Clear ();
_list = null;
}
public object Get (int index) => this [index];
public object Set (int index, object value) => this [index] = value;
public object At (int index) => this [index];
} }
} }

View File

@@ -1,29 +1,116 @@
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace DataUtils namespace DataUtils
{ {
internal static class NativeMethods internal static class NativeMethods
{ {
public const int LOCALE_SSHORTESTSCRIPT = 0x0000004F; // 获取四字母脚本代码
public const uint KLF_ACTIVATE = 0x00000001; // 激活键盘布局
// GetLocaleInfoW for LCID-based queries // GetLocaleInfoW for LCID-based queries
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetLocaleInfoW (int Locale, int LCType, [Out] StringBuilder lpLCData, int cchData); public static extern int GetLocaleInfoW (int Locale, int LCType, [Out] StringBuilder lpLCData, int cchData);
// GetLocaleInfoEx for locale name based queries // GetLocaleInfoEx for locale name based queries
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetLocaleInfoEx (string lpLocaleName, int LCType, [Out] StringBuilder lpLCData, int cchData); public static extern int GetLocaleInfoEx (string lpLocaleName, int LCType, [Out] StringBuilder lpLCData, int cchData);
// LocaleNameToLCID - available on Vista+; fallback is to use CultureInfo // LocaleNameToLCID - available on Vista+; fallback is to use CultureInfo
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int LocaleNameToLCID (string lpName, uint dwFlags); public static extern int LocaleNameToLCID (string lpName, uint dwFlags);
// LCIDToLocaleName (Vista+) // LCIDToLocaleName (Vista+)
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int LCIDToLocaleName (int Locale, [Out] StringBuilder lpName, int cchName, uint dwFlags); public static extern int LCIDToLocaleName (int Locale, [Out] StringBuilder lpName, int cchName, uint dwFlags);
[DllImport ("user32.dll")]
public static extern IntPtr GetKeyboardLayout (uint dwLayout);
[DllImport ("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr LoadKeyboardLayout (string pwszKLID, uint Flags);
} }
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_Language: System.Globalization.CultureInfo
{
public _I_Language (string localeName) : base (localeName) { }
public string AbbreviatedName => this.ThreeLetterISOLanguageName;
public string LanguageTag => this.IetfLanguageTag ?? this.Name;
public int LayoutDirection
{
get
{
if (base.TextInfo.IsRightToLeft) return 1;
string tag = this.LanguageTag;
bool isVerticalCandidate = false;
if (tag != null)
{
var scriptMatch = Regex.Match (tag, @"-([A-Za-z]{4})(?:-|$)");
if (scriptMatch.Success)
{
string script = scriptMatch.Groups [1].Value;
if (script == "Hani" || script == "Hira" || script == "Kana" || script == "Jpan" || script == "Kore" || script == "Hans" || script == "Hant")
isVerticalCandidate = true;
}
if (!isVerticalCandidate)
{
var regionMatch = Regex.Match (tag, @"-([A-Za-z]{2})$");
if (regionMatch.Success)
{
string region = regionMatch.Groups [1].Value.ToUpperInvariant ();
if (region == "JP" || region == "CN" || region == "TW" || region == "HK" || region == "MO" || region == "KR")
isVerticalCandidate = true;
}
}
}
if (isVerticalCandidate)
{
return 2;
}
return 0;
}
}
public string Script
{
get
{
StringBuilder sb = new StringBuilder (10);
if (NativeMethods.GetLocaleInfoEx (this.Name, NativeMethods.LOCALE_SSHORTESTSCRIPT, sb, sb.Capacity) > 0)
return sb.ToString ();
// 如果失败,尝试从语言标记中解析脚本子标记(如 "zh-Hans-CN" 中的 "Hans"
var match = Regex.Match (this.Name, @"-([A-Za-z]{4})(?:-|$)");
if (match.Success)
return match.Groups [1].Value;
return "Unknown";
}
}
public _I_List GetExtensionSubtags (string singleton)
{
if (string.IsNullOrEmpty (singleton) || singleton.Length != 1)
throw new ArgumentException ("Singleton must be a single character", nameof (singleton));
var subtags = new List<string> ();
string tag = this.LanguageTag;
string pattern = $@"-{Regex.Escape (singleton)}-([a-zA-Z0-9](?:-[a-zA-Z0-9]+)*)";
var match = Regex.Match (tag, pattern);
if (match.Success)
{
string extPart = match.Groups [1].Value;
subtags.AddRange (extPart.Split ('-'));
}
return new _I_List (subtags.Select (i => (object)i));
}
public bool TrySetInputMethodLanguageTag (string languageTag)
{
int lcid = NativeMethods.LocaleNameToLCID (languageTag, 0);
if (lcid == 0)
return false;
string klid = $"{lcid:X8}";
IntPtr hkl = NativeMethods.LoadKeyboardLayout (klid, NativeMethods.KLF_ACTIVATE);
return hkl != IntPtr.Zero;
}
}
[ComVisible (true)] [ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)] [ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_Locale public class _I_Locale
@@ -47,7 +134,6 @@ namespace DataUtils
} }
} }
} }
// Current LCID (int) // Current LCID (int)
public int CurrentLCID public int CurrentLCID
{ {
@@ -63,7 +149,6 @@ namespace DataUtils
} }
} }
} }
// Convert LCID -> locale name (e.g. 1033 -> "en-US") // Convert LCID -> locale name (e.g. 1033 -> "en-US")
public string ToLocaleName (int lcid) public string ToLocaleName (int lcid)
{ {
@@ -87,7 +172,6 @@ namespace DataUtils
} }
return string.Empty; return string.Empty;
} }
// Convert locale name -> LCID // Convert locale name -> LCID
public int ToLCID (string localeName) public int ToLCID (string localeName)
{ {
@@ -111,7 +195,6 @@ namespace DataUtils
// fallback: invariant culture // fallback: invariant culture
return CultureInfo.InvariantCulture.LCID; return CultureInfo.InvariantCulture.LCID;
} }
// Return a locale info string for given LCID and LCTYPE. LCTYPE is the Win32 LOCALE_* constant. // Return a locale info string for given LCID and LCTYPE. LCTYPE is the Win32 LOCALE_* constant.
// Returns a string (or empty string on failure). // Returns a string (or empty string on failure).
public object LocaleInfo (int lcid, int lctype) public object LocaleInfo (int lcid, int lctype)
@@ -177,7 +260,6 @@ namespace DataUtils
return string.Empty; return string.Empty;
} }
} }
// LocaleInfoEx: query by locale name string and LCTYPE // LocaleInfoEx: query by locale name string and LCTYPE
// Returns string if available; otherwise returns the integer result code (as int) if string empty (mimic C++ behavior). // Returns string if available; otherwise returns the integer result code (as int) if string empty (mimic C++ behavior).
public object LocaleInfoEx (string localeName, int lctype) public object LocaleInfoEx (string localeName, int lctype)
@@ -239,7 +321,6 @@ namespace DataUtils
return 0; return 0;
} }
} }
// Helpers similar to the C++: restricted (language) and elaborated (region) codes // Helpers similar to the C++: restricted (language) and elaborated (region) codes
public string GetLocaleRestrictedCode (string localeName) public string GetLocaleRestrictedCode (string localeName)
{ {
@@ -257,7 +338,6 @@ namespace DataUtils
return string.Empty; return string.Empty;
} }
} }
public string GetLocaleElaboratedCode (string localeName) public string GetLocaleElaboratedCode (string localeName)
{ {
if (string.IsNullOrEmpty (localeName)) localeName = CurrentLocale; if (string.IsNullOrEmpty (localeName)) localeName = CurrentLocale;
@@ -284,7 +364,6 @@ namespace DataUtils
} }
return string.Empty; return string.Empty;
} }
// LCID -> combined code like "en-US" (with configurable separator) // LCID -> combined code like "en-US" (with configurable separator)
public string LcidToLocaleCode (int lcid) public string LcidToLocaleCode (int lcid)
{ {
@@ -304,7 +383,6 @@ namespace DataUtils
} }
return string.Empty; return string.Empty;
} }
// Get the user default locale name // Get the user default locale name
public string GetUserDefaultLocaleName () public string GetUserDefaultLocaleName ()
{ {
@@ -317,7 +395,6 @@ namespace DataUtils
catch { } catch { }
return LcidToLocaleCode (CultureInfo.CurrentCulture.LCID); return LcidToLocaleCode (CultureInfo.CurrentCulture.LCID);
} }
// Get system default locale name (machine) // Get system default locale name (machine)
public string GetSystemDefaultLocaleName () public string GetSystemDefaultLocaleName ()
{ {
@@ -330,7 +407,6 @@ namespace DataUtils
catch { } catch { }
return LcidToLocaleCode (CultureInfo.InstalledUICulture.LCID); return LcidToLocaleCode (CultureInfo.InstalledUICulture.LCID);
} }
// Get computer locale code similar to C++ approach // Get computer locale code similar to C++ approach
public string GetComputerLocaleCode () public string GetComputerLocaleCode ()
{ {
@@ -350,7 +426,38 @@ namespace DataUtils
// fallback to invariant // fallback to invariant
return CultureInfo.InvariantCulture.Name ?? string.Empty; return CultureInfo.InvariantCulture.Name ?? string.Empty;
} }
public _I_List RecommendLocaleNames
{
get
{
var arr = new string [] {
System.Threading.Thread.CurrentThread.CurrentCulture.Name,
GetUserDefaultLocaleName (),
GetSystemDefaultLocaleName (),
LcidToLocaleCode (CurrentLCID),
GetLocaleRestrictedCode (System.Threading.Thread.CurrentThread.CurrentCulture.Name),
GetLocaleRestrictedCode (GetUserDefaultLocaleName ()),
GetLocaleRestrictedCode (GetSystemDefaultLocaleName ()),
"en-US",
"en"
};
var list = new _I_List ();
foreach (var loc in arr)
{
var lloc = loc.Trim ().ToLowerInvariant ();
var isfind = false;
foreach (var item in list)
{
var str = item as string;
if (string.IsNullOrWhiteSpace (str)) isfind = true;
isfind = str.Trim ().ToLowerInvariant () == lloc;
if (isfind) break;
}
if (!isfind) list.Add (loc);
}
return list;
}
}
// Compare two locale names; returns true if equal by name or LCID // Compare two locale names; returns true if equal by name or LCID
public bool LocaleNameCompare (string left, string right) public bool LocaleNameCompare (string left, string right)
{ {
@@ -366,8 +473,62 @@ namespace DataUtils
return false; return false;
} }
} }
// Constants // Constants
private const int LOCALE_NAME_MAX_LENGTH = 85; // defined by Windows private const int LOCALE_NAME_MAX_LENGTH = 85; // defined by Windows
public _I_Language CreateLanguage (string localeName) => new _I_Language (localeName);
public static string CurrentInputMethodLanguageTag
{
get
{
IntPtr hkl = NativeMethods.GetKeyboardLayout (0);
int lcid = hkl.ToInt32 () & 0xFFFF;
StringBuilder sb = new StringBuilder (85);
int result = NativeMethods.LCIDToLocaleName (lcid, sb, sb.Capacity, 0);
if (result > 0)
return sb.ToString ();
return null;
}
}
public static bool IsWellFormed (string languageTag)
{
if (string.IsNullOrEmpty (languageTag))
return false;
try
{
var _ = new CultureInfo (languageTag);
return true;
}
catch
{
return false;
}
}
public static _I_List GetMuiCompatibleLanguageListFromLanguageTags (IEnumerable<string> languageTags)
{
var result = new List<string> ();
foreach (string tag in languageTags)
{
if (string.IsNullOrEmpty (tag))
continue;
result.Add (tag);
try
{
var ci = new CultureInfo (tag);
string parent = ci.Parent.Name;
if (!string.IsNullOrEmpty (parent) && parent != tag && !result.Contains (parent))
result.Add (parent);
}
catch { }
string neutral = Regex.Replace (tag, @"-.*$", "");
if (neutral != tag && !result.Contains (neutral))
result.Add (neutral);
}
if (!result.Contains ("neutral"))
result.Add ("neutral");
return new _I_List (result.Select (t => (object)t));
}
} }
} }

View File

@@ -1,9 +1,11 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -382,5 +384,236 @@ namespace DataUtils
} }
[ComVisible (true)] [ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)] [ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_Exception: IExcep public class _I_Exception: Exception, IDisposable
{
private Exception bex = null;
public _I_Exception (Exception ex) { bex = ex; }
public _I_Exception (string message) { bex = new Exception (message); }
public _I_Exception (string msg, Exception innerEx) { bex = new Exception (msg, innerEx); }
public override IDictionary Data => bex.Data;
public override Exception GetBaseException () => bex.GetBaseException ();
public override void GetObjectData (SerializationInfo info, StreamingContext context) => bex.GetObjectData (info, context);
public override string HelpLink
{
get { return bex.HelpLink; }
set { bex.HelpLink = value; }
}
public override string Message => bex.Message;
public override string Source
{
get { return bex.Source; }
set { bex.Source = value; }
}
public override string StackTrace => bex.StackTrace;
public override string ToString () => bex.ToString ();
public override int GetHashCode () => bex.GetHashCode ();
public override bool Equals (object obj) => bex.Equals (obj);
public void Dispose () { bex = null; }
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_KeyValuePair: IDisposable
{
object key = null;
object value = null;
public _I_KeyValuePair (object k, object v)
{
key = k;
value = v;
}
public object Key { get { return key; } set { key = value; } }
public object Value { get { return value; } set { this.value = value; } }
public void Dispose ()
{
key = null;
value = null;
}
~_I_KeyValuePair ()
{
key = null;
value = null;
}
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_WwwFormUrlDecoder
{
private readonly Dictionary<string, string> _params = new Dictionary<string, string> ();
public _I_WwwFormUrlDecoder (string query)
{
if (string.IsNullOrEmpty (query)) return;
if (query.StartsWith ("?")) query = query.Substring (1);
foreach (var pair in query.Split ('&'))
{
var kv = pair.Split ('=');
if (kv.Length == 2)
_params [Uri.UnescapeDataString (kv [0])] = Uri.UnescapeDataString (kv [1]);
}
}
public string GetFirstValueByName (string name)
{
string value = null;
return _params.TryGetValue (name, out value) ? value : null;
}
public int Size => _params.Count;
public _I_KeyValuePair GetAt (uint index)
{
var pair = _params.ElementAt ((int)index);
return new _I_KeyValuePair (pair.Key, pair.Value);
}
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_Uri: Uri
{
public _I_Uri (string uri): base (uri) { }
public _I_Uri (string baseUri, string relativeUri) : base (new Uri (baseUri), relativeUri) { }
public string AbsoluteCanonicalUri => this.GetLeftPart (UriPartial.Authority) + this.PathAndQuery + this.Fragment;
public string DisplayIri => Uri.UnescapeDataString (this.OriginalString);
public string DisplayUri => Uri.UnescapeDataString (this.OriginalString);
public string Domain => ExtractDomain (this.Host);
public string Extension => System.IO.Path.GetExtension (this.AbsolutePath)?.TrimStart ('.') ?? "";
public string Password => ExtractPassword (this.UserInfo);
public string Path => this.AbsolutePath;
public object QueryParsed => new _I_WwwFormUrlDecoder (this.Query);
public string RawUri => this.OriginalString;
public string SchemeName => this.Scheme;
public bool Suspicious => !Uri.IsWellFormedUriString (this.OriginalString, UriKind.Absolute);
public string UserName => ExtractUserName (this.UserInfo);
public _I_Uri CombineUri (string relativeUri)
{
return new _I_Uri (this.AbsoluteUri, relativeUri);
}
public static string EscapeComponent (string component)
{
return Uri.EscapeDataString (component);
}
public static string UnescapeComponent (string component)
{
return Uri.UnescapeDataString (component);
}
private static string ExtractDomain (string host)
{
var parts = host.Split ('.');
if (parts.Length >= 2)
return string.Join (".", parts.Skip (1));
return host;
}
private static string ExtractUserName (string userInfo)
{
if (string.IsNullOrEmpty (userInfo)) return "";
var parts = userInfo.Split (':');
return parts [0];
}
private static string ExtractPassword (string userInfo)
{
if (string.IsNullOrEmpty (userInfo)) return "";
var parts = userInfo.Split (':');
return parts.Length > 1 ? parts [1] : "";
}
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class _I_Utilities
{
public _I_Uri CreateUri (string uri) => new _I_Uri (uri);
public _I_Uri CreateUri2 (string baseUri, string relaUri) => new _I_Uri (baseUri, relaUri);
public _I_Exception CreateException (string message) => new _I_Exception (message);
public _I_Exception CreateException2 (string message, _I_Exception innerEx) => new _I_Exception (message, innerEx);
public _I_Calendar CreateCalendar () => new _I_Calendar ();
public _I_Calendar CreateCalendar2 (object list) => new _I_Calendar (list);
public _I_Calendar CreateCalendar3 (object list, string arg1, string arg2) => new _I_Calendar (list, arg1, arg2);
public _I_Calendar CreateCalendar4 (object list, string arg1, string arg2, string arg3) => new _I_Calendar (list, arg1, arg2, arg3);
public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplate (string formatTemplate)
{
return new _I_DateTimeFormatter (formatTemplate);
}
public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplateAndLanguages (string formatTemplate, object languagesArray)
{
List<string> languages = JsArrayToStringList (languagesArray);
return new _I_DateTimeFormatter (formatTemplate, languages);
}
public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplateFull (string formatTemplate, object languagesArray,
string geographicRegion, string calendar, string clock)
{
List<string> languages = JsArrayToStringList (languagesArray);
return new _I_DateTimeFormatter (formatTemplate, languages, geographicRegion, calendar, clock);
}
public _I_DateTimeFormatter CreateDateTimeFormatterFromDateEnums (int year, int month, int day, int dayOfWeek)
{
return new _I_DateTimeFormatter (
(YearFormat)year,
(MonthFormat)month,
(DayFormat)day,
(DayOfWeekFormat)dayOfWeek
);
}
public _I_DateTimeFormatter CreateDateTimeFormatterFromTimeEnums (int hour, int minute, int second)
{
return new _I_DateTimeFormatter (
(HourFormat)hour,
(MinuteFormat)minute,
(SecondFormat)second
);
}
public _I_DateTimeFormatter CreateDateTimeFormatterFromDateTimeEnums (int year, int month, int day, int dayOfWeek,
int hour, int minute, int second, object languagesArray)
{
List<string> languages = JsArrayToStringList (languagesArray);
return new _I_DateTimeFormatter (
(YearFormat)year,
(MonthFormat)month,
(DayFormat)day,
(DayOfWeekFormat)dayOfWeek,
(HourFormat)hour,
(MinuteFormat)minute,
(SecondFormat)second,
languages
);
}
public _I_DateTimeFormatter CreateDateTimeFormatterFromDateTimeEnumsFull (int year, int month, int day, int dayOfWeek,
int hour, int minute, int second, object languagesArray,
string geographicRegion, string calendar, string clock)
{
List<string> languages = JsArrayToStringList (languagesArray);
return new _I_DateTimeFormatter (
(YearFormat)year,
(MonthFormat)month,
(DayFormat)day,
(DayOfWeekFormat)dayOfWeek,
(HourFormat)hour,
(MinuteFormat)minute,
(SecondFormat)second,
languages,
geographicRegion,
calendar,
clock
);
}
private List<string> JsArrayToStringList (object jsArray)
{
var result = new List<string> ();
if (jsArray == null) return result;
Type type = jsArray.GetType ();
try
{
int length = (int)type.InvokeMember ("length", BindingFlags.GetProperty, null, jsArray, null);
for (int i = 0; i < length; i++)
{
object value = type.InvokeMember (i.ToString (), BindingFlags.GetProperty, null, jsArray, null);
if (value != null)
result.Add (value.ToString ());
}
}
catch
{
// 如果无法获取 length则假设是单个字符串
string single = jsArray.ToString ();
if (!string.IsNullOrEmpty (single))
result.Add (single);
}
return result;
}
}
} }

View File

@@ -297,11 +297,18 @@ namespace DataUtils
return new HttpResponse (res); return new HttpResponse (res);
} }
} }
public void SendAsync (string sBody, string encoding, object pfResolve) public void SendAsync (string sBody, string encoding, object pfResolve, object pfReject)
{ {
System.Threading.ThreadPool.QueueUserWorkItem (delegate System.Threading.ThreadPool.QueueUserWorkItem (delegate
{ {
JsUtils.Call (pfResolve, Send (sBody, encoding)); try
{
JsUtils.Call (pfResolve, Send (sBody, encoding));
}
catch (Exception ex)
{
JsUtils.Call (pfReject, new _I_Exception (ex));
}
}); });
} }
public void Dispose () { } public void Dispose () { }

215
LICENSE
View File

@@ -1,21 +1,202 @@
MIT License
Copyright (c) 2025 Windows Modern Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Permission is hereby granted, free of charge, to any person obtaining a copy TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all 1. Definitions.
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR "License" shall mean the terms and conditions for use, reproduction,
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, and distribution as defined by Sections 1 through 9 of this document.
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER "Licensor" shall mean the copyright owner or entity authorized by
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, the copyright owner that is granting the License.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. "Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

17
LICENSE.SharpZipLib Normal file
View File

@@ -0,0 +1,17 @@
Copyright © 2000-2018 SharpZipLib Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -115,10 +115,10 @@
this.label1.AutoSize = true; this.label1.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.label1, 5); this.tableLayoutPanel1.SetColumnSpan(this.label1, 5);
this.label1.Dock = System.Windows.Forms.DockStyle.Fill; this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Font = new System.Drawing.Font("微软雅黑 Light", 20F); this.label1.Font = new System.Drawing.Font("Segoe UI", 19.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(27, 24); this.label1.Location = new System.Drawing.Point(27, 24);
this.label1.Name = "label1"; this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(727, 45); this.label1.Size = new System.Drawing.Size(727, 46);
this.label1.TabIndex = 0; this.label1.TabIndex = 0;
this.label1.Text = "Create Desktop Shortcut"; this.label1.Text = "Create Desktop Shortcut";
// //
@@ -127,7 +127,7 @@
this.label2.AutoSize = true; this.label2.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.label2, 5); this.tableLayoutPanel1.SetColumnSpan(this.label2, 5);
this.label2.Dock = System.Windows.Forms.DockStyle.Fill; this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Location = new System.Drawing.Point(27, 79); this.label2.Location = new System.Drawing.Point(27, 80);
this.label2.Name = "label2"; this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(727, 60); this.label2.Size = new System.Drawing.Size(727, 60);
this.label2.TabIndex = 1; this.label2.TabIndex = 1;
@@ -147,7 +147,7 @@
this.tableLayoutPanel2.Controls.Add(this.label7, 0, 8); this.tableLayoutPanel2.Controls.Add(this.label7, 0, 8);
this.tableLayoutPanel2.Controls.Add(this.customIconDisplay, 0, 9); this.tableLayoutPanel2.Controls.Add(this.customIconDisplay, 0, 9);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(27, 152); this.tableLayoutPanel2.Location = new System.Drawing.Point(27, 153);
this.tableLayoutPanel2.Name = "tableLayoutPanel2"; this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 10; this.tableLayoutPanel2.RowCount = 10;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
@@ -160,7 +160,7 @@
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 39F)); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 39F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 18F)); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 18F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 13F)); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 13F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(235, 324); this.tableLayoutPanel2.Size = new System.Drawing.Size(235, 323);
this.tableLayoutPanel2.TabIndex = 2; this.tableLayoutPanel2.TabIndex = 2;
// //
// label3 // label3
@@ -251,7 +251,7 @@
this.customIconDisplay.Dock = System.Windows.Forms.DockStyle.Fill; this.customIconDisplay.Dock = System.Windows.Forms.DockStyle.Fill;
this.customIconDisplay.Location = new System.Drawing.Point(3, 230); this.customIconDisplay.Location = new System.Drawing.Point(3, 230);
this.customIconDisplay.Name = "customIconDisplay"; this.customIconDisplay.Name = "customIconDisplay";
this.customIconDisplay.Size = new System.Drawing.Size(229, 91); this.customIconDisplay.Size = new System.Drawing.Size(229, 90);
this.customIconDisplay.TabIndex = 7; this.customIconDisplay.TabIndex = 7;
this.customIconDisplay.TabStop = false; this.customIconDisplay.TabStop = false;
// //
@@ -273,7 +273,7 @@
this.tableLayoutPanel3.Controls.Add(this.label12, 0, 9); this.tableLayoutPanel3.Controls.Add(this.label12, 0, 9);
this.tableLayoutPanel3.Controls.Add(this.shortcutNameInput, 0, 10); this.tableLayoutPanel3.Controls.Add(this.shortcutNameInput, 0, 10);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(273, 152); this.tableLayoutPanel3.Location = new System.Drawing.Point(273, 153);
this.tableLayoutPanel3.Name = "tableLayoutPanel3"; this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 11; this.tableLayoutPanel3.RowCount = 11;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
@@ -287,7 +287,7 @@
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F)); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 18F)); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 18F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(235, 324); this.tableLayoutPanel3.Size = new System.Drawing.Size(235, 323);
this.tableLayoutPanel3.TabIndex = 3; this.tableLayoutPanel3.TabIndex = 3;
// //
// label5 // label5
@@ -476,14 +476,14 @@
this.tableLayoutPanel4.Controls.Add(this.imageSizeList, 0, 1); this.tableLayoutPanel4.Controls.Add(this.imageSizeList, 0, 1);
this.tableLayoutPanel4.Controls.Add(this.imagesPreview, 0, 3); this.tableLayoutPanel4.Controls.Add(this.imagesPreview, 0, 3);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel4.Location = new System.Drawing.Point(519, 152); this.tableLayoutPanel4.Location = new System.Drawing.Point(519, 153);
this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 4; this.tableLayoutPanel4.RowCount = 4;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(235, 324); this.tableLayoutPanel4.Size = new System.Drawing.Size(235, 323);
this.tableLayoutPanel4.TabIndex = 4; this.tableLayoutPanel4.TabIndex = 4;
// //
// label8 // label8
@@ -500,7 +500,7 @@
// //
this.label9.AutoSize = true; this.label9.AutoSize = true;
this.label9.Dock = System.Windows.Forms.DockStyle.Fill; this.label9.Dock = System.Windows.Forms.DockStyle.Fill;
this.label9.Location = new System.Drawing.Point(3, 162); this.label9.Location = new System.Drawing.Point(3, 161);
this.label9.Name = "label9"; this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(229, 20); this.label9.Size = new System.Drawing.Size(229, 20);
this.label9.TabIndex = 1; this.label9.TabIndex = 1;
@@ -516,7 +516,7 @@
this.imageSizeList.Location = new System.Drawing.Point(3, 23); this.imageSizeList.Location = new System.Drawing.Point(3, 23);
this.imageSizeList.Name = "imageSizeList"; this.imageSizeList.Name = "imageSizeList";
this.imageSizeList.RowTemplate.Height = 27; this.imageSizeList.RowTemplate.Height = 27;
this.imageSizeList.Size = new System.Drawing.Size(229, 136); this.imageSizeList.Size = new System.Drawing.Size(229, 135);
this.imageSizeList.TabIndex = 2; this.imageSizeList.TabIndex = 2;
this.imageSizeList.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.imageSizeList_CellDoubleClick); this.imageSizeList.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.imageSizeList_CellDoubleClick);
// //
@@ -536,7 +536,7 @@
this.imagesPreview.AutoScroll = true; this.imagesPreview.AutoScroll = true;
this.imagesPreview.Dock = System.Windows.Forms.DockStyle.Fill; this.imagesPreview.Dock = System.Windows.Forms.DockStyle.Fill;
this.imagesPreview.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; this.imagesPreview.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.imagesPreview.Location = new System.Drawing.Point(3, 185); this.imagesPreview.Location = new System.Drawing.Point(3, 184);
this.imagesPreview.Name = "imagesPreview"; this.imagesPreview.Name = "imagesPreview";
this.imagesPreview.Size = new System.Drawing.Size(229, 136); this.imagesPreview.Size = new System.Drawing.Size(229, 136);
this.imagesPreview.TabIndex = 3; this.imagesPreview.TabIndex = 3;

13
NOTICE.TXT Normal file
View File

@@ -0,0 +1,13 @@
Copyright (c) 2025-2026 Windows Modern
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

230
PkgCLI/CliParsing.cs Normal file
View File

@@ -0,0 +1,230 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PkgCLI
{
public class NormalizeStringComparer: IEqualityComparer<string>
{
public bool Equals (string x, string y) => Polyfill.NEquals (x, y);
public int GetHashCode (string obj) => obj.NNormalize ().GetHashCode ();
}
public class NormalizeCharacterComparer: IEqualityComparer<char>
{
public bool Equals (char x, char y) => char.ToLowerInvariant (x) == char.ToLowerInvariant (y);
public int GetHashCode (char obj) => char.ToLowerInvariant (obj).GetHashCode ();
}
public class StringNSet: HashSet<string>
{
public StringNSet () : base (new NormalizeStringComparer ()) { }
public StringNSet (IEnumerable<string> list) : base (list, new NormalizeStringComparer ()) { }
}
public class CharNSet: HashSet<char>
{
public CharNSet () : base (new NormalizeCharacterComparer ()) { }
public CharNSet (IEnumerable<char> list) : base (list, new NormalizeCharacterComparer ()) { }
}
public static class CliParsingConst
{
public static readonly char [] defaultPrefixs = new char [] { '/', '-' };
public static readonly char [] defaultPostfixs = new char [] { '=', ':' };
public static readonly string [] emptyStringArray = new string [] { };
}
public class CmdParamName: IEquatable<CmdParamName>, IComparable<CmdParamName>, IDisposable
{
private string _id = "";
private string _name = "";
/// <summary>
/// 命令唯一标识,但不作为命令名,仅用于内部识别。命令 ID 可以作为命令名或别名。
/// </summary>
public string Id { get { return _id.NNormalize (); } set { _id = value; } }
/// <summary>
/// 命令名,唯一。命令名不能与别名重复。首字符不能为前缀中的字符,尾字符不能为后缀中的字符。
/// </summary>
public string Name { get { return _name.NNormalize (); } set { _name = value; } }
/// <summary>
/// 命令别名,唯一。不能与命令名重复。首字符不能为前缀中的字符,尾字符不能为后缀中的字符。
/// </summary>
/// </summary>
public StringNSet Aliases { get; private set; } = new StringNSet ();
/// <summary>
/// 命令前缀,为一个字符,标点符号。不能为命令名或别名的首字符。
/// </summary>
public CharNSet Prefixs { get; set; } = new CharNSet (CliParsingConst.defaultPrefixs);
/// <summary>
/// 命令后缀,为一个字符,标点符号。不能为命令名或别名的尾字符。
/// </summary>
public CharNSet Postfixs { get; set; } = new CharNSet (CliParsingConst.defaultPostfixs);
public bool Equals (CmdParamName other)
{
if (other == null) return false;
if (ReferenceEquals (this, other)) return true;
return string.Equals (this.Id, other.Id, StringComparison.Ordinal);
}
public int CompareTo (CmdParamName other)
{
if (other == null) return 1;
if (ReferenceEquals (this, other)) return 0;
return string.Compare (this.Id, other.Id, StringComparison.Ordinal);
}
public override bool Equals (object obj) => Equals (obj as CmdParamName);
public override int GetHashCode () => this.Id?.GetHashCode () ?? 0;
public bool ParamContains (string param)
{
var ret = Name.NEquals (param);
if (!ret)
{
foreach (var alias in Aliases)
{
if (alias.NEquals (param)) return true;
}
}
return ret;
}
public void Dispose ()
{
Aliases?.Clear ();
Prefixs?.Clear ();
}
public CmdParamName (string id, string name, IEnumerable<string> aliases, IEnumerable<char> prefixs, IEnumerable<char> postfixs)
{
Id = id;
Name = name;
Aliases = new StringNSet (aliases);
Prefixs = new CharNSet (prefixs);
Postfixs = new CharNSet (postfixs);
}
public CmdParamName (string name, IEnumerable<string> aliases) : this (name, name, aliases, CliParsingConst.defaultPrefixs, CliParsingConst.defaultPostfixs) { }
public CmdParamName (string name) : this (name, CliParsingConst.emptyStringArray) { }
public CmdParamName () { }
}
public class CommandParam: IEquatable<string>
{
private string _id = "";
public string Id { get { return _id.NNormalize (); } set { _id = value; } }
public string Value = "";
public bool Equals (string other)
{
return (_id ?? "").NEquals (other);
}
public override bool Equals (object obj)
{
if (obj is string) return Equals (obj as string);
else if (obj is CommandParam) return Equals ((obj as CommandParam).Id);
else return base.Equals (obj);
}
public override int GetHashCode ()
{
return Id.GetHashCode ();
}
}
public class CliParsing: IDisposable
{
public HashSet<CmdParamName> Params { get; set; } = new HashSet<CmdParamName> ();
public void Dispose ()
{
Params = null;
}
public List<CommandParam> Parse (string [] args)
{
var ret = new List<CommandParam> ();
CommandParam last = new CommandParam ();
for (long i = 0; i < args.LongLength; i++)
{
var arg = args [i]?.Trim () ?? "";
var item = args [i]?.NNormalize () ?? "";
if (string.IsNullOrWhiteSpace (item)) continue;
var first = item [0];
bool isfind = false;
foreach (var param in Params)
{
if (param.Prefixs.Contains (first))
{
var minser = param.Postfixs.Select (e => {
var index = item.IndexOf (e);
return index == -1 ? int.MaxValue : index;
}).Min ();
string paramPart, postfixPart;
if (minser == int.MaxValue)
{
paramPart = arg.Substring (1);
postfixPart = "";
}
else
{
paramPart = arg.Substring (1, minser - 1);
postfixPart = arg.Substring (minser + 1);
}
if (param.ParamContains (paramPart))
{
isfind = true;
var cmdParam = new CommandParam ();
cmdParam.Id = param.Id;
if (!string.IsNullOrEmpty (postfixPart))
cmdParam.Value = postfixPart;
last = cmdParam;
ret.Add (cmdParam);
break;
}
}
}
if (!isfind)
{
var valueparam = new CommandParam ();
valueparam.Value = arg;
ret.Add (valueparam);
}
}
return ret;
}
}
public static class CliPasingUtils
{
public static bool ParamContains (this List<CommandParam> cpl, string id)
{
foreach (var i in cpl)
{
if (i.Id.NEquals (id)) return true;
}
return false;
}
public static bool ParamContains (this List<CommandParam> cpl, CmdParamName param)
{
foreach (var i in cpl)
{
if (i.Id.NEquals (param.Id)) return true;
}
return false;
}
public static bool ParamsContainsOr (this List<CommandParam> cpl, params string [] ids)
{
foreach (var i in cpl)
{
foreach (var j in ids)
{
if (i.Id.NEquals (j)) return true;
}
}
return false;
}
public static bool ParamsContainsAnd (this List<CommandParam> cpl, params string [] ids)
{
if (ids == null || ids.Length == 0) return true;
foreach (var id in ids)
{
if (!ParamContains (cpl, id)) return false;
}
return true;
}
public static CommandParam GetFromId (this List <CommandParam> cpl, string id)
{
foreach (var c in cpl)
{
if (c.Id.NEquals (id)) return c;
}
return null;
}
}
}

97
PkgCLI/PkgCLI.csproj Normal file
View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" 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>{8D333AF6-E901-4301-B3EE-923088E81062}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PkgCLI</RootNamespace>
<AssemblyName>PkgCLI</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net40\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CliParsing.cs" />
<Compile Include="Polyfill.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Text.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AppxPackage\AppxPackage.csproj">
<Project>{bd681a4f-eb60-4bb8-90b5-65968fc7da59}</Project>
<Name>AppxPackage</Name>
</ProjectReference>
<ProjectReference Include="..\DataUtils\DataUtils.csproj">
<Project>{ffd3fd52-37a8-4f43-883c-de8d996cb0e0}</Project>
<Name>DataUtils</Name>
</ProjectReference>
<ProjectReference Include="..\PrivateInit\PrivateInit.csproj">
<Project>{8e708d9a-6325-4aa9-b5a5-d1b5eca8eef7}</Project>
<Name>PrivateInit</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

987
PkgCLI/Polyfill.cs Normal file
View File

@@ -0,0 +1,987 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using AppxPackage;
using AppxPackage.Info;
using Newtonsoft.Json;
namespace PkgCLI
{
public static class Polyfill
{
static public bool NEquals (this string s1, string s2)
{
if (string.IsNullOrWhiteSpace (s1) && string.IsNullOrWhiteSpace (s2)) return true;
else return s1?.Trim ()?.ToLowerInvariant () == s2?.Trim ()?.ToLowerInvariant ();
}
static public string NNormalize (this string s1)
{
return s1?.Trim ()?.ToLowerInvariant ();
}
static public string Join<T> (this IEnumerable<T> ie, string divide = ", ")
{
var ret = "";
for (var i = 0; i < ie.Count (); i++)
{
if (i != 0) ret += divide;
var item = ie.ElementAt (i);
if (item == null) ret += "(null)";
else ret += item.ToString ();
}
return ret;
}
/// <summary>
/// 将对象通过指定的选择器转换为目标类型。
/// 类似于 LINQ 的 Select但适用于单一对象。
/// </summary>
/// <typeparam name="T">目标类型</typeparam>
/// <param name="obj">源对象</param>
/// <param name="selector">转换委托,输入源对象,输出目标对象</param>
/// <returns>转换后的结果</returns>
public static T ToOther<T> (this object obj, Func<object, T> selector)
{
if (selector == null)
throw new ArgumentNullException (nameof (selector));
return selector (obj);
}
/// <summary>
/// 将字典格式化为对齐的文本,每个键值对一行,分隔符垂直对齐。
/// </summary>
/// <param name="dict">要格式化的字典</param>
/// <param name="separator">分隔符(如 ":", "="),默认为 ":"</param>
/// <param name="indent">每行前的缩进字符串,默认为空</param>
/// <param name="sortKeys">是否按键名排序(不区分大小写),默认为 false</param>
/// <returns>格式化后的字符串,例如:
/// Name : Alice
/// Age : 30
/// </returns>
public static string FormatDictionaryAligned (
this IDictionary<string, string> dict,
string separator = ":",
string indent = "",
bool sortKeys = false)
{
if (dict == null || dict.Count == 0)
return string.Empty;
var keys = sortKeys
? dict.Keys.OrderBy (k => k, StringComparer.OrdinalIgnoreCase).ToList ()
: dict.Keys.ToList ();
int maxKeyLength = keys.Max (k => k.Length);
var sb = new StringBuilder ();
foreach (string key in keys)
{
string value = dict [key] ?? string.Empty;
sb.AppendLine ($"{indent}{key.PadRight (maxKeyLength)} {separator} {value}");
}
return sb.ToString ().TrimEnd (Environment.NewLine.ToCharArray ());
}
public static string Format (this string format, params object [] args)
{
return String.Format (format, args);
}
public static string Format (this string format, object args)
{
return String.Format (format, args);
}
}
public static class PackageReaderExt
{
static public object GetJsonObjectForCli (this PackageReader pr)
{
var id = pr.Identity;
var prop = pr.Properties;
var pre = pr.Prerequisites;
var apps = pr.Applications;
var caps = pr.Capabilities;
var deps = pr.Dependencies;
dynamic obj = new {
valid = pr.IsValid,
type = pr.Type.ToOther (e => {
switch ((AppxPackage.Info.PackageType)e)
{
case AppxPackage.Info.PackageType.Appx: return "appx";
case AppxPackage.Info.PackageType.Bundle: return "bundle";
default:
case AppxPackage.Info.PackageType.Unknown: return "unknown";
}
}),
role = pr.Role.ToOther (o => {
switch ((AppxPackage.Info.PackageRole)o)
{
case AppxPackage.Info.PackageRole.Application: return "application";
case AppxPackage.Info.PackageRole.Framework: return "framework";
case AppxPackage.Info.PackageRole.Resource: return "resource";
default:
case AppxPackage.Info.PackageRole.Unknown: return "unknown";
}
}),
identity = new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.Expression,
realVersion = id.RealVersion.Expression,
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case AppxPackage.Info.Architecture.ARM: return "arm";
case AppxPackage.Info.Architecture.ARM64: return "arm64";
case AppxPackage.Info.Architecture.Neutral: return "neutral";
default:
case AppxPackage.Info.Architecture.Unknown: return "unknown";
case AppxPackage.Info.Architecture.x64: return "x64";
case AppxPackage.Info.Architecture.x86: return "x86";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId
},
properties = new {
displayName = prop.DisplayName,
publisherDisplayName = prop.Publisher,
description = prop.Description,
logo = prop.Logo,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
},
prerequisite = new {
osMinVersion = pre.OSMinVersion.ToString (),
osMaxVersionTested = pre.OSMaxVersionTested.ToString (),
_osMinVersion = pre.OSMinVersionDescription,
_osMaxVersionTested = pre.OSMaxVersionDescription
},
applications = apps.Select (e => {
var dict = new Dictionary<string, string> ();
foreach (var kv in e)
{
if (kv.Key.IndexOf ("Base64") >= 0) continue;
var value = e.NewAt (kv.Key, pr.EnablePri);
if (string.IsNullOrWhiteSpace (value))
value = e.At (kv.Key);
dict [kv.Key] = value;
}
return dict;
}).ToList (),
capabilities = new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
},
dependencies = deps.Select (e => new {
name = e.Name,
publisher = e.Publisher,
minVersion = e.Version.ToString ()
})
};
return obj;
}
/// <summary>
/// 从 PackageReader 中获取指定路径的值。
/// 支持格式:路径中可使用 '.' 或 ':' 分隔,支持索引器 '[index]',支持 '.length'。
/// 大小写不敏感,自动去除首尾空白。
/// 示例:
/// "Identity" -> 返回 Identity 字典
/// "Identity.Name" -> 返回名称
/// "Properties.Publisher" -> 返回发布者显示名称(别名)
/// "applications[0]" -> 返回第一个应用字典
/// "applications.length" -> 返回应用个数
/// "Applications[0].LogoBase64" -> 返回第一个应用的 LogoBase64
/// </summary>
public static object GetItem (this PackageReader pr, string item)
{
if (pr == null) throw new ArgumentNullException ("pr");
if (string.IsNullOrWhiteSpace (item)) return null;
string path = item.Trim ().Replace (':', '.');
object result = ResolvePath (pr, path);
return SerializeObject (result, pr, false);
}
private static object ResolvePath (object target, string path)
{
if (target == null) return null;
if (string.IsNullOrEmpty (path)) return target;
string [] segments = path.Split ('.');
object current = target;
foreach (string seg in segments)
{
if (current == null) return null;
if (seg.Contains ("[") && seg.Contains ("]"))
{
int bracketStart = seg.IndexOf ('[');
string propName = seg.Substring (0, bracketStart);
string indexStr = seg.Substring (bracketStart + 1, seg.Length - bracketStart - 2);
int index;
if (!int.TryParse (indexStr, out index))
return null;
object collection = GetPropertyValue (current, propName);
if (collection == null) return null;
current = GetIndexedValue (collection, index);
}
else if (string.Equals (seg, "length", StringComparison.OrdinalIgnoreCase) ||
string.Equals (seg, "count", StringComparison.OrdinalIgnoreCase))
{
current = GetLength (current);
}
else
{
current = GetPropertyValue (current, seg);
}
}
return current;
}
private static object GetPropertyValue (object target, string propName)
{
if (target == null) return null;
Type type = target.GetType ();
// 根对象 PackageReader 的属性名映射(不区分大小写)
if (type == typeof (PackageReader))
{
string mapped = null;
string lower = propName.ToLowerInvariant ();
switch (lower)
{
case "pkgid":
case "id":
case "identity": mapped = "Identity"; break;
case "prop":
case "properties": mapped = "Properties"; break;
case "prerequistes":
case "prerequisite":
case "prerequisites": mapped = "Prerequisites"; break;
case "res":
case "resources": mapped = "Resources"; break;
case "apps":
case "applications": mapped = "Applications"; break;
case "caps":
case "capabilities": mapped = "Capabilities"; break;
case "deps":
case "dependencies": mapped = "Dependencies"; break;
case "type": mapped = "Type"; break;
case "role": mapped = "Role"; break;
case "valid":
case "isvalid": mapped = "IsValid"; break;
case "filepath": mapped = "FilePath"; break;
}
if (mapped != null)
propName = mapped;
}
// PRProperties 别名Publisher / PublisherDisplayName 都映射到 Publisher 属性
if (type == typeof (PRProperties))
{
if (string.Equals (propName, "Publisher", StringComparison.OrdinalIgnoreCase) ||
string.Equals (propName, "PublisherDisplayName", StringComparison.OrdinalIgnoreCase))
{
propName = "Publisher";
}
}
// PRApplication 中以 Base64 结尾的属性 -> 调用 NewAtBase64
if (type == typeof (PRApplication) && propName.EndsWith ("Base64", StringComparison.OrdinalIgnoreCase))
{
string baseKey = propName.Substring (0, propName.Length - 6);
PRApplication app = (PRApplication)target;
MethodInfo method = typeof (PRApplication).GetMethod ("NewAtBase64", BindingFlags.Public | BindingFlags.Instance);
if (method != null)
{
return method.Invoke (app, new object [] { baseKey });
}
return null;
}
// PRApplication 普通属性访问(字典键,大小写不敏感)
if (type == typeof (PRApplication))
{
PRApplication app = (PRApplication)target;
// 直接使用索引器,内部已处理资源解析和大小写不敏感
return app [propName];
}
// MRApplication 同理
if (type == typeof (MRApplication))
{
MRApplication app = (MRApplication)target;
return app [propName];
}
// 反射属性(不区分大小写)
PropertyInfo prop = type.GetProperty (propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (prop != null)
{
return prop.GetValue (target, null);
}
// 反射字段
FieldInfo field = type.GetField (propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (field != null)
{
return field.GetValue (target);
}
return null;
}
private static object GetIndexedValue (object collection, int index)
{
if (collection == null) return null;
// PRApplications
PRApplications apps = collection as PRApplications;
if (apps != null)
{
if (index >= 0 && index < apps.Applications.Count)
return apps.Applications [index];
return null;
}
// IList
IList list = collection as IList;
if (list != null && index >= 0 && index < list.Count)
return list [index];
// 索引器属性
PropertyInfo indexer = collection.GetType ().GetProperty ("Item", new [] { typeof (int) });
if (indexer != null)
return indexer.GetValue (collection, new object [] { index });
return null;
}
private static int? GetLength (object obj)
{
if (obj == null) return null;
PRApplications apps = obj as PRApplications;
if (apps != null) return apps.Applications.Count;
PRDependencies deps = obj as PRDependencies;
if (deps != null) return deps.Dependencies.Count;
IList list = obj as IList;
if (list != null) return list.Count;
ICollection coll = obj as ICollection;
if (coll != null) return coll.Count;
return null;
}
private static object SerializeObject (object obj, PackageReader pr, bool filterBase64)
{
if (obj == null) return null;
Type type = obj.GetType ();
if (type.IsPrimitive || obj is string || obj is decimal || obj is Enum)
return obj;
// PRIdentity
if (type == typeof (PRIdentity))
{
PRIdentity id = (PRIdentity)obj;
return new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.Expression,
realVersion = id.RealVersion.Expression,
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case Architecture.ARM: return "arm";
case Architecture.ARM64: return "arm64";
case Architecture.Neutral: return "neutral";
case Architecture.x64: return "x64";
case Architecture.x86: return "x86";
default: return "unknown";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId
};
}
// PRProperties
if (type == typeof (PRProperties))
{
PRProperties prop = (PRProperties)obj;
return new {
displayName = prop.DisplayName,
publisherDisplayName = prop.Publisher,
description = prop.Description,
logo = prop.Logo,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
};
}
// PRPrerequisites
if (type == typeof (PRPrerequisites))
{
PRPrerequisites pre = (PRPrerequisites)obj;
return new {
osMinVersion = pre.OSMinVersion,
osMaxVersionTested = pre.OSMaxVersionTested,
_osMinVersion = pre.OSMinVersionDescription,
_osMaxVersionTested = pre.OSMaxVersionDescription
};
}
// PRCapabilities
if (type == typeof (PRCapabilities))
{
PRCapabilities caps = (PRCapabilities)obj;
return new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
};
}
// PRDependencies
if (type == typeof (PRDependencies))
{
PRDependencies deps = (PRDependencies)obj;
return deps.Select (e => new {
name = e.Name,
publisher = e.Publisher,
minVersion = e.Version.ToString ()
}).ToList ();
}
// PRApplications (集合)
if (type == typeof (PRApplications))
{
PRApplications apps = (PRApplications)obj;
return apps.Select (e => SerializeObject (e, pr, filterBase64)).ToList ();
}
// PRApplication (单个应用)
if (type == typeof (PRApplication))
{
PRApplication app = (PRApplication)obj;
var dict = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
foreach (var kv in app)
{
if (kv.Key.IndexOf ("Base64", StringComparison.OrdinalIgnoreCase) >= 0)
continue;
string value = app.NewAt (kv.Key, pr.EnablePri);
if (string.IsNullOrWhiteSpace (value))
value = app.At (kv.Key);
dict [kv.Key] = value;
}
return dict;
}
// IDictionary
IDictionary dictObj = obj as IDictionary;
if (dictObj != null)
{
var result = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
foreach (DictionaryEntry entry in dictObj)
{
string key = entry.Key?.ToString ();
if (string.IsNullOrEmpty (key)) continue;
if (filterBase64 && key.EndsWith ("_Base64", StringComparison.OrdinalIgnoreCase))
continue;
result [key] = SerializeObject (entry.Value, pr, filterBase64);
}
return result;
}
// IEnumerable (非字符串)
if (!(obj is string))
{
IEnumerable enumerable = obj as IEnumerable;
if (enumerable != null)
{
var list = new List<object> ();
foreach (var item in enumerable)
list.Add (SerializeObject (item, pr, filterBase64));
return list;
}
}
// 后备:反射属性
var props = type.GetProperties (BindingFlags.Public | BindingFlags.Instance);
var propDict = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
foreach (var prop in props)
{
if (prop.GetIndexParameters ().Length > 0) continue;
string propName = prop.Name;
if (filterBase64 && propName.EndsWith ("Base64", StringComparison.OrdinalIgnoreCase))
continue;
object val = prop.GetValue (obj, null);
propDict [propName] = SerializeObject (val, pr, filterBase64);
}
return propDict;
}
}
public static class ManifestReaderExt
{
/// <summary>
/// 获取用于 CLI 输出的 JSON 对象(与 PackageReaderExt.GetJsonObjectForCli 结构一致)。
/// </summary>
public static object GetJsonObjectForCli (this ManifestReader mr)
{
var id = mr.Identity;
var prop = mr.Properties;
var pre = mr.Prerequisites;
var apps = mr.Applications;
var caps = mr.Capabilities;
var deps = mr.Dependencies;
var res = mr.Resources;
dynamic obj = new {
valid = mr.IsValid,
type = mr.Type.ToOther (e => {
switch ((PackageType)e)
{
case PackageType.Appx: return "appx";
case PackageType.Bundle: return "bundle";
default:
case PackageType.Unknown: return "unknown";
}
}),
role = mr.Role.ToOther (o => {
switch ((PackageRole)o)
{
case PackageRole.Application: return "application";
case PackageRole.Framework: return "framework";
case PackageRole.Resource: return "resource";
default:
case PackageRole.Unknown: return "unknown";
}
}),
identity = new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.Expression,
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case Architecture.ARM: return "arm";
case Architecture.ARM64: return "arm64";
case Architecture.Neutral: return "neutral";
case Architecture.x64: return "x64";
case Architecture.x86: return "x86";
default: return "unknown";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId
},
properties = new {
displayName = prop.DisplayName,
publisherDisplayName = prop.Publisher,
description = prop.Description,
logo = prop.Logo,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
},
prerequisite = new {
osMinVersion = pre.OSMinVersion.ToString (),
osMaxVersionTested = pre.OSMaxVersionTested.ToString (),
_osMinVersion = pre.OSMinVersionDescription,
_osMaxVersionTested = pre.OSMaxVersionDescription
},
resources = new {
languages = res.Languages,
scales = res.Scales,
dxFeatureLevels = res.DXFeatures.Select (d => {
switch (d)
{
case DXFeatureLevel.Level9: return 9;
case DXFeatureLevel.Level10: return 10;
case DXFeatureLevel.Level11: return 11;
case DXFeatureLevel.Level12: return 12;
default: return -1;
}
}).ToList ()
},
applications = apps.Select (e => {
var dict = new Dictionary<string, string> ();
foreach (var kv in e)
{
if (kv.Key.IndexOf ("Base64", StringComparison.OrdinalIgnoreCase) >= 0)
continue;
string value = e.NewAt (kv.Key, mr.EnablePri);
if (string.IsNullOrWhiteSpace (value))
value = e.At (kv.Key);
dict [kv.Key] = value;
}
return dict;
}).ToList (),
capabilities = new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
},
dependencies = deps.Select (e => new {
name = e.Name,
publisher = e.Publisher,
minVersion = e.Version.ToString ()
})
};
return obj;
}
/// <summary>
/// 从 ManifestReader 中获取指定路径的值。
/// 支持格式:路径中可使用 '.' 或 ':' 分隔,支持索引器 '[index]',支持 '.length'。
/// 大小写不敏感,自动去除首尾空白。
/// 示例:
/// "Identity" -> 返回 Identity 字典
/// "Identity.Name" -> 返回名称
/// "Properties.Publisher" -> 返回发布者显示名称(别名)
/// "applications[0]" -> 返回第一个应用字典
/// "applications.length" -> 返回应用个数
/// "Applications[0].LogoBase64" -> 返回第一个应用的 LogoBase64
/// </summary>
public static object GetItem (this ManifestReader mr, string item)
{
if (mr == null) throw new ArgumentNullException ("mr");
if (string.IsNullOrWhiteSpace (item)) return null;
string path = item.Trim ().Replace (':', '.');
object result = ResolvePath (mr, path);
return SerializeObject (result, mr, false);
}
private static object ResolvePath (object target, string path)
{
if (target == null) return null;
if (string.IsNullOrEmpty (path)) return target;
string [] segments = path.Split ('.');
object current = target;
foreach (string seg in segments)
{
if (current == null) return null;
if (seg.Contains ("[") && seg.Contains ("]"))
{
int bracketStart = seg.IndexOf ('[');
string propName = seg.Substring (0, bracketStart);
string indexStr = seg.Substring (bracketStart + 1, seg.Length - bracketStart - 2);
int index;
if (!int.TryParse (indexStr, out index))
return null;
object collection = GetPropertyValue (current, propName);
if (collection == null) return null;
current = GetIndexedValue (collection, index);
}
else if (string.Equals (seg, "length", StringComparison.OrdinalIgnoreCase) ||
string.Equals (seg, "count", StringComparison.OrdinalIgnoreCase))
{
current = GetLength (current);
}
else
{
current = GetPropertyValue (current, seg);
}
}
return current;
}
private static object GetPropertyValue (object target, string propName)
{
if (target == null) return null;
Type type = target.GetType ();
// 根对象 ManifestReader 的属性名映射(不区分大小写)
if (type == typeof (ManifestReader))
{
string mapped = null;
string lower = propName.ToLowerInvariant ();
switch (lower)
{
case "pkgid":
case "id":
case "identity": mapped = "Identity"; break;
case "prop":
case "properties": mapped = "Properties"; break;
case "prerequistes":
case "prerequisite":
case "prerequisites": mapped = "Prerequisites"; break;
case "res":
case "resources": mapped = "Resources"; break;
case "apps":
case "applications": mapped = "Applications"; break;
case "caps":
case "capabilities": mapped = "Capabilities"; break;
case "deps":
case "dependencies": mapped = "Dependencies"; break;
case "type": mapped = "Type"; break;
case "role": mapped = "Role"; break;
case "valid":
case "isvalid": mapped = "IsValid"; break;
case "file":
case "filepath": mapped = "FilePath"; break;
case "fileroot": mapped = "FileRoot"; break;
}
if (mapped != null)
propName = mapped;
}
// MRProperties 别名Publisher / PublisherDisplayName 都映射到 Publisher 属性
if (type == typeof (MRProperties))
{
if (string.Equals (propName, "Publisher", StringComparison.OrdinalIgnoreCase) ||
string.Equals (propName, "PublisherDisplayName", StringComparison.OrdinalIgnoreCase))
{
propName = "Publisher";
}
}
// MRApplication 中以 Base64 结尾的属性 -> 调用 NewAtBase64
if (type == typeof (MRApplication) && propName.EndsWith ("Base64", StringComparison.OrdinalIgnoreCase))
{
string baseKey = propName.Substring (0, propName.Length - 6);
MRApplication app = (MRApplication)target;
MethodInfo method = typeof (MRApplication).GetMethod ("NewAtBase64", BindingFlags.Public | BindingFlags.Instance);
if (method != null)
{
return method.Invoke (app, new object [] { baseKey });
}
return null;
}
// MRApplication 普通属性访问(字典键,大小写不敏感)
if (type == typeof (MRApplication))
{
MRApplication app = (MRApplication)target;
return app [propName];
}
// 反射属性(不区分大小写)
PropertyInfo prop = type.GetProperty (propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (prop != null)
{
return prop.GetValue (target, null);
}
// 反射字段
FieldInfo field = type.GetField (propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (field != null)
{
return field.GetValue (target);
}
return null;
}
private static object GetIndexedValue (object collection, int index)
{
if (collection == null) return null;
MRApplications apps = collection as MRApplications;
if (apps != null)
{
if (index >= 0 && index < apps.Applications.Count)
return apps.Applications [index];
return null;
}
IList list = collection as IList;
if (list != null && index >= 0 && index < list.Count)
return list [index];
PropertyInfo indexer = collection.GetType ().GetProperty ("Item", new [] { typeof (int) });
if (indexer != null)
return indexer.GetValue (collection, new object [] { index });
return null;
}
private static int? GetLength (object obj)
{
if (obj == null) return null;
MRApplications apps = obj as MRApplications;
if (apps != null) return apps.Applications.Count;
MRDependencies deps = obj as MRDependencies;
if (deps != null) return deps.Dependencies.Count;
IList list = obj as IList;
if (list != null) return list.Count;
ICollection coll = obj as ICollection;
if (coll != null) return coll.Count;
return null;
}
private static object SerializeObject (object obj, ManifestReader mr, bool filterBase64)
{
if (obj == null) return null;
Type type = obj.GetType ();
if (type.IsPrimitive || obj is string || obj is decimal || obj is Enum)
return obj;
// MRIdentity
if (type == typeof (MRIdentity))
{
MRIdentity id = (MRIdentity)obj;
return new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.Expression,
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case Architecture.ARM: return "arm";
case Architecture.ARM64: return "arm64";
case Architecture.Neutral: return "neutral";
case Architecture.x64: return "x64";
case Architecture.x86: return "x86";
default: return "unknown";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId
};
}
// MRProperties
if (type == typeof (MRProperties))
{
MRProperties prop = (MRProperties)obj;
return new {
displayName = prop.DisplayName,
publisherDisplayName = prop.Publisher,
description = prop.Description,
logo = prop.Logo,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
};
}
// MRPrerequisites
if (type == typeof (MRPrerequisites))
{
MRPrerequisites pre = (MRPrerequisites)obj;
return new {
osMinVersion = pre.OSMinVersion,
osMaxVersionTested = pre.OSMaxVersionTested,
_osMinVersion = pre.OSMinVersionDescription,
_osMaxVersionTested = pre.OSMaxVersionDescription
};
}
// MRResources
if (type == typeof (MRResources))
{
MRResources res = (MRResources)obj;
return new {
languages = res.Languages,
scales = res.Scales,
dxFeatureLevels = res.DXFeatures.Select (d => {
switch (d)
{
case DXFeatureLevel.Level9: return 9;
case DXFeatureLevel.Level10: return 10;
case DXFeatureLevel.Level11: return 11;
case DXFeatureLevel.Level12: return 12;
default: return -1;
}
}).ToList ()
};
}
// MRCapabilities
if (type == typeof (MRCapabilities))
{
MRCapabilities caps = (MRCapabilities)obj;
return new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
};
}
// MRDependencies
if (type == typeof (MRDependencies))
{
MRDependencies deps = (MRDependencies)obj;
return deps.Select (e => new {
name = e.Name,
publisher = e.Publisher,
minVersion = e.Version.ToString ()
}).ToList ();
}
// MRApplications (集合)
if (type == typeof (MRApplications))
{
MRApplications apps = (MRApplications)obj;
return apps.Select (e => SerializeObject (e, mr, filterBase64)).ToList ();
}
// MRApplication (单个应用)
if (type == typeof (MRApplication))
{
MRApplication app = (MRApplication)obj;
var dict = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
foreach (var kv in app)
{
if (kv.Key.IndexOf ("Base64", StringComparison.OrdinalIgnoreCase) >= 0)
continue;
string value = app.NewAt (kv.Key, mr.EnablePri);
if (string.IsNullOrWhiteSpace (value))
value = app.At (kv.Key);
dict [kv.Key] = value;
}
return dict;
}
// IDictionary
IDictionary dictObj = obj as IDictionary;
if (dictObj != null)
{
var result = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
foreach (DictionaryEntry entry in dictObj)
{
string key = entry.Key?.ToString ();
if (string.IsNullOrEmpty (key)) continue;
if (filterBase64 && key.EndsWith ("_Base64", StringComparison.OrdinalIgnoreCase))
continue;
result [key] = SerializeObject (entry.Value, mr, filterBase64);
}
return result;
}
// IEnumerable (非字符串)
if (!(obj is string))
{
IEnumerable enumerable = obj as IEnumerable;
if (enumerable != null)
{
var list = new List<object> ();
foreach (var item in enumerable)
list.Add (SerializeObject (item, mr, filterBase64));
return list;
}
}
// 后备:反射属性
var props = type.GetProperties (BindingFlags.Public | BindingFlags.Instance);
var propDict = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
foreach (var prop in props)
{
if (prop.GetIndexParameters ().Length > 0) continue;
string propName = prop.Name;
if (filterBase64 && propName.EndsWith ("Base64", StringComparison.OrdinalIgnoreCase))
continue;
object val = prop.GetValue (obj, null);
propDict [propName] = SerializeObject (val, mr, filterBase64);
}
return propDict;
}
}
}

859
PkgCLI/Program.cs Normal file
View File

@@ -0,0 +1,859 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataUtils;
using AppxPackage;
using System.IO;
using static AppxPackage.PackageManager;
using Newtonsoft.Json;
using Win32;
namespace PkgCLI
{
class Program
{
public delegate _I_HResult PackageOperation (string filePath, IEnumerable<string> depUris, DeploymentOptions options, PackageProgressCallback progress = null);
static readonly string [] helpArgs = new string [] {
"/?",
"-?",
"help",
"/help",
"-help",
"/h",
"-h"
};
public static StringResXmlDoc res = new StringResXmlDoc (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "locale\\pkgcli.xml"));
static bool IsHelpParam (string arg) => helpArgs.Contains (arg.Normalize ());
static void PrintVersion ()
{
var verFilePath = Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "version");
var verFileInst = new _I_File (verFilePath);
var verstr = verFileInst.Content?.Trim () ?? "0.0.0.1";
Console.WriteLine (String.Format (res.Get ("PKGCLI_VERSION"), verstr));
}
static void PrintTotalHelp ()
{
Console.WriteLine (res.Get ("PKGCLI_TOTALHELP"));
}
public static bool IsFilePathInList (List<string> filelist, string file)
{
foreach (var f in filelist)
{
if (f.NEquals (file)) return true;
}
return false;
}
public static void AddFiles (List<string> filelist, string file)
{
if (string.IsNullOrWhiteSpace (file)) return;
if (!File.Exists (file)) file = Path.Combine (Environment.CurrentDirectory, file);
if (!File.Exists (file)) return;
var ext = Path.GetExtension (file);
if (ext.NEquals (".txt"))
{
var lines = File.ReadAllLines (file);
foreach (var l in lines)
{
if (string.IsNullOrWhiteSpace (l)) continue;
var line = l.Trim ();
if (!File.Exists (l)) line = Path.Combine (Path.GetDirectoryName (file), l);
if (!File.Exists (line)) continue;
if (!IsFilePathInList (filelist, line))
filelist.Add (line);
}
}
else if (!IsFilePathInList (filelist, file)) filelist.Add (file);
}
public static void AddNStringItems (List<string> strlist, string str)
{
var find = false;
foreach (var l in strlist)
if (l.NEquals (str))
{
find = true;
break;
}
if (!find) strlist.Add (str);
}
public static void ToFormatString (PMPackageInfo pkg, IEnumerable<string> filter)
{
if (pkg == null) return;
var labels = new List<string> ();
var values = new List<string> ();
var id = pkg.Identity;
labels.Add ("Identity:Name"); values.Add (id.Name);
labels.Add ("Identity:Publisher"); values.Add (id.Publisher);
labels.Add ("Identity:FamilyName"); values.Add (id.FamilyName);
labels.Add ("Identity:FullName"); values.Add (id.FullName);
labels.Add ("Identity:PublisherId"); values.Add (id.PublisherId);
labels.Add ("Identity:ResourceId"); values.Add (id.ResourceId);
labels.Add ("Identity:Version"); values.Add (id.Version?.ToString () ?? "");
labels.Add ("Identity:ProcessArchitecture"); values.Add (string.Join (", ", id.ProcessArchitecture));
var prop = pkg.Properties;
labels.Add ("Properties:DisplayName"); values.Add (prop.DisplayName);
labels.Add ("Properties:Description"); values.Add (prop.Description);
labels.Add ("Properties:Publisher"); values.Add (prop.Publisher);
labels.Add ("Properties:Framework"); values.Add (prop.Framework.ToString ());
labels.Add ("Properties:ResourcePackage"); values.Add (prop.ResourcePackage.ToString ());
labels.Add ("Properties:Logo"); values.Add (prop.Logo);
labels.Add ("IsBundle"); values.Add (pkg.IsBundle.ToString ());
labels.Add ("DevelopmentMode"); values.Add (pkg.DevelopmentMode.ToString ());
labels.Add ("InstallLocation"); values.Add (pkg.InstallLocation);
labels.Add ("Users"); values.Add (string.Join ("; ", pkg.Users));
Console.WriteLine ($"[{pkg.Identity.FullName}]");
var indicesToOutput = new List<int> ();
bool outputAll = (filter == null || !filter.Any ());
for (int i = 0; i < labels.Count; i++)
{
if (outputAll)
{
indicesToOutput.Add (i);
}
else
{
string label = labels [i];
foreach (string patternRaw in filter)
{
if (MatchPattern (label, patternRaw))
{
indicesToOutput.Add (i);
break;
}
}
}
}
if (indicesToOutput.Count == 0) return;
int maxLabelLen = 0;
foreach (int i in indicesToOutput)
if (labels [i].Length > maxLabelLen) maxLabelLen = labels [i].Length;
string format = "{0,-" + maxLabelLen + "} = {1}";
foreach (int i in indicesToOutput)
Console.WriteLine (format, labels [i], values [i]);
}
/// <summary>
/// 匹配模式(忽略大小写,首尾空格,支持通配符 *
/// </summary>
private static bool MatchPattern (string text, string pattern)
{
if (string.IsNullOrEmpty (pattern)) return true;
pattern = pattern.Trim ();
text = text ?? "";
if (pattern == "*") return true;
// 忽略大小写
var comparison = StringComparison.OrdinalIgnoreCase;
// 检查通配符位置
bool startsWithStar = pattern.StartsWith ("*");
bool endsWithStar = pattern.EndsWith ("*");
if (startsWithStar && endsWithStar)
{
// *middle* 包含子串
string middle = pattern.Substring (1, pattern.Length - 2);
return text.IndexOf (middle, comparison) >= 0;
}
else if (startsWithStar)
{
// *suffix 以 suffix 结尾
string suffix = pattern.Substring (1);
return text.EndsWith (suffix, comparison);
}
else if (endsWithStar)
{
// prefix* 以 prefix 开头
string prefix = pattern.Substring (0, pattern.Length - 1);
return text.StartsWith (prefix, comparison);
}
else
{
// 精确匹配(忽略大小写)
return string.Equals (text, pattern, comparison);
}
}
/// <summary>
/// 判断字符串是否为有效的包全名 (Package Full Name)
/// 格式: <IdentityName>_<Version>_<ProcessorArchitecture>_<ResourceId>_<PublisherId>
/// 其中 ResourceId 可以为空(表现为连续两个下划线)
/// </summary>
public static bool IsPackageFullName (string fullName)
{
if (string.IsNullOrWhiteSpace (fullName)) return false;
string [] parts = fullName.Split (new char [] { '_' }, StringSplitOptions.None);
if (parts.Length != 5)
return false;
if (string.IsNullOrEmpty (parts [0])) // IdentityName
return false;
if (string.IsNullOrEmpty (parts [1])) // Version
return false;
if (string.IsNullOrEmpty (parts [2])) // ProcessorArchitecture
return false;
if (string.IsNullOrEmpty (parts [4])) // PublisherId
return false;
if (!parts [1].Contains ('.')) return false;
return true;
}
/// <summary>
/// 判断字符串是否为有效的包系列名 (Package Family Name)
/// 格式: <IdentityName>_<PublisherId>
/// </summary>
public static bool IsPackageFamilyName (string familyName)
{
if (string.IsNullOrWhiteSpace (familyName)) return false;
string [] parts = familyName.Split ('_');
if (parts.Length != 2) return false;
if (string.IsNullOrEmpty (parts [0]) || string.IsNullOrEmpty (parts [1]))
return false;
return true;
}
/// <summary>
/// 从 args[startIndex..] 生成安全的命令行字符串
/// </summary>
private static string BuildCommandLine (string [] args, int startIndex)
{
if (args.Length <= startIndex) return null;
var sb = new StringBuilder ();
for (int i = startIndex; i < args.Length; i++)
{
if (i > startIndex) sb.Append (' ');
sb.Append (EscapeArgument (args [i]));
}
return sb.ToString ();
}
/// <summary>
/// 按 Win32 命令行规则转义单个参数
/// </summary>
private static string EscapeArgument (string arg)
{
if (string.IsNullOrEmpty (arg)) return "\"\"";
bool needQuotes = false;
foreach (char c in arg)
{
if (char.IsWhiteSpace (c) || c == '"')
{
needQuotes = true;
break;
}
}
if (!needQuotes) return arg;
var sb = new StringBuilder ();
sb.Append ('"');
foreach (char c in arg)
{
if (c == '"') sb.Append ("\\\"");
else sb.Append (c);
}
sb.Append ('"');
return sb.ToString ();
}
public static readonly string [] configItems = new string [] {
"AppMetadataItems"
};
public static void RefreshConfig ()
{
var conf = new InitConfig (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "config.ini"));
var sSettings = conf.GetSection ("Settings");
var kAppMetadatas = sSettings.GetKey ("PkgCLI:AppMetadataItems");
var appMd = kAppMetadatas.ReadString ("Id,BackgroundColor,DisplayName,ForegroundText,ShortName,SmallLogo,Square44x44Logo");
var appMdList = (appMd ?? "").Split (',', ';', '|');
for (var i = 0; i < appMdList.Length; i ++)
{
appMdList [i] = appMdList [i].Trim ();
}
PackageReader.UpdateApplicationItems (appMdList);
}
static void Main (string [] args)
{
var currencoding = Console.OutputEncoding;
try
{
//Console.OutputEncoding = Encoding.UTF8;
if (args.Length <= 0 || args.Length >= 1 && IsHelpParam (args [0]))
{
PrintVersion ();
PrintTotalHelp ();
return;
}
var parser = new CliParsing ();
parser.Params = new HashSet<CmdParamName> (new CmdParamName [] {
new CmdParamName ("install", new string [] { "add" }),
new CmdParamName ("register", new string [] { "reg" }),
new CmdParamName ("update", new string [] { "up" }),
new CmdParamName ("stage"),
new CmdParamName ("remove", new string [] { "uninstall" }),
new CmdParamName ("read"),
new CmdParamName ("get"),
new CmdParamName ("find"),
new CmdParamName ("active", new string [] { "launch", "start", "activate" }),
new CmdParamName ("config", new string [] { "conf" }),
new CmdParamName ("version", new string [] { "ver" }),
new CmdParamName ("help", new string [] { "?", "h" }),
new CmdParamName ("developmode", new string [] { "develop" }),
new CmdParamName ("forceappshutdown", new string [] { "forceshutdown" , "appshutdown", "forcesd", "force"}),
new CmdParamName ("installallresources", new string [] {"allresources", "allres"}),
new CmdParamName ("savexml"),
new CmdParamName ("savejson"),
new CmdParamName ("fullname"),
new CmdParamName ("filter"),
new CmdParamName ("package", new string [] { "pkg" }),
new CmdParamName ("manifest", new string [] { "mani" }),
new CmdParamName ("usepri", new string [] { "pri" }),
new CmdParamName ("item"),
new CmdParamName ("set"),
new CmdParamName ("refresh"),
new CmdParamName ("show"),
new CmdParamName ("encoding", new string [] { "en", "charset", "encode" }),
new CmdParamName ("yes", new string [] {"y", "agree"})
});
RefreshConfig ();
var cmds = parser.Parse (args);
if (cmds.ParamContains ("encoding"))
{
#region help text: encoding
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_ENCODING"));
return;
}
#endregion
try
{
var c = cmds.GetFromId ("encoding");
var i = 0;
var isint = false;
Encoding en = null;
try { i = Convert.ToInt32 (c.Value); isint = true; } catch { isint = false; }
if (isint) en = Encoding.GetEncoding (i);
else en = Encoding.GetEncoding (c.Value);
Console.OutputEncoding = en;
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine (String.Format (res.Get ("PKGCLI_WARNING_ENCODING"), ex.GetType (), ex.Message));
Console.ResetColor ();
}
}
if (CliPasingUtils.ParamsContainsOr (cmds, "install", "register", "update", "stage"))
{
#region help text: install register, update, stage
PrintVersion ();
if (CliPasingUtils.ParamContains (cmds, "help"))
{
Console.WriteLine (res.Get ("PKGCLI_HELP_IRUS"));
return;
}
#endregion
var options = DeploymentOptions.None;
if (CliPasingUtils.ParamContains (cmds, "developmode")) options |= DeploymentOptions.DevelopmentMode;
if (CliPasingUtils.ParamContains (cmds, "forceappshutdown")) options |= DeploymentOptions.ForceAppShutdown;
if (CliPasingUtils.ParamContains (cmds, "installallresources")) options |= DeploymentOptions.InstallAllResources;
var totallist = new List<Tuple<int, string>> ();
var filelist = new List<string> ();
foreach (var f in cmds)
{
if (string.IsNullOrWhiteSpace (f.Id))
{
var file = f.Value;
AddFiles (filelist, file);
}
else
{
switch (f.Id)
{
case "install":
case "register":
case "update":
case "stage":
AddFiles (filelist, f.Value);
break;
}
}
}
foreach (var f in filelist) totallist.Add (new Tuple<int, string> (0, f));
if (cmds.ParamContains ("register") && cmds.ParamContains ("fullname"))
{
foreach (var f in cmds)
{
if (f.Id.NEquals ("fullname"))
{
if (string.IsNullOrWhiteSpace (f.Value))
{
totallist.Add (new Tuple<int, string> (1, f.Value));
}
}
}
}
PackageOperation ope = null;
if (cmds.ParamContains ("install")) ope = AddPackage;
else if (cmds.ParamContains ("register")) ope = RegisterPackage;
else if (cmds.ParamContains ("update")) ope = UpdatePackage;
else if (cmds.ParamContains ("stage")) ope = StagePackage;
for (int i = 0; i < totallist.Count; i++)
{
Console.WriteLine ();
var file = totallist [i];
Console.Write ("\r" + String.Format (res.Get ("PKGCLI_PROGRESS_OPERATION"), i + 1, totallist.Count));
var hr = new _I_HResult (0);
var tempope = ope;
if (file.Item1 == 1)
{
if (cmds.ParamContains ("register")) tempope = RegisterPackageByFullName;
}
hr = tempope (file.Item2, null, options, prog => {
var str = "\r" + String.Format (res.Get ("PKGCLI_PROGRESS_OPERATION_WITHPROGRESS"), i + 1, totallist.Count, prog, (int)((i + prog * 0.01) / totallist.Count * 100));
Console.Write (str);
});
if (hr.Failed)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write ("\n" + String.Format (res.Get ("PKGCLI_ERROR_IRUS_EXCEPTION"), i + 1, file.Item2, "0x" + hr.HResult.ToString ("X8"), hr.Message));
Console.ResetColor ();
}
}
Console.WriteLine ("\n" + res.Get ("PKGCLI_COMPLETE_OPERATION"));
return;
}
else if (cmds.ParamsContainsOr ("remove"))
{
#region help text: remove
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_REMOVE"));
return;
}
#endregion
var list = new List<string> ();
foreach (var c in cmds)
{
if (string.IsNullOrWhiteSpace (c.Id) || c.Id.NEquals ("remove"))
{
if (!string.IsNullOrWhiteSpace (c.Value)) list.Add (c.Value);
}
}
var agreecmd = cmds.GetFromId ("yes");
bool? agree = null;
if (agreecmd != null) agree = true;
if (agree == null)
{
if (list.Count <= 0) agree = true;
else
{
Console.Write (String.Format (res.Get ("PKGCLI_ASK_REMOVE"), list.Count));
var userinput = Console.ReadLine ();
if (userinput.NEquals ("y") || userinput.NEquals ("yes")) agree = true;
else agree = false;
}
}
if (agree == false) throw new OperationCanceledException (res.Get ("PKGCLI_ERROR_USERABORT"));
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine ();
var file = list [i];
Console.Write ("\r" + String.Format (res.Get ("PKGCLI_PROGRESS_OPERATION"), i + 1, list.Count));
var hr = RemovePackage (file, prog => {
var str = "\r" + String.Format (res.Get ("PKGCLI_PROGRESS_OPERATION_WITHPROGRESS"), i + 1, list.Count, prog, (int)((i + prog * 0.01) / list.Count * 100));
Console.Write (str);
});
if (hr.Failed)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write ("\n" + String.Format (res.Get ("PKGCLI_ERROR_IRUS_EXCEPTION"), i + 1, file, "0x" + hr.HResult.ToString ("X8"), hr.Message));
Console.ResetColor ();
}
}
Console.WriteLine ("\n" + res.Get ("PKGCLI_COMPLETE_OPERATION"));
return;
}
else if (cmds.ParamsContainsOr ("get"))
{
#region help text: get
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_GET"));
return;
}
#endregion
var filter = new HashSet<string> (new NormalizeStringComparer ());
if (cmds.ParamContains ("filter"))
{
foreach (var c in cmds)
{
if (c.Id.NEmpty () || c.Id.NEquals ("filter"))
{
var items = c.Value.Split (',', ';');
foreach (var i in items) filter.Add (i);
}
}
}
var hr = GetPackages ();
if (hr.Item1.Failed)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine (String.Format (res.Get ("PKGCLI_ERROR_EXCEPTION"), "0x" + hr.Item1.HResult.ToString ("X8"), hr.Item1.Message));
Console.ResetColor ();
return;
}
foreach (var i in hr.Item2)
{
ToFormatString (i, filter);
Console.WriteLine ();
}
Console.WriteLine ("[Statistic]");
Console.WriteLine ($"Length = {hr.Item2.Count}");
return;
}
else if (cmds.ParamsContainsOr ("find"))
{
#region help text: find
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_FIND"));
return;
}
#endregion
var names = new List<string> ();
foreach (var c in cmds)
{
if (c.Id.NEmpty ())
{
if (c.Value.NEmpty ()) continue;
names.Add (c.Value);
}
}
var filter = new HashSet<string> (new NormalizeStringComparer ());
if (cmds.ParamContains ("filter"))
{
foreach (var c in cmds)
{
if (c.Id.NEquals ("filter"))
{
var items = c.Value.Split (',', ';');
foreach (var i in items) filter.Add (i);
}
}
}
var result = new List<Tuple<string, Tuple<_I_HResult, List<PMPackageInfo>>>> ();
if (names.Count == 2)
{
result.Add (new Tuple<string, Tuple<_I_HResult, List<PMPackageInfo>>> (names [0], FindPackage (names [0], names [1])));
}
else
{
foreach (var n in names)
{
if (IsPackageFullName (n))
{
result.Add (new Tuple<string, Tuple<_I_HResult, List<PMPackageInfo>>> (n, FindPackageByFullName (n)));
}
else
{
result.Add (new Tuple<string, Tuple<_I_HResult, List<PMPackageInfo>>> (n, FindPackage (n)));
}
}
}
foreach (var r in result)
{
foreach (var l in r.Item2.Item2)
{
ToFormatString (l, filter);
Console.WriteLine ();
}
Console.WriteLine ($"[Statistic:{r.Item1}]");
Console.WriteLine ($"HResult = {"0x" + r.Item2.Item1.HResult.ToString ("X8")}");
Console.WriteLine ($"Message = {Escape.ToEscape (r.Item2.Item1.Message)}");
Console.WriteLine ($"Length = {r.Item2.Item2.Count}");
}
return;
}
else if (cmds.ParamsContainsOr ("active"))
{
#region help text: active
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_ACTIVATE"));
return;
}
#endregion
foreach (var c in cmds)
{
if (string.IsNullOrWhiteSpace (c.Id) || c.Id.NEquals ("active"))
{
if (c.Value.NEmpty ()) continue;
var i = 0;
for (i = 0; i < args.Length; i++)
{
if (args [i].NNormalize ().IndexOf (c.Value.NNormalize ()) >= 0) break;
}
var hr = ActiveApp (c.Value, BuildCommandLine (args, i + 1));
if (hr.Succeeded) Console.WriteLine (res.Get ("PKGCLI_COMPLETE_DONE"));
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write (String.Format (res.Get ("PKGCLI_ERROR_EXCEPTION"), "0x" + hr.HResult.ToString ("X8"), hr.Message));
Console.ResetColor ();
}
return;
}
}
return;
}
else if (cmds.ParamsContainsOr ("read"))
{
#region help text: read
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_READ"));
return;
}
#endregion
var filename = "";
var readtype = "";
var savename = "";
var savetype = "default";
CommandParam cmd = null;
cmd = cmds.GetFromId ("manifest");
if (cmd != null)
{
filename = cmd.Value;
readtype = "manifest";
}
cmd = cmds.GetFromId ("package");
if (cmd != null)
{
filename = cmd.Value;
readtype = "package";
}
if (string.IsNullOrWhiteSpace (filename) || !File.Exists (filename))
{
cmd = cmds.GetFromId ("");
if (cmd != null)
{
if (File.Exists (cmd.Value))
{
filename = cmd.Value;
if (string.IsNullOrWhiteSpace (readtype))
{
var ext = Path.GetExtension (cmd.Value);
if (ext.NEquals (".xml") || ext.NEquals (".appxpackage") || ext.NEquals (".msixpackage"))
readtype = "manifest";
else readtype = "package";
}
}
}
}
if (string.IsNullOrWhiteSpace (filename) || !File.Exists (filename))
{
cmd = cmds.GetFromId ("read");
if (cmd != null)
{
if (File.Exists (cmd.Value))
{
filename = cmd.Value;
if (string.IsNullOrWhiteSpace (readtype))
{
var ext = Path.GetExtension (cmd.Value);
if (ext.NEquals (".xml") || ext.NEquals (".appxpackage") || ext.NEquals (".msixpackage"))
readtype = "manifest";
else readtype = "package";
}
}
}
}
if (string.IsNullOrWhiteSpace (filename) || !File.Exists (filename)) throw new FileNotFoundException ();
cmd = cmds.GetFromId ("savexml");
if (cmd != null)
{
savename = cmd.Value;
savetype = "xml";
}
if (string.IsNullOrWhiteSpace (savename))
{
cmd = cmds.GetFromId ("savejson");
if (cmd != null)
{
savename = cmd.Value;
savetype = "json";
}
}
if (string.IsNullOrWhiteSpace (savename))
{
savetype = "ini";
}
switch (readtype)
{
default:
case "package":
{
var pr = new PackageReader (filename);
pr.UsePri = cmds.ParamContains ("usepri");
pr.EnablePri = true;
switch (savetype)
{
default:
case "default":
{
if (cmds.ParamContains ("item"))
{
object value = pr.GetItem (cmds.GetFromId ("item").Value);
if (value is string) Console.WriteLine (value as string);
else if (value is DataUtils.Version) Console.WriteLine (value.ToString ());
else Console.WriteLine (JsonConvert.SerializeObject (value, Formatting.Indented));
}
else Console.WriteLine (JsonConvert.SerializeObject (pr.GetJsonObjectForCli (), Formatting.Indented));
}
break;
case "json":
{
var res = pr.SaveJsonFileCS (savename);
if (res) Console.WriteLine ("Succeeded!");
else Console.WriteLine ("Failed.");
}
break;
case "xml":
{
var res = pr.SaveXmlFileCS (savename);
if (res) Console.WriteLine ("Succeeded!");
else Console.WriteLine ("Failed.");
}
break;
}
}
break;
case "manifest":
{
var mr = new ManifestReader (filename);
mr.UsePri = cmds.ParamContains ("usepri");
mr.EnablePri = true;
if (cmds.ParamContains ("item"))
{
object value = mr.GetItem (cmds.GetFromId ("item").Value);
if (value is string) Console.WriteLine (value as string);
else if (value is DataUtils.Version) Console.WriteLine (value.ToString ());
else Console.WriteLine (JsonConvert.SerializeObject (value, Formatting.Indented));
}
else Console.WriteLine (JsonConvert.SerializeObject (mr.GetJsonObjectForCli (), Formatting.Indented));
//Console.WriteLine (mr.BuildJsonText ());
}
break;
}
return;
}
else if (cmds.ParamsContainsOr ("config"))
{
#region help text: config
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_CONFIG"));
return;
}
#endregion
var conf = new InitConfig (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "config.ini"));
var sSettings = conf.GetSection ("Settings");
if (cmds.ParamContains ("refresh")) RefreshConfig ();
else if (cmds.ParamContains ("set"))
{
var cmd = cmds.GetFromId ("set");
var key = cmd.Value;
if (string.IsNullOrWhiteSpace (key)) throw new InvalidOperationException (Program.res.Get ("PKGCLI_ERROR_KEYSTRINGEMPTY"));
var isfind = false;
foreach (var i in configItems)
{
if (i.NEquals (key))
{
isfind = true;
break;
}
}
if (!isfind) throw new KeyNotFoundException (String.Format (Program.res.Get("PKGCLI_ERROR_CANNOTFINDKEY"), key));
var valuelist = new List<string> ();
foreach (var c in cmds)
{
if (c.Id.NEmpty ())
{
if (string.IsNullOrWhiteSpace (c.Value)) continue;
valuelist.Add (c.Value);
}
}
var res = sSettings.GetKey ($"PkgCLI:{key.Trim ()}").Set (valuelist.Join (","));
if (res) Console.WriteLine ("Succeeded!");
else Console.WriteLine ("Failed.");
}
else if (cmds.ParamContains ("show"))
{
var cmd = cmds.GetFromId ("show");
var key = cmd.Value;
if (string.IsNullOrWhiteSpace (key))
{
var dict = new Dictionary<string, string> ();
foreach (var k in configItems)
{
var cKey = sSettings.GetKey ($"PkgCLI:{k}");
dict [k] = cKey.ReadString ("(use default)");
}
Console.WriteLine (dict.FormatDictionaryAligned ("="));
return;
}
var isfind = false;
foreach (var i in configItems)
{
if (i.NEquals (key))
{
isfind = true;
break;
}
}
if (!isfind) throw new KeyNotFoundException (String.Format (Program.res.Get ("PKGCLI_ERROR_CANNOTFINDKEY"), key));
var value = sSettings.GetKey ($"PkgCLI:{key.Trim ()}").ReadString ("(use default)");
Console.WriteLine (value);
}
return;
}
else if (cmds.ParamsContainsOr ("version"))
{
#region help text: version
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_VERSION"));
return;
}
#endregion
PrintVersion ();
return;
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine ("Invalid args. Please use \"/help\" to get help.");
Console.ResetColor ();
}
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine (String.Format (res.Get ("PKGCLI_ERROR_FINALEXCEPTION"), ex.GetType (), ex.Message, ex.StackTrace));
}
finally
{
Console.ResetColor ();
Console.OutputEncoding = currencoding;
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle ("PkgCLI")]
[assembly: AssemblyDescription ("")]
[assembly: AssemblyConfiguration ("")]
[assembly: AssemblyCompany ("")]
[assembly: AssemblyProduct ("PkgCLI")]
[assembly: AssemblyCopyright ("Copyright © 2026")]
[assembly: AssemblyTrademark ("")]
[assembly: AssemblyCulture ("")]
//将 ComVisible 设置为 false 将使此程序集中的类型
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible (false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid ("8d333af6-e901-4301-b3ee-923088e81062")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion ("1.0.0.0")]
[assembly: AssemblyFileVersion ("1.0.0.0")]

112
PkgCLI/Text.cs Normal file
View File

@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace System
{
namespace Text
{
public static class Escape
{
/// <summary>按 JSON 规范对字符串进行转义。</summary>
/// <param name="input">原始字符串。</param>
/// <returns>转义后的 JSON 字符串字面量内容(不含外围双引号)。</returns>
public static string ToEscape (string input)
{
if (input == null) throw new ArgumentNullException (nameof (input));
if (input.Length == 0) return string.Empty;
StringBuilder sb = new StringBuilder (input.Length);
foreach (char c in input)
{
switch (c)
{
case '"': sb.Append ("\\\""); break;
case '\\': sb.Append ("\\\\"); break;
case '\b': sb.Append ("\\b"); break;
case '\f': sb.Append ("\\f"); break;
case '\n': sb.Append ("\\n"); break;
case '\r': sb.Append ("\\r"); break;
case '\t': sb.Append ("\\t"); break;
default:
// 控制字符 (U+0000 - U+001F) 需转义为 \uXXXX
if (c <= 0x1F)
{
sb.Append ("\\u");
sb.Append (((int)c).ToString ("X4"));
}
else
{
sb.Append (c);
}
break;
}
}
return sb.ToString ();
}
/// <summary>按 JSON 规范反转义字符串。</summary>
/// <param name="input">转义后的 JSON 字符串内容(不含外围双引号)。</param>
/// <returns>原始字符串。</returns>
/// <exception cref="FormatException">遇到非法转义序列时抛出。</exception>
public static string Unescape (string input)
{
if (input == null) throw new ArgumentNullException (nameof (input));
if (input.Length == 0) return string.Empty;
StringBuilder sb = new StringBuilder (input.Length);
int i = 0;
while (i < input.Length)
{
char c = input [i];
if (c == '\\')
{
i++;
if (i >= input.Length)
throw new FormatException ("字符串末尾包含不完整的转义序列。");
char next = input [i];
switch (next)
{
case '"': sb.Append ('"'); break;
case '\\': sb.Append ('\\'); break;
case '/': sb.Append ('/'); break; // 允许转义斜杠
case 'b': sb.Append ('\b'); break;
case 'f': sb.Append ('\f'); break;
case 'n': sb.Append ('\n'); break;
case 'r': sb.Append ('\r'); break;
case 't': sb.Append ('\t'); break;
case 'u':
i++;
if (i + 4 > input.Length)
throw new FormatException ("\\u 转义后必须跟随 4 位十六进制数字。");
string hex = input.Substring (i, 4);
int codePoint; // 先声明变量,兼容 C# 5/6
if (!int.TryParse (hex,
NumberStyles.HexNumber,
CultureInfo.InvariantCulture,
out codePoint))
{
throw new FormatException (string.Format ("无效的 Unicode 转义序列: \\u{0}", hex));
}
sb.Append ((char)codePoint);
i += 3; // 循环末尾会再加1因此这里只增加3
break;
default:
throw new FormatException (string.Format ("未识别的转义序列: \\{0}", next));
}
}
else
{
sb.Append (c);
}
i++;
}
return sb.ToString ();
}
}
}
}

4
PkgCLI/packages.config Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net40" />
</packages>

View File

@@ -142,6 +142,11 @@ namespace PriFileFormat
comStream.SetSize (value); comStream.SetSize (value);
} }
} }
public override void Close ()
{
comStream = null;
base.Close ();
}
~ComStreamWrapper () { comStream = null;} ~ComStreamWrapper () { comStream = null;}
} }
} }

View File

@@ -174,11 +174,15 @@ namespace PriFileFormat
} }
~HierarchicalSchemaSection () ~HierarchicalSchemaSection ()
{ {
Version = null; try
foreach (var item in Items) { item.Parent = null; } {
foreach (var scope in Scopes) { scope.Parent = null; } Version = null;
Scopes = null; foreach (var item in Items) { item.Parent = null; }
Items = null; foreach (var scope in Scopes) { scope.Parent = null; }
Scopes = null;
Items = null;
}
catch { }
} }
// Checksum computation is buggy for some files // Checksum computation is buggy for some files

View File

@@ -48,7 +48,6 @@
<Compile Include="ByteSpan.cs" /> <Compile Include="ByteSpan.cs" />
<Compile Include="ComStreamWrapper.cs" /> <Compile Include="ComStreamWrapper.cs" />
<Compile Include="DataItemSection.cs" /> <Compile Include="DataItemSection.cs" />
<Compile Include="DataTree.cs" />
<Compile Include="DecisionInfoSection.cs" /> <Compile Include="DecisionInfoSection.cs" />
<Compile Include="HierarchicalSchemaSection.cs" /> <Compile Include="HierarchicalSchemaSection.cs" />
<Compile Include="PriDescriptorSection.cs" /> <Compile Include="PriDescriptorSection.cs" />

View File

@@ -1,3 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup></configuration> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
</configuration>

View File

@@ -4,7 +4,7 @@
<h2>Required runtime libraries</h2> <h2>Required runtime libraries</h2>
<ul> <ul>
<li>Microsoft .NET Framework 4.5 (may be pre-installed on Windows 8.x and later)</li> <li>Microsoft .NET Framework 4.5 (may be pre-installed on Windows 8.x and later)</li>
<li>Microsoft .NET Framework 4.6</li> <li>Microsoft .NET Framework 4.6.2</li>
<li>Microsoft Visual C++ 2013 Redistributable (x86)</li> <li>Microsoft Visual C++ 2013 Redistributable (x86)</li>
<li>Microsoft Visual C++ 2015 Redistributable (x86)</li> <li>Microsoft Visual C++ 2015 Redistributable (x86)</li>
</ul> </ul>
@@ -15,9 +15,14 @@
<h2>Attention</h2> <h2>Attention</h2>
<ul> <ul>
<li><del>This program is an x86 program, not an ARM application, not cross-platform, and cannot be used on Windows RT.</del></li> <li><del>This program is an x86 program, not an ARM application, not cross-platform, and cannot be used on Windows RT.</del></li>
<li>This program uses some third-party libraries and other Github projects, and is completed using AI (ChatGTP). This project can be used for learning and communication purposes.</li> <li>The program uses some third-party libraries and other GitHub projects, and is completed with the assistance of AI (ChatGTP). This project can be used for learning and communication purposes.</li>
<li>(Important) Internet Explorer must support TLS 1.2 (requiring the use of IE's XMLHttpRequest to retrieve update information), especially IE10. You can do this by opening the "Advanced" tab in Control Panel/Internet Explorer's "Internet Options," finding "Use TLS 1.2" and checking the box, then clicking "OK" and saving. The settings will take effect the next time you open the browser.<br><img width="300" height="395" alt="屏幕截图 2025-12-08 103450" src="https://github.com/user-attachments/assets/69ee21ca-7f47-4d56-8dde-37e5704776c1" /></li> <li>(Important) Internet Explorer must support TLS 1.2 (requiring the use of IE's XMLHttpRequest to retrieve update information), especially IE10. You can do this by opening the "Advanced" tab in Control Panel/Internet Explorer's "Internet Options," finding "Use TLS 1.2" and checking the box, then clicking "OK" and saving. The settings will take effect the next time you open the browser.<br><img width="300" height="395" alt="屏幕截图 2025-12-08 103450" src="https://github.com/user-attachments/assets/69ee21ca-7f47-4d56-8dde-37e5704776c1" /></li>
</ul> </ul>
<h2>Special Thanks</h2>
<a href="https://github.com/modernw/App-Installer-For-Windows-8.x-Reset/graphs/contributors">
<!-- Made with [contrib.rocks](https://contrib.rocks). -->
<img src="https://contrib.rocks/image?repo=modernw/App-Installer-For-Windows-8.x-Reset" />
</a>
<hr> <hr>
<p>(Translated by Google Translate)</p> <p>(Translated by Google Translate)</p>
<picture> <picture>

View File

@@ -18,10 +18,6 @@ namespace Reader
static void Main () static void Main ()
{ {
Directory.SetCurrentDirectory (AppDomain.CurrentDomain.BaseDirectory); Directory.SetCurrentDirectory (AppDomain.CurrentDomain.BaseDirectory);
AppxPackage.PackageReader.AddApplicationItem ("SmallLogo");
AppxPackage.PackageReader.AddApplicationItem ("Square30x30Logo");
AppxPackage.PackageReader.AddApplicationItem ("Logo");
AppxPackage.PackageReader.AddApplicationItem ("Square44x44Logo");
DataUtils.BrowserEmulation.SetWebBrowserEmulation (); DataUtils.BrowserEmulation.SetWebBrowserEmulation ();
Application.EnableVisualStyles (); Application.EnableVisualStyles ();
Application.SetCompatibleTextRenderingDefault (false); Application.SetCompatibleTextRenderingDefault (false);

BIN
Reader/Project2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

View File

@@ -71,6 +71,9 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Project2.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net40\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
@@ -170,6 +173,9 @@
<Install>false</Install> <Install>false</Install>
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Project2.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@@ -31,14 +31,14 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ReaderShell)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ReaderShell));
this.SuspendLayout(); this.SuspendLayout();
// //
// ManagerShell // ReaderShell
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(657, 414); this.ClientSize = new System.Drawing.Size(657, 414);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Location = new System.Drawing.Point(0, 0); this.Location = new System.Drawing.Point(0, 0);
this.Name = "ManagerShell"; this.Name = "ReaderShell";
this.PageScale = 125; this.PageScale = 125;
this.Text = "Form1"; this.Text = "Form1";
this.WindowIcon = ((System.Drawing.Icon)(resources.GetObject("$this.WindowIcon"))); this.WindowIcon = ((System.Drawing.Icon)(resources.GetObject("$this.WindowIcon")));

File diff suppressed because it is too large Load Diff

View File

@@ -71,6 +71,45 @@ Original Project:
License: MIT License License: MIT License
License File: LICENSE.WinJS License File: LICENSE.WinJS
----------------------------------------------------------------------
CodeMirror
----------------------------------------------------------------------
This product includes CodeMirror, which is licensed under the MIT License.
Original Project:
Name: CodeMirror
Author: Marijn Haverbeke and contributors
Project Homepage: https://codemirror.net/
License: MIT License
License File: LICENSE.CodeMirror
----------------------------------------------------------------------
Json.NET (Newtonsoft.Json)
----------------------------------------------------------------------
This product includes Json.NET (also known as Newtonsoft.Json), which is licensed under the MIT License.
Original Project:
Name: Json.NET
Author: James Newton-King
Project Homepage: https://www.newtonsoft.com/json
License: MIT License
License File: LICENSE.Newtonsoft.Json
----------------------------------------------------------------------
SharpZipLib
----------------------------------------------------------------------
This product includes SharpZipLib, which is licensed under the MIT License.
Original Project:
Name: SharpZipLib
Author: SharpZipLib Contributors
Project Homepage: https://icsharpcode.github.io/SharpZipLib/
License: MIT License
License File: LICENSE.SharpZipLib
---------------------------------------------------------------------- ----------------------------------------------------------------------
End of notices. End of notices.

Binary file not shown.

View File

@@ -502,6 +502,7 @@ namespace Win32
using namespace System; using namespace System;
using namespace System::Runtime::InteropServices; using namespace System::Runtime::InteropServices;
[ComVisible (true)] [ComVisible (true)]
[ClassInterface (ClassInterfaceType::AutoDual)]
public ref class Key public ref class Key
{ {
private: private:
@@ -523,6 +524,7 @@ namespace Win32
); );
return CStringToMPString (res); return CStringToMPString (res);
} }
Object ^GetWithDefault (Object ^dflt) { return Get (dflt); }
Object ^Get () Object ^Get ()
{ {
auto res = GetPrivateProfileStringW ( auto res = GetPrivateProfileStringW (

View File

@@ -90,7 +90,8 @@ std::map <std::string, unsigned> g_nameToId = {
MAKENAMEIDMAP (IDS_MSGBOX_TRYAGAIN), MAKENAMEIDMAP (IDS_MSGBOX_TRYAGAIN),
MAKENAMEIDMAP (IDS_MSGBOX_CONTINUE), MAKENAMEIDMAP (IDS_MSGBOX_CONTINUE),
MAKENAMEIDMAP (IDS_PREINSTALL_SUPPOS), MAKENAMEIDMAP (IDS_PREINSTALL_SUPPOS),
MAKENAMEIDMAP (IDS_PREINSTALL_NOSUPPOS) MAKENAMEIDMAP (IDS_PREINSTALL_NOSUPPOS),
MAKENAMEIDMAP (IDS_PREINSTALL_SUITCONDITION)
}; };
#ifdef MAKENAMEIDMAP #ifdef MAKENAMEIDMAP

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,205 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{33D91B58-1981-4A3C-B4D1-86EE406CDE12}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>priformatcli</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>shlwapi.lib;version.lib;dwmapi.lib;winhttp.lib;Psapi.lib;advapi32.lib;gdi32.lib;comdlg32.lib;shell32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>shlwapi.lib;version.lib;dwmapi.lib;winhttp.lib;Psapi.lib;advapi32.lib;gdi32.lib;comdlg32.lib;shell32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="localeex.h" />
<ClInclude Include="mpstr.h" />
<ClInclude Include="nstring.h" />
<ClInclude Include="prifile.h" />
<ClInclude Include="priformatcli.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="strcmp.h" />
<ClInclude Include="syncutil.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="themeinfo.h" />
<ClInclude Include="typestrans.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="priformatcli.cpp" />
<ClCompile Include="stdafx.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="priformatcli.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PriFileFormat\PriFile.csproj">
<Project>{ef4012d4-ef08-499c-b803-177739350b2d}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -381,6 +381,7 @@ void DestroyPriFileInstance (PCSPRIFILE pFilePri)
if (!pFilePri) return; if (!pFilePri) return;
try try
{ {
#ifdef ELDER_FUNC
CreateScopedLock (g_threadlock); CreateScopedLock (g_threadlock);
auto it = g_tasklist.find (pFilePri); auto it = g_tasklist.find (pFilePri);
if (it != g_tasklist.end ()) if (it != g_tasklist.end ())
@@ -388,6 +389,7 @@ void DestroyPriFileInstance (PCSPRIFILE pFilePri)
it->second.bIsRunning = false; it->second.bIsRunning = false;
g_tasklist.erase (it); g_tasklist.erase (it);
} }
#endif
IntPtr handlePtr = IntPtr (pFilePri); IntPtr handlePtr = IntPtr (pFilePri);
System::Runtime::InteropServices::GCHandle handle = System::Runtime::InteropServices::GCHandle::FromIntPtr (handlePtr); System::Runtime::InteropServices::GCHandle handle = System::Runtime::InteropServices::GCHandle::FromIntPtr (handlePtr);
PriFileInst ^inst = safe_cast <PriFileInst ^> (handle.Target); PriFileInst ^inst = safe_cast <PriFileInst ^> (handle.Target);

View File

@@ -224,7 +224,7 @@ typedef class prifile
{ {
LPWSTR lpstr = nullptr; LPWSTR lpstr = nullptr;
reltask release ([&lpstr] () { reltask release ([&lpstr] () {
if (lpstr) free (lpstr); if (lpstr) PriFormatFreeString (lpstr);
lpstr = nullptr; lpstr = nullptr;
}); });
lpstr = GetPriResource (m_hPriFile, resname.c_str ()); lpstr = GetPriResource (m_hPriFile, resname.c_str ());

View File

@@ -127,6 +127,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" GeneratedByTileIconifier="true">
<VisualElements ShowNameOnSquare150x150Logo="on" Square150x150Logo="VisualElements\MediumIconReader.png" Square70x70Logo="VisualElements\SmallIconReader.png" ForegroundText="light" BackgroundColor="#004fe2" TileIconifierColorSelection="Default" TileIconifierCreatedWithUpgrade="true" />
</Application>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<ShortcutItemImage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OriginalBytes>iVBORw0KGgoAAAANSUhEUgAAANIAAADSCAYAAAA/mZ5CAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAnoSURBVHhe7d17qKR1HcdxsbKLS2WWsFBiEUoRGRUZUVhBEOZ1ddW8oKbrHyJUEkkKuRRhRekfUeHSvUgpoljX3dpatXUttYzoQkGEZkpRoNAfQSC7vX/zfGc958yZM7/nPJf5PWfeL/gyc+b53c6Z78f13OYcIUmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJG0whw4d2n7w4MHL4k1JdRGgzxKkEe7/lbo0LknDRjNvo/5GPR0PdYL1vxgZWobH/0JdFMOkYaF5r6GeiH4e4e0n43KrWPfW2GIqxvyZuiCmSGWjWT9ELQvQUlx7NIa2giW3VyvnYf8/UufFdKksNOdH1wrQUoz7XUxrhHWuiyVrY+7vqS2xlDRfNOONVFaAlmLOgVhiXZi/LZZqhHV+S50Vy0r9of+eTaUvM9cO0FLM3x1L1sK8C2KJ1rDmw9TpsYXUHfrtBVTjAC3FWnfE8lmYsrWa2Q3O85CBUiforxdTrQZoKdbdEVutiaGdhmgpzvSAgVIraKSX0VOdBWgp9vh8bLsqhvQWoqU41/0GSutC42ymh3oJ0FLsd1McYRkuzSVES3G2/QZK2eiZ3gO0FHt/OI4ywkNzD9EK9xoorYkGuT6aZa44x5XpPNwtLUSHccZ9BkpT0RyfjF6ZK85xS9wtGufca6C0KhrjE9EnvWPvndy8Kc7xWuqe6krZOOceykBpOXqj1s+wNZUCNK0RuXw1135VjSwb57zLQGkZ+qLzMK0VoJUYdxX1UEwtWp33SwuAnugkTE0ajXlXUg/GUkVr8n5qg6EfWgtTm43FOh+gHoili9bm+60BoxcahanLRmLdK6hfxFZF6/LjoIGgAdLnKE9HT2Tps3HY7nL2ur/auWx9flxUIHrgGBrg0aodpptno7DvZdSBOErR5vlxUgF48lf9/k5JjcE5LqXui6MVraSPm3rEc38CT/zfqzYouxE41yXU/jhq0dLHkZsj4+haBDzp6YVOHqEG8YKMnPNi6udVy5aJ8x0dx9Ui4Yl/jNpBD4x+rGcIOO9FVIk/evTSOKIWDQ359WiC9F/T27gZUqDeT91dnX6+OMcr4lhaRPTAxPeXBhioC6l91en7x94nxlG0qOiDqd+oHWCgzqd+Vp2+H+x3cmyvRUYj3Bw9MdXQAsVZt3Lmn44O3yH2eGtsqUVHM3w5+mKmoQWK855H7a1O3y7WfVdsI42a7fbojWwDDNS51I+r0zfHWqfF0lKFptgT/VHbAAO1pcn7mzD/3FhOegaN0fj7MQMM1DnU7ur0tWyNJaTl2gjS2AADdRZ1V3X6mQyRpmszSGMDDNSZ1K7q9KsyRFpbF0EaG2CgzqDurE5/mCHSbF0GaWyAgfog9SRnTi9w+c42KpbWRtVHkMZKDxRnO5Izfpyq9VvE07DOdyh/fGgR8ET3FqQx9iwqUJzlKM50A/W/0QEbYp0UoFNieS0CnvDegzTG3nMNFPs/n0p/O/e/1YmaYR0DtKh44ucWpDHO0Gug2GsTe15H/Wd0gIZYxwAtOhpg7kEa4yydBoq1X8QeH6GeGm3YEOt8lTJAKitIY5yp1UCx3rHU9dS/qx2aSeejDJCeQUMUF6Sx1LDcrDtQzD+OupH6R7ViM+k8lAHSJBqj2CCNpQbmJjtQjN9MpS9jH36VpCbS/pQB0nQ0SPFBGuOsN8exp2LMtdRjMaUR1jFAykOjDCZI4dNx9Am8LxfHmEYiQG+JZaXZhhYkzrszjj6Ba4/EsHVJAeKmty/DawMZYJDuiaNPWE+QmPMvA6TGNliQ0hcYPkal7xWlHzy9htrGtPRXLtL/9qUfQj2b+++j3sN9f5hU7aChNkyQpLkxSFILNlKQuHx53JX6tVqQeOxH3KTPJ4qzVpDSNSp9wcFAqV8rg8Tb6fXfnhOX03/lizIrSDEsjfsTNwZK/VjRfOn+prg0wtvPGl0sRG6QxnjsYW5qB4o5fkVP+cbNx+0vqZfEw8tw+ag0pgTpvHGsCeP3ZTVc209dGENXxfXxL/o9zhSDpHw0Tfq84jfU5nhoVTTW80YdOWfpvHGkCelaDJuKMXuoM2LKCA8fT23n8SdGgyoGSfmi+U6IN9fE2KOrHpufdN44zoR4X7Iw9p/Ut7j7veqRCQZJ+Wimk+JuFsa/MBptLlJY4igT0rUY1gaDpG7RZMdUvdY/g6QNhaY9NhquVwZJg0IjzXypXhr3uKrn+mOQNBg05B3RTDlh2hxje2GQNAg043ejkcZywvTyGNs5g6Ti0YjfjiZaaWaYGJO+F9M5g6Si0YTfjAaaJudfplfG2M4YJBWLBvxaNM8sOWF6dYzthEFSkWi+r0Tj5MoJ00kxtnUGScWh8XZE09SVE6bXxNhWGSQVhaar+y/RSjlhel2MbY1BUjFokm9UvdJYTphOjrGtMEgqAs027Uvc65UTpjfG2MYMkuaORrs9mqRtOWF6c4xtxCBprmiy70eDdCUnTKfE2HUzSJobGuyH0RxdywnT22LsuhgkzQXNtTMaoy85YXpHjK3NIKl3NNbuaIq+5YTp1Bhbi0FSr2iqvdEQ85ITpmtjbDaDpN7QUHdHM8zbmmHinCfGuGwGSZ3jyT+eZvpD1QfFWDNMMSabQVLnePLfnhqgTtF86/nXa9W11qo44gSu1WKQVCSar/bnUjG1FbFkNoOkItF8e6JxssXUVsSS2QySikTz7YrGyRZTWxFLZjNIKhLNl/4WUi0xtRWxZDaDpCLRfD+IxskWU1sRS2YzSCoSDTPtReSniqkTuLSJZr6pTlUr5mNOX0F6VSwrzUbzrXwdu5li6qq4fDX169HADvQRJNZJf6niubGsNBsNU/sX/WLqmhjWSaB6CtItsaSUh76p/WvnMTULw1sNVNdBYo3HqdfHklIemqb2i6DE1FqY1kqgugwS85+iTovlpHw0zm3RR9li6rowvVGgugoSc9MvP74hlpLqoYG+VLVSvpjaCPtexVK1A9V2kJizmzozlpDWhyb6QvRUtpjaCva/giWzA5XCElMnpGsxbCbG/oTaElOlZmimW6O3ssXUVnGOS1h6ZqBSWGLKhHQthk3FmH3UeTFFagdN9bnosWwxtROc53y2mBqoFJYYOiFdi2GruZc6O4ZK7aL5PlP1Wb6Y2inOdQ5bTQSqbpB47D7q9BgidYMm+1T0XLaY2osUAurB2Do7SNw/QL03LkndotluoNL3T7IrpvaKfd9N7aXujIcmpGvULurUeEiSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJKmuI474P9M94UzlaHRYAAAAAElFTkSuQmCC</OriginalBytes>
<OriginalPath>E:\Profiles\Bruce\Desktop\tilesassets\medium.scale-140.png</OriginalPath>
<Height>100</Height>
<Width>100</Width>
<X>0</X>
<Y>0</Y>
</ShortcutItemImage>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<ShortcutItemImage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OriginalBytes>iVBORw0KGgoAAAANSUhEUgAAAGIAAABiCAYAAACrpQYOAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAYaSURBVHhe7ZxrqFRVFMclSqKIqLAyMope2DuCoiJIiAj80osoKgr6Zh/K3m8lJKwsRCw0sJBQ1Ii+BPUlIoqIiiCSoAdJZIlaiGWZlff22+f8z25mzpyZPTNn3+7ss37w59yzznrctZZ35p6Z8c4wDMMwDMMwDMMwDMMwDMMwDMMwDMMIY3Jy8na0eGJiYrZMxjC4IaIrdDoQDH8u2kL8JMcfbSFDoAV4GOB8XQqmWEIrtpBA3JCyiXWB4V0nt77g+67CumILqcANJZtQHxjczQqppN8SWrGFCAbwbD6ScIi5Q+ElBllCK41dCA2vykcwHJ3L4PxQNNQSWiFHMxZCg+vzlkeHXLcq52z0vsy1QL50F0JTF+Vt1gc5F6LPdVo7yS6Epi7POqwBhrPa5eS4QAOLRpILoaGRlsEw1qALlS7DDQg9gX6QWxTIn9ZCaGbgZdD8WtS2gE64fgx6DG1VWBTIn85CaCRoGTS7Dp2vsCDwn4UeQT8pTRTIn8ZCaGBO3lIZrm1EZ8l1KIg/ilQPcdyeZ40D+cd/IRqWh/NX0Wm6XAukPYKcD6CdeZU4kH+8F8I3fht6GZ0kUxQY0uHUuB/9kk0uAuSe4DBTJccPDcf9azpOpmhQ4zB0L9qVTa8myLfP5VaZ8YQGvlAz29CT6HhdigY13Esj96Bfs0mOADn2oFlKPb7QxIfqKYPz7WgJX54gl2hQ4xBq3Yf2ZMUHhLhdaI7SjTc0Unojx4F9J3oKRX3+cFDuYOo8iP7Iq/cH3x3oFKUYf2hmn3rrCtfdc8hSjicrJBrUmUmdh9GfWfEKuL4VjfQr9rRDvfWFxt3DwDPoVIVGg3IHUudR9Fde/T+wuZ/gC+SaDnl74TCI3WgZOl0pokG5A6jzONqv2l+js3U5LVyDw8BAfkPPo7lKFRXqrKCse2s3VCcqdDzgGx4JBvQ7Wo7OVMraIL17znA/EaWHqG7g9wYa+JMn0wL1MDIMYC9agUZ+6CCHu89wd+JBv9bi9zq6SuHjiXqpDQbi7nJXonNVIhjC3WtT7r4i6M4bv9c4DPVBuGlH3lL9MKS/0Yuo70vp+ByN3MvnOxTeE/zcQ9A8haeBeosGA9uPVqFzVLIN7ItQ0Dt8+L2JLlNoWqjHKUElPQz1Y13qCX5vo0sUlibqdUpQSY/MlTD8d9Clck8b9TwlqKQHk3vbtlJyawY0PGWopNENzahgEw8F7m3HKKikh1pL0JE6bTaakWOTzs9jOJtzU71kBVuQ2T0XvIB6vrqL20H6Mk3yUeRLKGAoZ8RYhtJ7ZPZQczWHtldWOT8W+9McF8uUJjTYtoSCGMtQao/MJaj7CrqWL9176cVNXtqL6EXdy1Baj8yhNHcRjjqXoZQemUNpziJcs27wOvXUtQyl88gcSjMWwaDdJzfc4/PmWMtQKo/MoaS/CJpcmveaE2sZSuOROZS0F8Fgl6nRNmIsQyk8MoeS7iIY6HI12ZW6l6Fwj8yhpLkIBrlSDfakzmUo1CNzKOktggG6O9hg6lqGwjwyh5LWIhjcGjU2EHUsQyEemUNJZxEMbK2aGopRlyF3j8yhpLEIBrVODY1Ej2VcLJdK5OqROZTxXgQNuI+obMx7qYcey+j5IQC5eWQOZbwXwXDuQu6TElX6R42W4Jr7OxvdPs6Yietty+D8LeyVyM0jcyhpPVl3wvD2qtESbhFyCwL/DQrtitw8MoeS/CJ2q9ESQyziJYV2RW4emUNJfhE/q9ESQyziOYV2RW4emUNJfhHb1GiJzkVwPg9z5/PEog5bJUrjkTkI6lyjsDShwe/Va4nORRRgvxIN/LeaFO6ROQjqRf+vY/8rNPitei1RtYgCrs9HH8m9LwrzyNwXatytkHShyS/Vb4l+iyjA9Wr0aRbUA7l7ZK6E+p+hm+SeNjRa+ZfIQhdRgP/1vfLJzSNzCXK4G8Y75dYMaPgT9V+CawMtooC4G1HpJ02XPTJ7iPkKLdTlZkHjbX95oBWuDbWIAuJvQd8oXeUi8NmCFsjcTBjABvRdhdbLbSTI4x6yPtCpB9t76AadGoZhGIZhGIZhGIZhGIZhGIZhGIbRcGbM+BeN+q7PrwKDyAAAAABJRU5ErkJggg==</OriginalBytes>
<OriginalPath>E:\Profiles\Bruce\Desktop\tilesassets\small.scale-140.png</OriginalPath>
<Height>50</Height>
<Width>50</Width>
<X>0</X>
<Y>0</Y>
</ShortcutItemImage>

View File

@@ -34,4 +34,11 @@
<scale dpi="180">splash\manager\splash.scale-180.png</scale> <scale dpi="180">splash\manager\splash.scale-180.png</scale>
<scale dpi="default">splash\manager\splash.png</scale> <scale dpi="default">splash\manager\splash.png</scale>
</resource> </resource>
<resource id="reader">
<scale dpi="80">splash\reader\splash.scale-80.png</scale>
<scale dpi="100">splash\reader\splash.scale-100.png</scale>
<scale dpi="140">splash\reader\splash.scale-140.png</scale>
<scale dpi="180">splash\reader\splash.scale-180.png</scale>
<scale dpi="default">splash\reader\splash.png</scale>
</resource>
</resources> </resources>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -32,7 +32,7 @@
ForegroundText='light' ForegroundText='light'
BackgroundColor='#004fe2'> BackgroundColor='#004fe2'>
<DefaultTile ShowName='allLogos' /> <DefaultTile ShowName='allLogos' />
<SplashScreen Image="VisualElements\splash\manager\splash.png" <SplashScreen Image="VisualElements\splash\reader\splash.png"
BackgroundColor="#004fe2" DarkModeBackgroundColor='#002770' /> BackgroundColor="#004fe2" DarkModeBackgroundColor='#002770' />
</VisualElements> </VisualElements>
</Application> </Application>

Binary file not shown.

View File

@@ -626,11 +626,11 @@ progress.win-ring:indeterminate::-ms-fill {
@keyframes scale-visible { @keyframes scale-visible {
from { from {
transform: translateX(50px) scale(0.8); transform: translateX(50px) scale(0.8);
opacity: 0; /*opacity: 0;*/
} }
to { to {
transform: translateX(0) scale(1); transform: translateX(0) scale(1);
opacity: 1; /*opacity: 1;*/
} }
} }

View File

@@ -143,7 +143,7 @@
<!-- Loading... --> <!-- Loading... -->
<div class="content loading"> <div class="content loading">
<span class="ring-loading">&#57543;</span>&nbsp; <span class="ring-loading">&#57543;</span>&nbsp;
<span data-res-byname="IDS_PLEASEWAIT">Please wait...</span> <span data-res-byname="IDS_PLEASEWAIT"></span>
</div> </div>
<!-- Main Page --> <!-- Main Page -->
<div class="content select preinstall installing installsuccess installfailed main"> <div class="content select preinstall installing installsuccess installfailed main">

View File

@@ -35,6 +35,8 @@
try { try {
inst.sendAsync(body, encoding, function(resp) { inst.sendAsync(body, encoding, function(resp) {
if (c) c(resp); if (c) c(resp);
}, function(err) {
if (e) e(err);
}); });
} catch (ex) { if (e) e(ex); } } catch (ex) { if (e) e(ex); }
}); });

View File

@@ -442,6 +442,8 @@
createShortcutButton.setAttribute("data-app-user-model-id", item.AppUserModelID); createShortcutButton.setAttribute("data-app-user-model-id", item.AppUserModelID);
createShortcutButton.textContent = strres.get("MANAGER_APP_SHORTCUTCREATE_TITLE"); createShortcutButton.textContent = strres.get("MANAGER_APP_SHORTCUTCREATE_TITLE");
createShortcutButton.style.marginRight = "10px"; createShortcutButton.style.marginRight = "10px";
appItem.setAttribute("title", item.Id);
appItem.setAttribute("aria-label", item.DisplayName || item.ShortName);
Windows.UI.Event.Util.addEvent(launchButton, "click", function(e) { Windows.UI.Event.Util.addEvent(launchButton, "click", function(e) {
e.stopPropagation(); e.stopPropagation();
Package.manager.active(this.getAttribute("data-app-user-model-id")); Package.manager.active(this.getAttribute("data-app-user-model-id"));

View File

@@ -509,7 +509,7 @@
supportDisplay.classList.add("not-support"); supportDisplay.classList.add("not-support");
supportDisplay.classList.remove("support"); supportDisplay.classList.remove("support");
} }
supportDisplay.setAttribute("title", strutils.format("OS Min Version: {0}, Architecture: {1}", support.showOsminversionText, support.showArchitectureText)); supportDisplay.setAttribute("title", strutils.format(Bridge.Resources.byname("IDS_PREINSTALL_SUITCONDITION"), support.showOsminversionText, support.showArchitectureText));
} }
} }

View File

@@ -0,0 +1,285 @@
(function(global) {
function isString(obj) {
return typeof obj === "string" || obj instanceof String;
}
function isFunction(obj) {
return typeof obj === "function";
}
function isBool(obj) {
return typeof obj === "boolean" || obj instanceof Boolean;
}
function isNumber(obj) {
return typeof obj === "number" || obj instanceof Number;
}
function isDate(obj) {
return obj instanceof Date;
}
function isDevToolsOpen() {
if (window.__IE_DEVTOOLBAR_CONSOLE_COMMAND_LINE) {
return true; // IE10 或更早版本
}
if (window.__BROWSERTOOLS_CONSOLE) {
return true; // IE11
}
if (window.__BROWSERTOOLS_DOMEXPLORER_ADDED) {
return true; // IE11
}
return false;
}
var APIs = [
"Windows.ApplicationModel.DesignMode.designModeEnabled",
"Windows.ApplicationModel.Resources.Core.ResourceContext",
"Windows.ApplicationModel.Resources.Core.ResourceManager",
"Windows.ApplicationModel.Search.Core.SearchSuggestionManager",
"Windows.ApplicationModel.Search.SearchQueryLinguisticDetails",
"Windows.Data.Text.SemanticTextQuery",
"Windows.Foundation.Collections.CollectionChange",
"Windows.Foundation.Uri",
"Windows.Globalization.ApplicationLanguages",
"Windows.Globalization.Calendar",
"Windows.Globalization.DateTimeFormatting",
"Windows.Globalization.Language",
"Windows.Phone.UI.Input.HardwareButtons",
"Windows.Storage.ApplicationData",
"Windows.Storage.CreationCollisionOption",
"Windows.Storage.BulkAccess.FileInformationFactory",
"Windows.Storage.FileIO",
"Windows.Storage.FileProperties.ThumbnailType",
"Windows.Storage.FileProperties.ThumbnailMode",
"Windows.Storage.FileProperties.ThumbnailOptions",
"Windows.Storage.KnownFolders",
"Windows.Storage.Search.FolderDepth",
"Windows.Storage.Search.IndexerOption",
"Windows.Storage.Streams.RandomAccessStreamReference",
"Windows.UI.ApplicationSettings.SettingsEdgeLocation",
"Windows.UI.ApplicationSettings.SettingsCommand",
"Windows.UI.ApplicationSettings.SettingsPane",
"Windows.UI.Core.AnimationMetrics",
"Windows.UI.Input.EdgeGesture",
"Windows.UI.Input.EdgeGestureKind",
"Windows.UI.Input.PointerPoint",
"Windows.UI.ViewManagement.HandPreference",
"Windows.UI.ViewManagement.InputPane",
"Windows.UI.ViewManagement.UISettings",
"Windows.UI.WebUI.Core.WebUICommandBar",
"Windows.UI.WebUI.Core.WebUICommandBarBitmapIcon",
"Windows.UI.WebUI.Core.WebUICommandBarClosedDisplayMode",
"Windows.UI.WebUI.Core.WebUICommandBarIconButton",
"Windows.UI.WebUI.Core.WebUICommandBarSymbolIcon",
"Windows.UI.WebUI.WebUIApplication",
];
for (var i = 0; i < APIs.length; i++) {
var api = APIs[i];
apiNs = api.split(".");
var lastNs = global;
for (var j = 0; j < apiNs.length - 1; j++) {
var ns = apiNs[j];
if (typeof lastNs[ns] === "undefined") lastNs[ns] = {};
lastNs = lastNs[ns];
}
var leaf = apiNs[apiNs.length - 1];
if ("abcdefghijklmnopqrstuvwxyz".indexOf(leaf[0]) < 0) {
lastNs[leaf] = {};
Object.defineProperty(lastNs[leaf], "current", {
get: function() { return null; },
enumerable: true,
});
}
}
Object.defineProperty(Windows.ApplicationModel.DesignMode, "designModeEnabled", {
get: isDevToolsOpen,
enumerable: true,
});
Windows.Foundation.Collections.CollectionChange = {
reset: 0,
itemInserted: 1,
itemRemoved: 2,
itemChanged: 3
};
Windows.Foundation.Uri = function(uri) {
var inst = null;
if (arguments.length === 2) {
inst = external.Utilities.createUri2(uri, arguments[1]);
} else {
inst = external.Utilities.createUri(uri);
}
inst.jsType = this;
return inst;
};
Windows.Globalization.ApplicationLanguages = {};
Object.defineProperty(Windows.Globalization.ApplicationLanguages, "languages", {
get: function() {
try {
var list = [];
var langs = external.System.Locale.recommendLocaleNames;
langs.forEach(function(item) {
list.push(item);
});
return list;
} catch (e) {
return navigator.languages;
}
},
enumerable: true,
});
Object.defineProperty(Windows.Globalization.ApplicationLanguages, "Languages", {
get: function() {
return Windows.Globalization.ApplicationLanguages.languages;
},
enumerable: true,
});
Windows.Globalization.LanguageLayoutDirection = {
ltr: 0,
rtl: 1,
ttbLtr: 2,
ttbRtl: 3
};
Windows.Globalization.Language = function(languageTag) {
var inst = external.System.Locale.createLanguage(languageTag);
inst.jsType = this;
return inst;
};
Object.defineProperty(Windows.Globalization.Language, "currentInputMethodLanguageTag", {
get: function() {
return external.System.Locale.currentInputMethodLanguageTag;
},
enumerable: true,
});
Windows.Globalization.Language.isWellFormed = external.System.Locale.isWellFormed;
Windows.Globalization.Language.getMuiCompatibleLanguageListFromLanguageTags = external.System.Locale.getMuiCompatibleLanguageListFromLanguageTags;
Windows.Globalization.Calendar = function(args) {
var inst = null;
if (arguments.length === 0) {
inst = external.Utilities.createCalendar(args);
} else if (arguments.length === 1) {
inst = external.Utilities.createCalendar2(args);
} else if (arguments.length === 3) {
inst = external.Utilities.createCalendar3(args, arguments[1], arguments[2], arguments[3]);
} else if (arguments.length === 4) {
inst = external.Utilities.createCalendar4(args, arguments[1], arguments[2], arguments[3], arguments[4]);
}
return inst;
};
Windows.Globalization.DateTimeFormatting = {};
Windows.Globalization.DateTimeFormatting.DayFormat = {
default: 1,
none: 0
};
Windows.Globalization.DateTimeFormatting.DayOfWeekFormat = {
none: 0,
default: 1,
abberviated: 2,
full: 3
};
Windows.Globalization.DateTimeFormatting.HourFormat = {
none: 0,
default: 1
};
Windows.Globalization.DateTimeFormatting.MinuteFormat = {
none: 0,
default: 1
};
Windows.Globalization.DateTimeFormatting.MonthFormat = {
none: 0,
default: 1,
abberviated: 2,
full: 3,
numeric: 4
};
Windows.Globalization.DateTimeFormatting.SecondFormat = {
default: 1,
none: 0
};
Windows.Globalization.DateTimeFormatting.YearFormat = {
default: 1,
none: 0,
abberviated: 2,
full: 3,
};
Windows.Globalization.DateTimeFormatting.DateTimeFormatter = function() {
var args = Array.prototype.slice.call(arguments);
var inst = null;
if (args.length === 1) inst = external.Utilities.createDateTimeFormatterFromTemplate(args[0]);
else if (args.length === 2) inst = external.Utilities.CreateDateTimeFormatterFromTemplateAndLanguages(args[0], args[1]);
else if (args.length === 3) inst = external.Utilities.CreateDateTimeFormatterFromTimeEnums(args[0], args[1], args[2]);
else if (args.length === 4) inst = external.Utilities.CreateDateTimeFormatterFromDateEnums(args[0], args[1], args[2], args[3]);
else if (args.length === 5) inst = external.Utilities.CreateDateTimeFormatterFromTemplateFull(args[0], args[1], args[2], args[3], args[4]);
else if (args.length === 8) inst = external.Utilities.CreateDateTimeFormatterFromDateTimeEnums(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
else if (args.length === 11) inst = external.Utilities.CreateDateTimeFormatterFromDateTimeEnumsFull(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]);
return inst;
};
Windows.Storage.CreationCollisionOption = {
generateUniqueName: 0,
replaceExisting: 1,
failIfExists: 2,
openIfExists: 3
};
Windows.Storage.FileProperties = {
ThumbnailType: {
image: 0,
icon: 1
},
ThumbnailMode: {
pictureView: 0,
videosView: 1,
musicView: 2,
documentsView: 3,
listView: 4,
singleItem: 5
},
ThumbnailType: {
image: 0,
icon: 1
},
VideoOrientation: {
normal: 0,
rotate90: 90,
rotate180: 180,
rotate270: 270
},
PhotoOrientation: {
unspecified: 0,
normal: 1,
flipHorizontal: 2,
rotate180: 3,
flipVertical: 4,
transpose: 5,
rotate270: 6,
transverse: 7,
rotate90: 8
},
};
Windows.Storage.Search = {
FolderDepth: function() {},
IndexerOption: function() {}
};
Windows.Storage.Search.FolderDepth.deep = 1;
Windows.Storage.Search.FolderDepth.shallow = 0;
Windows.Storage.Search.IndexerOption.useIndexerWhenAvailable = 0;
Windows.Storage.Search.IndexerOption.onlyUseIndexer = 1;
Windows.Storage.Search.IndexerOption.doNotUseIndexer = 2;
Windows.Storage.Search.IndexerOption.onlyUseIndexerAndOptimizeForIndexedProperties = 3;
Windows.UI.ApplicationSettings.SettingsEdgeLocation = {
right: 0,
left: 1
};
Windows.UI.Input.EdgeGestureKind = {
touch: 0,
keyboard: 1,
mouse: 2
};
Windows.UI.ViewManagement.HandPreference = {
leftHanded: 0,
rightHanded: 1
};
Windows.UI.WebUI.Core.WebUICommandBarClosedDisplayMode = {
default: 0,
minimal: 1,
compact: 2
};
})(this);

View File

@@ -2,6 +2,7 @@
var strres = external.StringResources; var strres = external.StringResources;
var conf = external.Config.current; var conf = external.Config.current;
var set = conf.getSection("Settings"); var set = conf.getSection("Settings");
var metadata = conf.getSection("PackageReader:AppMetadatas");
function createLocalizedCompare(locale) { function createLocalizedCompare(locale) {
return function(a, b) { return function(a, b) {
@@ -15,6 +16,26 @@
}; };
} }
var pagemgr = new PageManager(); var pagemgr = new PageManager();
(function() {
var nstrutil = Bridge.NString;
var boolTrue = ["true", "1", "yes", "on", "y", "t", "zhen", "真"];
var boolFalse = ["false", "0", "no", "off", "n", "f", "jia", "假"];
global.parseBool = function(str) {
if (typeof str === "boolean") return str;
str = "" + str;
for (var i = 0; i < boolTrue.length; i++) {
if (nstrutil.equals(str, boolTrue[i])) {
return true;
}
}
for (var i = 0; i < boolFalse.length; i++) {
if (nstrutil.equals(str, boolFalse[i])) {
return false;
}
}
return null;
};
})();
OnLoad.add(function() { OnLoad.add(function() {
var mgr = Package.manager; var mgr = Package.manager;
var nstr = Bridge.NString; var nstr = Bridge.NString;
@@ -26,6 +47,7 @@
var themeColor = Bridge.UI.themeColor; var themeColor = Bridge.UI.themeColor;
pagemgr.register("reader", document.getElementById("tag-reader"), document.getElementById("page-reader")); pagemgr.register("reader", document.getElementById("tag-reader"), document.getElementById("page-reader"));
pagemgr.register("acquire", document.getElementById("tag-acquire"), document.getElementById("page-acquire")); pagemgr.register("acquire", document.getElementById("tag-acquire"), document.getElementById("page-acquire"));
pagemgr.register("search", document.getElementById("tag-search"), document.getElementById("page-search"));
pagemgr.go("reader"); pagemgr.go("reader");
}); });
})(this); })(this);

View File

@@ -57,6 +57,7 @@
try { try {
var obj = nodes[i].getAttribute('data-res-resxml'); var obj = nodes[i].getAttribute('data-res-resxml');
var strres = external.StringResources; var strres = external.StringResources;
if (!strres) strres = Bridge.External.WinJsStringRes;
if (strres) { if (strres) {
try { try {
nodes[i].textContent = strres.get(obj); nodes[i].textContent = strres.get(obj);

File diff suppressed because it is too large Load Diff

View File

@@ -32,30 +32,43 @@
.win-contentdialog .win-contentdialog-title { .win-contentdialog .win-contentdialog-title {
font-size: 20pt; font-size: 20pt;
font-weight: normal; font-weight: normal;
padding: 0 172px;
box-sizing: border-box; box-sizing: border-box;
display: block; display: block;
} }
.win-contentdialog .win-contentdialog-content { .win-contentdialog .win-contentdialog-content {
padding: 0 172px;
overflow-y: auto; overflow-y: auto;
box-sizing: border-box; box-sizing: border-box;
max-height: calc(100vh - 200px); max-height: calc(100vh - 200px);
margin: 10px 0 20px 0; margin-top: 10px;
margin-bottom: 20px;
padding-right: 24px;
font-weight: normal; font-weight: normal;
} }
.win-contentdialog .win-contentdialog-commands { .win-contentdialog .win-contentdialog-commands {
padding: 0 172px;
box-sizing: border-box; box-sizing: border-box;
display: -ms-flexbox;
display: flex; display: flex;
-ms-flex-direction: row;
flex-direction: row; flex-direction: row;
-ms-flex-wrap: wrap;
flex-wrap: wrap; flex-wrap: wrap;
-ms-flex-line-pack: start;
align-content: flex-start; align-content: flex-start;
-ms-flex-pack: end;
justify-content: flex-end; justify-content: flex-end;
} }
.win-contentdialog .win-contentdialog-title,
.win-contentdialog .win-contentdialog-content,
.win-contentdialog .win-contentdialog-commands {
width: 680px;
max-width: calc(100vw - 172px * 2);
margin-left: auto;
margin-right: auto;
}
.win-contentdialog .win-contentdialog-commands>button { .win-contentdialog .win-contentdialog-commands>button {
margin-left: 20px; margin-left: 20px;
} }
@@ -114,4 +127,11 @@
.win-ui-dark .win-contentdialog .win-contentdialog-dialog, .win-ui-dark .win-contentdialog .win-contentdialog-dialog,
.win-contentdialog.win-ui-dark .win-contentdialog-dialog { .win-contentdialog.win-ui-dark .win-contentdialog-dialog {
background-color: rgb(31, 0, 104); background-color: rgb(31, 0, 104);
}
.win-ui-dark .win-contentdialog .win-contentdialog-dialog button[type=submit],
.win-contentdialog.win-ui-dark .win-contentdialog-dialog button[type=submit],
.win-ui-dark .win-contentdialog .win-contentdialog-dialog input[type=submit],
.win-contentdialog.win-ui-dark .win-contentdialog-dialog input[type=submit] {
border-color: white;
} }

Binary file not shown.

View File

@@ -1,7 +0,0 @@
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,460 +0,0 @@
/*!
Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Build: 3.0.0.winjs.2014.10.2
Version: WinJS.3.0
*/
(function (global) {
global.strings = global.strings || {};
var appxVersion = "WinJS.3.0";
var developerPrefix = "Developer.";
if (appxVersion.indexOf(developerPrefix) === 0) {
appxVersion = appxVersion.substring(developerPrefix.length);
}
function addStrings(keyPrefix, strings) {
Object.keys(strings).forEach(function (key) {
global.strings[keyPrefix + key.replace("\\", "/")] = strings[key];
});
}
addStrings("ms-resource://"+appxVersion+"/ui/",
{
"appBarAriaLabel": "App Bar",
"appBarCommandAriaLabel": "App Bar Item",
"averageRating": "Average Rating",
"backbuttonarialabel": "Back",
"clearYourRating" : "Clear your rating",
"closeOverlay" : "Close",
"datePicker": "Date Picker",
"flipViewPanningContainerAriaLabel": "Scrolling Container",
"flyoutAriaLabel": "Flyout",
"hubViewportAriaLabel": "Scrolling Container",
"listViewViewportAriaLabel": "Scrolling Container",
"menuCommandAriaLabel": "Menu Item",
"menuAriaLabel": "Menu",
"navBarContainerViewportAriaLabel": "Scrolling Container",
"off" : "Off",
"on" : "On",
"pivotAriaLabel": "Pivot",
"pivotViewportAriaLabel": "Scrolling Container",
"searchBoxAriaLabel": "Searchbox",
"searchBoxAriaLabelInputNoPlaceHolder": "Searchbox, enter to submit query, esc to clear text",
"searchBoxAriaLabelInputPlaceHolder": "Searchbox, {0}, enter to submit query, esc to clear text",
"searchBoxAriaLabelButton": "Click to submit query",
"searchBoxAriaLabelQuery": "Suggestion: {0}",
"_searchBoxAriaLabelQuery.comment": "Suggestion: query text (example: Suggestion: contoso)",
"searchBoxAriaLabelSeparator": "Separator: {0}",
"_searchBoxAriaLabelSeparator.comment": "Separator: separator text (example: Separator: People or Separator: Apps)",
"searchBoxAriaLabelResult": "Result: {0}, {1}",
"_searchBoxAriaLabelResult.comment": "Result: text, detailed text (example: Result: contoso, www.contoso.com)",
"selectAMPM": "Select A.M P.M",
"selectDay": "Select Day",
"selectHour": "Select Hour",
"selectMinute": "Select Minute",
"selectMonth": "Select Month",
"selectYear": "Select Year",
"settingsFlyoutAriaLabel": "Settings Flyout",
"tentativeRating": "Tentative Rating",
"timePicker": "Time Picker",
"unrated": "Unrated",
"userRating": "User Rating",
// AppBar Icons follow, the format of the ui.js and ui.resjson differ for
// the AppBarIcon namespace. The remainder of the file therefore differs.
// Code point comments are the icon glyphs in the 'Segoe UI Symbol' font.
"appBarIcons\\previous": "\uE100", //  group:Media
"_appBarIcons\\previous.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\next": "\uE101", //  group:Media
"_appBarIcons\\next.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\play": "\uE102", //  group:Media
"_appBarIcons\\play.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\pause": "\uE103", //  group:Media
"_appBarIcons\\pause.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\edit": "\uE104", //  group:File
"_appBarIcons\\edit.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\save": "\uE105", //  group:File
"_appBarIcons\\save.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\clear": "\uE106", //  group:File
"_appBarIcons\\clear.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\delete": "\uE107", //  group:File
"_appBarIcons\\delete.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\remove": "\uE108", //  group:File
"_appBarIcons\\remove.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\add": "\uE109", //  group:File
"_appBarIcons\\add.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\cancel": "\uE10A", //  group:Editing
"_appBarIcons\\cancel.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\accept": "\uE10B", //  group:General
"_appBarIcons\\accept.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\more": "\uE10C", //  group:General
"_appBarIcons\\more.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\redo": "\uE10D", //  group:Editing
"_appBarIcons\\redo.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\undo": "\uE10E", //  group:Editing
"_appBarIcons\\undo.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\home": "\uE10F", //  group:General
"_appBarIcons\\home.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\up": "\uE110", //  group:General
"_appBarIcons\\up.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\forward": "\uE111", //  group:General
"_appBarIcons\\forward.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\right": "\uE111", //  group:General
"_appBarIcons\\right.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\back": "\uE112", //  group:General
"_appBarIcons\\back.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\left": "\uE112", //  group:General
"_appBarIcons\\left.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\favorite": "\uE113", //  group:Media
"_appBarIcons\\favorite.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\camera": "\uE114", //  group:System
"_appBarIcons\\camera.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\settings": "\uE115", //  group:System
"_appBarIcons\\settings.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\video": "\uE116", //  group:Media
"_appBarIcons\\video.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\sync": "\uE117", //  group:Media
"_appBarIcons\\sync.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\download": "\uE118", //  group:Media
"_appBarIcons\\download.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\mail": "\uE119", //  group:Mail and calendar
"_appBarIcons\\mail.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\find": "\uE11A", //  group:Data
"_appBarIcons\\find.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\help": "\uE11B", //  group:General
"_appBarIcons\\help.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\upload": "\uE11C", //  group:Media
"_appBarIcons\\upload.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\emoji": "\uE11D", //  group:Communications
"_appBarIcons\\emoji.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\twopage": "\uE11E", //  group:Layout
"_appBarIcons\\twopage.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\leavechat": "\uE11F", //  group:Communications
"_appBarIcons\\leavechat.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\mailforward": "\uE120", //  group:Mail and calendar
"_appBarIcons\\mailforward.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\clock": "\uE121", //  group:General
"_appBarIcons\\clock.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\send": "\uE122", //  group:Mail and calendar
"_appBarIcons\\send.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\crop": "\uE123", //  group:Editing
"_appBarIcons\\crop.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\rotatecamera": "\uE124", //  group:System
"_appBarIcons\\rotatecamera.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\people": "\uE125", //  group:Communications
"_appBarIcons\\people.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\closepane": "\uE126", //  group:Layout
"_appBarIcons\\closepane.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\openpane": "\uE127", //  group:Layout
"_appBarIcons\\openpane.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\world": "\uE128", //  group:General
"_appBarIcons\\world.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\flag": "\uE129", //  group:Mail and calendar
"_appBarIcons\\flag.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\previewlink": "\uE12A", //  group:General
"_appBarIcons\\previewlink.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\globe": "\uE12B", //  group:Communications
"_appBarIcons\\globe.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\trim": "\uE12C", //  group:Editing
"_appBarIcons\\trim.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\attachcamera": "\uE12D", //  group:System
"_appBarIcons\\attachcamera.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\zoomin": "\uE12E", //  group:Layout
"_appBarIcons\\zoomin.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\bookmarks": "\uE12F", //  group:Editing
"_appBarIcons\\bookmarks.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\document": "\uE130", //  group:File
"_appBarIcons\\document.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\protecteddocument": "\uE131", //  group:File
"_appBarIcons\\protecteddocument.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\page": "\uE132", //  group:Layout
"_appBarIcons\\page.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\bullets": "\uE133", //  group:Editing
"_appBarIcons\\bullets.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\comment": "\uE134", //  group:Communications
"_appBarIcons\\comment.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\mail2": "\uE135", //  group:Mail and calendar
"_appBarIcons\\mail2.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\contactinfo": "\uE136", //  group:Communications
"_appBarIcons\\contactinfo.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\hangup": "\uE137", //  group:Communications
"_appBarIcons\\hangup.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\viewall": "\uE138", //  group:Data
"_appBarIcons\\viewall.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\mappin": "\uE139", //  group:General
"_appBarIcons\\mappin.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\phone": "\uE13A", //  group:Communications
"_appBarIcons\\phone.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\videochat": "\uE13B", //  group:Communications
"_appBarIcons\\videochat.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\switch": "\uE13C", //  group:Communications
"_appBarIcons\\switch.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\contact": "\uE13D", //  group:Communications
"_appBarIcons\\contact.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\rename": "\uE13E", //  group:File
"_appBarIcons\\rename.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\pin": "\uE141", //  group:System
"_appBarIcons\\pin.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\musicinfo": "\uE142", //  group:Media
"_appBarIcons\\musicinfo.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\go": "\uE143", //  group:General
"_appBarIcons\\go.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\keyboard": "\uE144", //  group:System
"_appBarIcons\\keyboard.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\dockleft": "\uE145", //  group:Layout
"_appBarIcons\\dockleft.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\dockright": "\uE146", //  group:Layout
"_appBarIcons\\dockright.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\dockbottom": "\uE147", //  group:Layout
"_appBarIcons\\dockbottom.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\remote": "\uE148", //  group:System
"_appBarIcons\\remote.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\refresh": "\uE149", //  group:Data
"_appBarIcons\\refresh.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\rotate": "\uE14A", //  group:Layout
"_appBarIcons\\rotate.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\shuffle": "\uE14B", //  group:Media
"_appBarIcons\\shuffle.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\list": "\uE14C", //  group:Editing
"_appBarIcons\\list.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\shop": "\uE14D", //  group:General
"_appBarIcons\\shop.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\selectall": "\uE14E", //  group:Data
"_appBarIcons\\selectall.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\orientation": "\uE14F", //  group:Layout
"_appBarIcons\\orientation.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\import": "\uE150", //  group:Data
"_appBarIcons\\import.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\importall": "\uE151", //  group:Data
"_appBarIcons\\importall.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\browsephotos": "\uE155", //  group:Media
"_appBarIcons\\browsephotos.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\webcam": "\uE156", //  group:System
"_appBarIcons\\webcam.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\pictures": "\uE158", //  group:Media
"_appBarIcons\\pictures.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\savelocal": "\uE159", //  group:File
"_appBarIcons\\savelocal.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\caption": "\uE15A", //  group:Media
"_appBarIcons\\caption.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\stop": "\uE15B", //  group:Media
"_appBarIcons\\stop.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\showresults": "\uE15C", //  group:Data
"_appBarIcons\\showresults.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\volume": "\uE15D", //  group:Media
"_appBarIcons\\volume.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\repair": "\uE15E", //  group:System
"_appBarIcons\\repair.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\message": "\uE15F", //  group:Communications
"_appBarIcons\\message.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\page2": "\uE160", //  group:Layout
"_appBarIcons\\page2.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\calendarday": "\uE161", //  group:Mail and calendar
"_appBarIcons\\calendarday.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\calendarweek": "\uE162", //  group:Mail and calendar
"_appBarIcons\\calendarweek.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\calendar": "\uE163", //  group:Mail and calendar
"_appBarIcons\\calendar.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\characters": "\uE164", //  group:Editing
"_appBarIcons\\characters.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\mailreplyall": "\uE165", //  group:Mail and calendar
"_appBarIcons\\mailreplyall.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\read": "\uE166", //  group:Mail and calendar
"_appBarIcons\\read.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\link": "\uE167", //  group:Communications
"_appBarIcons\\link.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\accounts": "\uE168", //  group:Communications
"_appBarIcons\\accounts.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\showbcc": "\uE169", //  group:Mail and calendar
"_appBarIcons\\showbcc.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\hidebcc": "\uE16A", //  group:Mail and calendar
"_appBarIcons\\hidebcc.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\cut": "\uE16B", //  group:Editing
"_appBarIcons\\cut.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\attach": "\uE16C", //  group:Mail and calendar
"_appBarIcons\\attach.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\paste": "\uE16D", //  group:Editing
"_appBarIcons\\paste.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\filter": "\uE16E", //  group:Data
"_appBarIcons\\filter.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\copy": "\uE16F", //  group:Editing
"_appBarIcons\\copy.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\emoji2": "\uE170", //  group:Mail and calendar
"_appBarIcons\\emoji2.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\important": "\uE171", //  group:Mail and calendar
"_appBarIcons\\important.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\mailreply": "\uE172", //  group:Mail and calendar
"_appBarIcons\\mailreply.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\slideshow": "\uE173", //  group:Media
"_appBarIcons\\slideshow.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\sort": "\uE174", //  group:Data
"_appBarIcons\\sort.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\manage": "\uE178", //  group:System
"_appBarIcons\\manage.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\allapps": "\uE179", //  group:System
"_appBarIcons\\allapps.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\disconnectdrive": "\uE17A", //  group:System
"_appBarIcons\\disconnectdrive.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\mapdrive": "\uE17B", //  group:System
"_appBarIcons\\mapdrive.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\newwindow": "\uE17C", //  group:System
"_appBarIcons\\newwindow.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\openwith": "\uE17D", //  group:System
"_appBarIcons\\openwith.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\contactpresence": "\uE181", //  group:Communications
"_appBarIcons\\contactpresence.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\priority": "\uE182", //  group:Mail and calendar
"_appBarIcons\\priority.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\uploadskydrive": "\uE183", //  group:File
"_appBarIcons\\uploadskydrive.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\gototoday": "\uE184", //  group:Mail and calendar
"_appBarIcons\\gototoday.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\font": "\uE185", //  group:Editing
"_appBarIcons\\font.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\fontcolor": "\uE186", //  group:Editing
"_appBarIcons\\fontcolor.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\contact2": "\uE187", //  group:Communications
"_appBarIcons\\contact2.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\folder": "\uE188", //  group:File
"_appBarIcons\\folder.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\audio": "\uE189", //  group:Media
"_appBarIcons\\audio.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\placeholder": "\uE18A", //  group:General
"_appBarIcons\\placeholder.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\view": "\uE18B", //  group:Layout
"_appBarIcons\\view.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\setlockscreen": "\uE18C", //  group:System
"_appBarIcons\\setlockscreen.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\settile": "\uE18D", //  group:System
"_appBarIcons\\settile.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\cc": "\uE190", //  group:Media
"_appBarIcons\\cc.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\stopslideshow": "\uE191", //  group:Media
"_appBarIcons\\stopslideshow.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\permissions": "\uE192", //  group:System
"_appBarIcons\\permissions.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\highlight": "\uE193", //  group:Editing
"_appBarIcons\\highlight.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\disableupdates": "\uE194", //  group:System
"_appBarIcons\\disableupdates.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\unfavorite": "\uE195", //  group:Media
"_appBarIcons\\unfavorite.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\unpin": "\uE196", //  group:System
"_appBarIcons\\unpin.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\openlocal": "\uE197", //  group:File
"_appBarIcons\\openlocal.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\mute": "\uE198", //  group:Media
"_appBarIcons\\mute.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\italic": "\uE199", //  group:Editing
"_appBarIcons\\italic.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\underline": "\uE19A", //  group:Editing
"_appBarIcons\\underline.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\bold": "\uE19B", //  group:Editing
"_appBarIcons\\bold.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\movetofolder": "\uE19C", //  group:File
"_appBarIcons\\movetofolder.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\likedislike": "\uE19D", //  group:Data
"_appBarIcons\\likedislike.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\dislike": "\uE19E", //  group:Data
"_appBarIcons\\dislike.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\like": "\uE19F", //  group:Data
"_appBarIcons\\like.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\alignright": "\uE1A0", //  group:Editing
"_appBarIcons\\alignright.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\aligncenter": "\uE1A1", //  group:Editing
"_appBarIcons\\aligncenter.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\alignleft": "\uE1A2", //  group:Editing
"_appBarIcons\\alignleft.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\zoom": "\uE1A3", //  group:Layout
"_appBarIcons\\zoom.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\zoomout": "\uE1A4", //  group:Layout
"_appBarIcons\\zoomout.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\openfile": "\uE1A5", //  group:File
"_appBarIcons\\openfile.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\otheruser": "\uE1A6", //  group:System
"_appBarIcons\\otheruser.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\admin": "\uE1A7", //  group:System
"_appBarIcons\\admin.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\street": "\uE1C3", //  group:General
"_appBarIcons\\street.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\map": "\uE1C4", //  group:General
"_appBarIcons\\map.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\clearselection": "\uE1C5", //  group:Data
"_appBarIcons\\clearselection.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\fontdecrease": "\uE1C6", //  group:Editing
"_appBarIcons\\fontdecrease.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\fontincrease": "\uE1C7", //  group:Editing
"_appBarIcons\\fontincrease.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\fontsize": "\uE1C8", //  group:Editing
"_appBarIcons\\fontsize.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\cellphone": "\uE1C9", //  group:Communications
"_appBarIcons\\cellphone.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\reshare": "\uE1CA", //  group:Communications
"_appBarIcons\\reshare.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\tag": "\uE1CB", //  group:Data
"_appBarIcons\\tag.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\repeatone": "\uE1CC", //  group:Media
"_appBarIcons\\repeatone.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\repeatall": "\uE1CD", //  group:Media
"_appBarIcons\\repeatall.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\outlinestar": "\uE1CE", //  group:Data
"_appBarIcons\\outlinestar.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\solidstar": "\uE1CF", //  group:Data
"_appBarIcons\\solidstar.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\calculator": "\uE1D0", //  group:General
"_appBarIcons\\calculator.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\directions": "\uE1D1", //  group:General
"_appBarIcons\\directions.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\target": "\uE1D2", //  group:General
"_appBarIcons\\target.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\library": "\uE1D3", //  group:Media
"_appBarIcons\\library.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\phonebook": "\uE1D4", //  group:Communications
"_appBarIcons\\phonebook.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\memo": "\uE1D5", //  group:Communications
"_appBarIcons\\memo.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\microphone": "\uE1D6", //  group:System
"_appBarIcons\\microphone.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\postupdate": "\uE1D7", //  group:Communications
"_appBarIcons\\postupdate.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\backtowindow": "\uE1D8", //  group:Layout
"_appBarIcons\\backtowindow.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\fullscreen": "\uE1D9", //  group:Layout
"_appBarIcons\\fullscreen.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\newfolder": "\uE1DA", //  group:File
"_appBarIcons\\newfolder.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\calendarreply": "\uE1DB", //  group:Mail and calendar
"_appBarIcons\\calendarreply.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\unsyncfolder": "\uE1DD", //  group:File
"_appBarIcons\\unsyncfolder.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\reporthacked": "\uE1DE", //  group:Communications
"_appBarIcons\\reporthacked.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\syncfolder": "\uE1DF", //  group:File
"_appBarIcons\\syncfolder.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\blockcontact": "\uE1E0", //  group:Communications
"_appBarIcons\\blockcontact.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\switchapps": "\uE1E1", //  group:System
"_appBarIcons\\switchapps.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\addfriend": "\uE1E2", //  group:Communications
"_appBarIcons\\addfriend.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\touchpointer": "\uE1E3", //  group:System
"_appBarIcons\\touchpointer.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\gotostart": "\uE1E4", //  group:System
"_appBarIcons\\gotostart.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\zerobars": "\uE1E5", //  group:System
"_appBarIcons\\zerobars.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\onebar": "\uE1E6", //  group:System
"_appBarIcons\\onebar.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\twobars": "\uE1E7", //  group:System
"_appBarIcons\\twobars.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\threebars": "\uE1E8", //  group:System
"_appBarIcons\\threebars.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\fourbars": "\uE1E9", //  group:System
"_appBarIcons\\fourbars.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\scan": "\uE294", //  group:General
"_appBarIcons\\scan.comment": "{Locked:qps-ploc,qps-plocm}",
"appBarIcons\\preview": "\uE295", //  group:General
"_appBarIcons\\preview.comment": "{Locked:qps-ploc,qps-plocm}"
}
);
}(this));

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -8,10 +8,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="js/module.js"></script> <script type="text/javascript" src="js/module.js"></script>
<script type="text/javascript" src="js/polyfill-ie.js"></script> <script type="text/javascript" src="js/polyfill-ie.js"></script>
<script type="text/javascript" src="js/polyfill-winrt.js"></script>
<link rel="stylesheet" href="libs/winjs/1.0/css/ui-light.css" id="winjs-style-1"> <link rel="stylesheet" href="libs/winjs/1.0/css/ui-light.css" id="winjs-style-1">
<link rel="stylesheet" href="libs/winjs/2.0/css/ui-light.css" id="winjs-style"> <link rel="stylesheet" href="libs/winjs/2.0/css/ui-light.css" id="winjs-style">
<script type="text/javascript" src="libs/winjs/1.0/js/base.js"></script> <script type="text/javascript" src="libs/winjs/1.0/js/base.js"></script>
<script type="text/javascript" src="libs/winjs/1.0/js/ui.js"></script> <script type="text/javascript" src="libs/winjs/1.0/js/ui.js"></script>
<script type="text/javascript" src="libs/winjs/1.0/js/en-us/base.strings.js"></script>
<script type="text/javascript" src="libs/winjs/1.0/js/en-us/ui.strings.js"></script>
<script type="text/javascript" src="js/color.js"></script> <script type="text/javascript" src="js/color.js"></script>
<script type="text/javascript" src="js/promise.js"></script> <script type="text/javascript" src="js/promise.js"></script>
<script type="text/javascript" src="js/bridge.js"></script> <script type="text/javascript" src="js/bridge.js"></script>
@@ -44,11 +47,17 @@
<script type="text/javascript" src="js/rdinit.js"></script> <script type="text/javascript" src="js/rdinit.js"></script>
<style> <style>
.itemrow { .itemrow {
display: -ms-flexbox;
display: flex; display: flex;
-ms-flex-direction: row;
flex-direction: row; flex-direction: row;
-ms-flex-wrap: wrap;
flex-wrap: wrap; flex-wrap: wrap;
-ms-flex-line-pack: center;
align-content: center; align-content: center;
-ms-flex-pack: start;
justify-content: flex-start; justify-content: flex-start;
-ms-flex-align: center;
align-items: center; align-items: center;
margin: 10px 0; margin: 10px 0;
} }
@@ -60,13 +69,13 @@
<div class="page full guide fold"> <div class="page full guide fold">
<main class="main"> <main class="main">
<div id="page-reader" style="display: none;" class="ispage padding"> <div id="page-reader" style="display: none;" class="ispage padding">
<h2>读取</h2> <h2 data-res-resxml="READER_READER_TITLE"></h2>
<p>请选择一个包,获取其信息。</p> <p data-res-resxml="READER_READER_DESC"></p>
<div> <div>
<label for="read-pkgpath">文件路径</label> <label for="read-pkgpath" data-res-resxml="READER_READER_FILEPATH"></label>
<div class="itemrow"> <div class="itemrow">
<input type="text" id="read-pkgpath" style="margin-right: 10px;"> <input type="text" id="read-pkgpath" style="margin-right: 10px;">
<button id="read-browse">浏览</button> <button id="read-browse" data-res-resxml="READER_READER_BROWSER"></button>
</div> </div>
<script> <script>
(function() { (function() {
@@ -76,7 +85,9 @@
readBrowse.onclick = function() { readBrowse.onclick = function() {
var explorer = external.Storage.Explorer; var explorer = external.Storage.Explorer;
explorer.file( explorer.file(
"{appxpkg}|*.appx;*.appxbundle;*.msix;*.msixbundle|{allfiles}|*.*", "{appxpkg}|*.appx;*.appxbundle;*.msix;*.msixbundle|{allfiles}|*.*"
.replace("{appxpkg}", stringRes("READER_READER_APPXFILE"))
.replace("{allfiles}", stringRes("READER_READER_ALLFILES")),
lastDir, lastDir,
function(result) { function(result) {
if (!result) return; if (!result) return;
@@ -90,20 +101,127 @@
</div> </div>
<div class="itemrow"> <div class="itemrow">
<input type="checkbox" id="read-usepri" style="margin-left: 0;"> <input type="checkbox" id="read-usepri" style="margin-left: 0;">
<label for="read-usepri">需要解析 PRI 资源文件</label> <label for="read-usepri" data-res-resxml="READER_READER_USEPRI"></label>
</div> </div>
<style> <style>
.part-read-button { .part-read-button {
margin-bottom: 5px; margin-bottom: 5px;
} }
</style> </style>
<button id="read-btn" class="part-read-button">读取</button> <button id="read-btn" class="part-read-button" data-res-resxml="READER_READER_READ"></button>
<button id="read-result-save" class="part-read-button">将读取结果保存为文件</button> <button id="read-result-save" class="part-read-button" data-res-resxml="READER_READER_SAVEFILE"></button>
<button id="read-result-xml" class="part-read-button">保存为 XML 文件</button> <button id="read-result-xml" class="part-read-button" data-res-resxml="READER_READER_SAVEXML"></button>
<button id="read-result-json" class="part-read-button">保存为 JSON 文件</button> <button id="read-result-json" class="part-read-button" data-res-resxml="READER_READER_SAVEJSON"></button>
<button id="read-refreshmetadata" class="part-read-button" data-res-resxml="READER_READER_REFRESHMETADATA"></button>
<script>
(function(global) {
var conf = external.Config.current;
var set = conf.getSection("Settings");
var metadata = conf.getSection("PackageReader:AppMetadatas");
var reader = Package.reader;
var appitems = [
"Id",
"StartPage",
"EntryPoint",
"Executable",
"BackgroundColor",
"DisplayName",
"Description",
"ShortName",
"ForegroundText",
"SmallLogo",
"Square30x30Logo",
"Square44x44Logo",
"Square70x70Logo",
"Square71x71Logo",
"Logo",
"Square150x150Logo",
"WideLogo",
"Wide310x150Logo",
"Square310x310Logo",
"Tall150x310Logo",
"LockScreenLogo",
"LockScreenNotification",
"DefaultSize",
"AppListEntry",
"VisualGroup",
"MinWidth",
];
var defaultItems = [
"Id",
"DisplayName",
"BackgroundColor",
"ForegroundText",
"ShortName",
"Square44x44Logo",
"SmallLogo"
];
function refreshMetadataItems() {
var metaitemlist = [];
for (var i = 0; i < appitems.length; i++) {
var item = appitems[i];
var isenable = metadata.getKey(item).value;
if (isenable === null || isenable === void 0 || isenable === "") {
isenable = defaultItems.indexOf(item) >= 0;
}
if (parseBool(isenable) == true) {
metaitemlist.push(item);
}
}
reader.updateApplicationReadItems(metaitemlist);
}
refreshMetadataItems();
var refreshMetadataButton = document.getElementById("read-refreshmetadata");
refreshMetadataButton.onclick = function() {
refreshMetadataItems();
var container = document.createElement("div");
document.body.appendChild(container);
var contentdlg = new WinJS.UI.ContentDialog(container);
contentdlg.title = stringRes("READER_READER_HASREFRESHMETADATA");
var content = document.createElement("div");
content.style.width = "100%";
var stylenode = document.createElement("style");
stylenode.textContent = "table { border-collapse: collapse; max-width: 100%; -ms-user-select: element; } th, td { border: 1px solid white; padding: 5px; }";
content.appendChild(stylenode);
var table = document.createElement("table");
var thead = document.createElement("thead");
var htr = document.createElement("tr");
var thitem = document.createElement("th");
var thdesc = document.createElement("th");
thitem.textContent = stringRes("READER_SETTINGS_APPITEMS_ITEM");
thdesc.textContent = stringRes("READER_SETTINGS_APPITEMS_DESCRIPTION");
var tbody = document.createElement("tbody");
htr.appendChild(thitem);
htr.appendChild(thdesc);
thead.appendChild(htr);
table.appendChild(thead);
table.appendChild(tbody);
content.appendChild(table);
contentdlg.content = content;
contentdlg.commands.push(new WinJS.UI.ContentDialogCommand(
getPublicRes(800)
));
var items = Package.reader.getApplicationReadItems();
items.forEach(function(item) {
var tr = document.createElement("tr");
var tditem = document.createElement("td");
var tddesc = document.createElement("td");
tditem.textContent = item;
tddesc.textContent = stringRes("APPMETADATA_" + item.toUpperCase());
tr.appendChild(tditem);
tr.appendChild(tddesc);
tbody.appendChild(tr);
});
contentdlg.showAsync().then(function() {
contentdlg.dispose();
});
};
})(this);
</script>
<br> <br>
<progress id="read-loading" style="display: none;"></progress> <progress id="read-loading" style="display: none;"></progress>
<p style="margin-bottom: 2px; margin-top: 5px;">读取结果:</p> <p style="margin-bottom: 2px; margin-top: 5px;" data-res-resxml="READER_READER_RESULT"></p>
<iframe id="read-result" width="100%" frameborder="0" src="report.html"></iframe> <iframe id="read-result" width="100%" frameborder="0" src="report.html"></iframe>
<script> <script>
(function() { (function() {
@@ -112,7 +230,7 @@
function readResultResizeEvent(e) { function readResultResizeEvent(e) {
var parent = readResult.parentElement.parentElement; var parent = readResult.parentElement.parentElement;
var newHeight = parent.getBoundingClientRect().height - readResult.getBoundingClientRect().top - 24; var newHeight = parent.getBoundingClientRect().height - readResult.getBoundingClientRect().top - 60;
//console.log(e, parent.getBoundingClientRect().height, readResult.getBoundingClientRect().top, newHeight); //console.log(e, parent.getBoundingClientRect().height, readResult.getBoundingClientRect().top, newHeight);
readResult.style.height = parseInt(newHeight) + "px"; readResult.style.height = parseInt(newHeight) + "px";
} }
@@ -123,6 +241,8 @@
</script> </script>
<script> <script>
(function(global) { (function(global) {
var conf = external.Config.current;
var set = conf.getSection("Settings");
var readBtn = document.getElementById("read-btn"); var readBtn = document.getElementById("read-btn");
var readResult = document.getElementById("read-result"); var readResult = document.getElementById("read-result");
var readPkgpath = document.getElementById("read-pkgpath"); var readPkgpath = document.getElementById("read-pkgpath");
@@ -132,6 +252,7 @@
var readSave = document.getElementById("read-result-save"); var readSave = document.getElementById("read-result-save");
var readToXml = document.getElementById("read-result-xml"); var readToXml = document.getElementById("read-result-xml");
var readToJson = document.getElementById("read-result-json"); var readToJson = document.getElementById("read-result-json");
readUsepri.checked = set.getKey("PackageReader:DefaultParsingPriFile").readBool();
readResult.style.display = "none"; readResult.style.display = "none";
readBtn.onclick = function() { readBtn.onclick = function() {
var self = this; var self = this;
@@ -160,7 +281,7 @@
onCompleted(); onCompleted();
readResult.contentWindow.setReport({ readResult.contentWindow.setReport({
status: false, status: false,
message: "请选择一个有效文件" message: stringRes("READER_READER_PLEASESELECT")
}); });
self.disabled = false; self.disabled = false;
return; return;
@@ -187,7 +308,7 @@
progress.classList.add("win-ring"); progress.classList.add("win-ring");
progress.style.color = "white"; progress.style.color = "white";
var span = document.createElement("span"); var span = document.createElement("span");
span.textContent = "正在保存文件"; span.textContent = stringRes("READER_READER_SAVINGHTML");
progress.style.marginRight = "10px"; progress.style.marginRight = "10px";
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;") cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
cont.appendChild(progress); cont.appendChild(progress);
@@ -199,7 +320,7 @@
return dlg.show().then(function(id) { return dlg.show().then(function(id) {
return new Promise(function(c, e) { return new Promise(function(c, e) {
external.Storage.save( external.Storage.save(
"{htmlfile}|*.html;*.htm", "{htmlfile}|*.html;*.htm".replace("{htmlfile}", stringRes("READER_READER_HTMLFILE")),
lastDir, lastDir,
"report-" + new Date().getTime(), "report-" + new Date().getTime(),
c c
@@ -216,7 +337,7 @@
}); });
}).then(null, function(err) { }).then(null, function(err) {
dlg.hide().then(function() { dlg.hide().then(function() {
dlg.title = "保存时发生问题"; dlg.title = stringRes("READER_READER_SAVEERR");
dlg.content = err.message || err; dlg.content = err.message || err;
dlg.commands.push(new WinJS.UI.ContentDialogCommand( dlg.commands.push(new WinJS.UI.ContentDialogCommand(
getPublicRes(800) getPublicRes(800)
@@ -238,7 +359,7 @@
progress.classList.add("win-ring"); progress.classList.add("win-ring");
progress.style.color = "white"; progress.style.color = "white";
var span = document.createElement("span"); var span = document.createElement("span");
span.textContent = "正在生成 JSON 文件,请稍候... \n这可能需要比较长的时间。"; span.textContent = stringRes("READER_READER_SAVEINGJSON");
progress.style.marginRight = "10px"; progress.style.marginRight = "10px";
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;") cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
cont.appendChild(progress); cont.appendChild(progress);
@@ -250,7 +371,7 @@
return dlg.show().then(function(id) { return dlg.show().then(function(id) {
return new Promise(function(c, e) { return new Promise(function(c, e) {
external.Storage.save( external.Storage.save(
"{jsonzipfile}|*.zip", "{jsonzipfile}|*.zip".replace("{jsonzipfile}", stringRes("READER_READER_JSONFILE")),
lastDir, lastDir,
"report-" + new Date().getTime(), "report-" + new Date().getTime(),
c c
@@ -259,7 +380,7 @@
}).then(function(filepath) { }).then(function(filepath) {
return new Promise(function(c, e) { return new Promise(function(c, e) {
if (!readPkgpath.value) { if (!readPkgpath.value) {
e(new Error("请选择一个有效文件")); e(new Error(stringRes("READER_READER_PLEASESELECT")));
return; return;
} }
try { try {
@@ -284,7 +405,7 @@
}); });
}).then(null, function(err) { }).then(null, function(err) {
dlg.hide().then(function() { dlg.hide().then(function() {
dlg.title = "保存时发生问题"; dlg.title = stringRes("READER_READER_SAVEERR");
dlg.content = err.message || err; dlg.content = err.message || err;
dlg.commands.push(new WinJS.UI.ContentDialogCommand( dlg.commands.push(new WinJS.UI.ContentDialogCommand(
getPublicRes(800) getPublicRes(800)
@@ -307,7 +428,7 @@
progress.classList.add("win-ring"); progress.classList.add("win-ring");
progress.style.color = "white"; progress.style.color = "white";
var span = document.createElement("span"); var span = document.createElement("span");
span.textContent = "正在生成 XML 文件,请稍候... \n这可能需要比较长的时间。"; span.textContent = stringRes("READER_READER_SAVEINGXML");
progress.style.marginRight = "10px"; progress.style.marginRight = "10px";
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;") cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
cont.appendChild(progress); cont.appendChild(progress);
@@ -319,7 +440,7 @@
return dlg.show().then(function(id) { return dlg.show().then(function(id) {
return new Promise(function(c, e) { return new Promise(function(c, e) {
external.Storage.save( external.Storage.save(
"{xmlzipfile}|*.zip", "{xmlzipfile}|*.zip".replace("{xmlzipfile}", stringRes("READER_READER_XMLFILE")),
lastDir, lastDir,
"report-" + new Date().getTime(), "report-" + new Date().getTime(),
c c
@@ -329,7 +450,7 @@
return new Promise(function(c, e) { return new Promise(function(c, e) {
try { try {
if (!readPkgpath.value) { if (!readPkgpath.value) {
e(new Error("请选择一个有效文件")); e(new Error(stringRes("READER_READER_PLEASESELECT")));
return; return;
} }
var pkg = Package.reader.package(readPkgpath.value); var pkg = Package.reader.package(readPkgpath.value);
@@ -353,7 +474,7 @@
}); });
}).then(null, function(err) { }).then(null, function(err) {
dlg.hide().then(function() { dlg.hide().then(function() {
dlg.title = "保存时发生问题"; dlg.title = stringRes("READER_READER_SAVEERR");
dlg.content = err.message || err; dlg.content = err.message || err;
dlg.commands.push(new WinJS.UI.ContentDialogCommand( dlg.commands.push(new WinJS.UI.ContentDialogCommand(
getPublicRes(800) getPublicRes(800)
@@ -369,43 +490,48 @@
</script> </script>
</div> </div>
<div id="page-acquire" style="display: none;" class="ispage padding"> <div id="page-acquire" style="display: none;" class="ispage padding">
<h2>获取</h2> <h2 data-res-resxml="READER_ACQUIRE_TITLE"></h2>
<div id="acquire-forbidden" style="width: 100%;"> <div id="acquire-forbidden" style="width: 100%;">
<p>由于来自 store.rg-adguard.net 的限制,现在暂时无法实现对包的获取。请自行打开下面 URL 进行访问。</p> <p data-res-resxml="READER_ACQUIRE_PROHIBIT"></p>
<a onclick="external.Process.open ('https://store.rg-adguard.net')">store.rg-adguard.net</a> <a onclick="external.Process.open ('https://store.rg-adguard.net')">store.rg-adguard.net</a>
</div> </div>
<div id="acquire-enable" style="width: 100%;"> <div id="acquire-enable" style="width: 100%;">
<p>请在下面的输入框中输入要查询的内容,设置好参数后将进行查询。</p> <p data-res-resxml="READER_ACQUIRE_DESC"></p>
<div> <div>
<div> <div>
<input type="text" id="acquire-input"> <input type="text" id="acquire-input">
<select id="acquire-valuetype" name="type"> <select id="acquire-valuetype" name="type" value="url">
<option value="url">分享链接</option> <option value="url" data-res-resxml="READER_ACQUIRE_SHAREDURL"></option>
<option value="ProductId">产品 ID</option> <option value="ProductId" data-res-resxml="READER_ACQUIRE_PRODUCTID"></option>
<option value="PackageFamilyName">包系列名</option> <option value="PackageFamilyName" data-res-resxml="READER_ACQUIRE_PFN"></option>
<option value="CategoryId">类别 ID</option> <option value="CategoryId" data-res-resxml="READER_ACQUIRE_CATEGORYID"></option>
</select> </select>
<select id="acquire-channel" name="ring"> <select id="acquire-channel" name="ring" value="RP">
<option title="Windows Insider Fast" value="WIF">快速</option> <option title="Windows Insider Fast" value="WIF" data-res-resxml="READER_ACQUIRE_WIF"></option>
<option title="Windows Insider Slow" value="WIS">慢速</option> <option title="Windows Insider Slow" value="WIS" data-res-resxml="READER_ACQUIRE_WIS"></option>
<option title="Release Preview" value="RP" selected>发布预览</option> <option title="Release Preview" value="RP" data-res-resxml="READER_ACQUIRE_RP"></option>
<option title="Default OS" value="Retail">正式</option> <option title="Default OS" value="Retail" data-res-resxml="READER_ACQUIRE_RETAIL"></option>
</select> </select>
</div> </div>
<div> <div>
<div class="itemrow"> <div class="itemrow">
<input type="checkbox" id="acquire-smartquery" style="margin-left: 0px;"> <input type="checkbox" id="acquire-smartquery" style="margin-left: 0px;">
<label for="acquire-smartquery">自动查询</label> <label for="acquire-smartquery" data-res-resxml="READER_ACQUIRE_SMARTQUERY"></label>
</div> </div>
<button id="acquire-query">查询</button> <button id="acquire-query" data-res-resxml="READER_ACQUIRE_QUERY"></button>
</div> </div>
</div> </div>
<style> <style>
.acquire-item { .acquire-item {
display: -ms-flexbox;
display: flex; display: flex;
-ms-flex-direction: column;
flex-direction: column; flex-direction: column;
-ms-flex-wrap: none;
flex-wrap: nowrap; flex-wrap: nowrap;
-ms-flex-line-pack: start;
align-content: flex-start; align-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start; justify-content: flex-start;
width: 100%; width: 100%;
margin: 5px 0; margin: 5px 0;
@@ -431,11 +557,17 @@
font-size: 10pt; font-size: 10pt;
line-height: 1.2em; line-height: 1.2em;
font-weight: normal; font-weight: normal;
display: -ms-flexbox;
display: flex; display: flex;
-ms-flex-direction: row;
flex-direction: row; flex-direction: row;
-ms-flex-wrap: wrap;
flex-wrap: wrap; flex-wrap: wrap;
-ms-flex-line-pack: center;
align-content: center; align-content: center;
-ms-flex-pack: justify;
justify-content: space-between; justify-content: space-between;
-ms-flex-align: center;
align-items: center; align-items: center;
margin-top: 3px; margin-top: 3px;
margin-bottom: 3px; margin-bottom: 3px;
@@ -443,13 +575,13 @@
.acquire-item .medium div { .acquire-item .medium div {
text-align: center; text-align: center;
-ms-flex: 0 0 auto;
flex: 0 0 auto; flex: 0 0 auto;
} }
.acquire-item .medium #ext { .acquire-item .medium #ext {
text-align: left; text-align: left;
max-width: 100px; max-width: 100px;
/*min-width: 97px;*/
} }
.acquire-item .medium div:nth-child(1), .acquire-item .medium div:nth-child(1),
@@ -467,15 +599,22 @@
.acquire-item .bottom { .acquire-item .bottom {
font-weight: bold; font-weight: bold;
font-size: 9pt; font-size: 9pt;
display: -ms-flexbox;
display: flex; display: flex;
-ms-flex-direction: row;
flex-direction: row; flex-direction: row;
-ms-flex-line-pack: center;
align-content: center; align-content: center;
-ms-flex-wrap: wrap;
flex-wrap: wrap; flex-wrap: wrap;
-ms-flex-pack: justify;
justify-content: space-between; justify-content: space-between;
-ms-flex-align: center;
align-items: center; align-items: center;
} }
.acquire-item #hashpart { .acquire-item #hashpart {
-ms-flex: 1 1 auto;
flex: 1; flex: 1;
overflow-y: hidden; overflow-y: hidden;
overflow-x: hidden; overflow-x: hidden;
@@ -492,17 +631,19 @@
} }
</style> </style>
<div id="acquire-template" class="acquire-item" style="display: none;"> <div id="acquire-template" class="acquire-item" style="display: none;">
<div id="name" class="top" title="Identity Name">Identity Name</div> <div id="name" class="top" title="Identity Name"></div>
<div class="medium"> <div class="medium">
<div id="ext" title="File Type">Appx</div> <div id="ext" title="File Type"></div>
<div id="version" title="Version">1.0.0.0</div> <div id="version" title="Version"></div>
<div id="architecture" title="Processor Architecture">neutral</div> <div id="architecture" title="Processor Architecture"></div>
<div id="publisherId" title="Identity Publisher Id"></div> <div id="publisherId" title="Identity Publisher Id"></div>
<div id="size" title="File Size"></div> <div id="size" title="File Size"></div>
</div> </div>
<div class="bottom"> <div class="bottom">
<div id="hashpart"><span>SHA-1: </span><span id="hash"></span></div> <div id="hashpart"><span>SHA-1: </span><span id="hash"></span></div>
<div><a download id="download" href="">点击下载</a></div> <div>
<a download id="download" href="" data-res-resxml="READER_ACQUIRE_CLICKDOWNLOAD"></a>
</div>
</div> </div>
</div> </div>
<div id="acquire-loading"> <div id="acquire-loading">
@@ -514,17 +655,17 @@
</div> </div>
</div> </div>
<div id="acquire-result" style="width: 100%;"> <div id="acquire-result" style="width: 100%;">
<p style="font-weight: normal;" title="Category ID"><span>类别 ID</span>: <span id="acquire-categoryid" style="user-select: text; -ms-user-select: element;"></span></p> <p style="font-weight: normal;" title="Category ID"><span data-res-resxml="READER_ACQUIRE_CATEGORYID"></span>: <span id="acquire-categoryid" style="user-select: text; -ms-user-select: element;"></span></p>
<h3>以下可能为检索到的应用</h3> <h3 data-res-resxml="READER_ACQUIRE_RESULTAPPS"></h3>
<div id="acquire-list-app" style="width: 100%;"></div> <div id="acquire-list-app" style="width: 100%;"></div>
<h3>以下可能为检索到的依赖项</h3> <h3 data-res-resxml="READER_ACQUIRE_RESULTDEPS"></h3>
<div id="acquire-list-dep" style="width: 100%;"></div> <div id="acquire-list-dep" style="width: 100%;"></div>
</div> </div>
<script> <script>
(function(global) { (function(global) {
var conf = external.Config.current; var conf = external.Config.current;
var set = conf.getSection("Settings"); var set = conf.getSection("Settings");
var isForbidden = !set.getKey("EnableAcquire").readBool(false); var isForbidden = !set.getKey("PackageReader:EnableAcquire").readBool(false);
var acquireInput = document.getElementById("acquire-input"); var acquireInput = document.getElementById("acquire-input");
var acquireValuetype = document.getElementById("acquire-valuetype"); var acquireValuetype = document.getElementById("acquire-valuetype");
var acquireChannel = document.getElementById("acquire-channel"); var acquireChannel = document.getElementById("acquire-channel");
@@ -578,7 +719,7 @@
keys.forEach(function(k, i) { keys.forEach(function(k, i) {
var listview = listView[k]; var listview = listView[k];
var p = document.createElement("p"); var p = document.createElement("p");
p.textContent = "还没有内容..."; p.textContent = stringRes("READER_ACQUIRE_NOCONTENT");
listview.emptyView = p; listview.emptyView = p;
}); });
acquireLoading.statusBar = new TransitionPanel(acquireLoading, { acquireLoading.statusBar = new TransitionPanel(acquireLoading, {
@@ -606,8 +747,8 @@
acquireSmartquery.disabled = acquireSmartquery.disabled =
acquireValuetype.disabled = acquireValuetype.disabled =
acquireChannel.disabled = true; acquireChannel.disabled = true;
queryFunc = StoreRG.test; //queryFunc = StoreRG.test;
acquireLoadingLabel.textContent = "正在查询..."; acquireLoadingLabel.textContent = stringRes("READER_ACQUIRE_QUERYING");
queryFunc(acquireInput.value, acquireValuetype.value, acquireChannel.value).then(function(result) { queryFunc(acquireInput.value, acquireValuetype.value, acquireChannel.value).then(function(result) {
acquireCategoryid.textContent = result.categoryId; acquireCategoryid.textContent = result.categoryId;
var applist = []; var applist = [];
@@ -628,7 +769,7 @@
return item.file; return item.file;
}); });
listView.deps.refresh(); listView.deps.refresh();
acquireLoadingLabel.textContent = "已获取到 {0} 个信息" acquireLoadingLabel.textContent = stringRes("READER_ACQUIRE_RESULTCNT")
.replace("{0}", applist.length + deplist.length); .replace("{0}", applist.length + deplist.length);
}, function(err) { }, function(err) {
dataSrc.apps.clear(); dataSrc.apps.clear();
@@ -654,6 +795,13 @@
</script> </script>
</div> </div>
</div> </div>
<div id="page-search" style="display: none;" class="ispage padding">
<h2 data-res-resxml="READER_SEARCH_TITLE"></h2>
<div id="search-forbidden" style="width: 100%;">
<p data-res-resxml="READER_SEARCH_PROHIBIT"></p>
<a onclick="external.Process.open ('https://dbox.tools')">dbox.tools</a>
</div>
</div>
</main> </main>
<aside class="win-ui-dark"> <aside class="win-ui-dark">
<nav class="container"> <nav class="container">
@@ -677,15 +825,19 @@
<ul class="list"> <ul class="list">
<li id="tag-reader"> <li id="tag-reader">
<div role="img">&#57650;</div> <div role="img">&#57650;</div>
<span class="win-type-base" data-res-resxml="MANAGER_MANAGE"></span> <span class="win-type-base" data-res-resxml="READER_READER_TITLE"></span>
</li> </li>
<li id="tag-acquire"> <li id="tag-acquire">
<div role="img">&#57624;</div> <div role="img">&#57624;</div>
<span class="win-type-base" data-res-resxml="MANAGER_MANAGE"></span> <span class="win-type-base" data-res-resxml="READER_ACQUIRE_TITLE"></span>
</li>
<li id="tag-search">
<div role="img">&#57626;</div>
<span class="win-type-base" data-res-resxml="READER_SEARCH_TITLE"></span>
</li> </li>
<li id="tag-settings"> <li id="tag-settings">
<div role="img">&#57621;</div> <div role="img">&#57621;</div>
<span class="win-type-base" data-res-resxml="MANAGER_SETTINGS"></span> <span class="win-type-base" data-res-resxml="READER_SETTINGS_TITLE"></span>
</li> </li>
<script> <script>
(function(global) { (function(global) {

View File

@@ -195,6 +195,42 @@
</table> </table>
<script> <script>
(function(global) { (function(global) {
var imageItem = [
"LockScreenLogo",
"Logo",
"SmallLogo",
"Square150x150Logo",
"Square30x30Logo",
"Square310x310Logo",
"Square44x44Logo",
"Square70x70Logo",
"Square71x71Logo",
"Tall150x310Logo",
"WideLogo",
"Wide310x150Logo"
];
function toLowerCase(str) {
if (typeof str !== "string") return "";
return str.replace(/[A-Z]/g, function(ch) {
return String.fromCharCode(ch.charCodeAt(0) + 32);
});
}
function trim(str) {
return str.replace(/^\s+|\s+$/g, "");
}
function isImageItem(item) {
var tl = trim(toLowerCase(item));
for (var i = 0; i < imageItem.length; i++) {
var lower = trim(toLowerCase(imageItem[i]));
if (lower == tl) {
return true;
}
}
return false;
}
if (typeof Array.prototype.forEach !== "function") { if (typeof Array.prototype.forEach !== "function") {
Array.prototype.forEach = function(callback, thisArg) { Array.prototype.forEach = function(callback, thisArg) {
var T, k; var T, k;
@@ -317,7 +353,7 @@
var tdv = document.createElement("td"); var tdv = document.createElement("td");
tdk.textContent = key; tdk.textContent = key;
tdv.textContent = t[key]; tdv.textContent = t[key];
if (typeof t[key + "_Base64"] !== "undefined") { if (typeof t[key + "_Base64"] !== "undefined" && isImageItem(key)) {
tdv.innerHTML = ""; tdv.innerHTML = "";
var img = document.createElement("img"); var img = document.createElement("img");
img.src = t[key + "_Base64"]; img.src = t[key + "_Base64"];

View File

@@ -80,6 +80,9 @@
<p> <p>
<a id="about-eula" data-res-fromfile="publicRes(137)"></a> <a id="about-eula" data-res-fromfile="publicRes(137)"></a>
</p> </p>
<p>
<a id="about-thanks" data-res-fromfile="publicRes (230)"></a>
</p>
<p data-res-fromfile="publicRes (138)"></p> <p data-res-fromfile="publicRes (138)"></p>
<ul> <ul>
<li><a href="https://github.com/chausner/PriTools" target="_blank">chausner/PriTools</a></li> <li><a href="https://github.com/chausner/PriTools" target="_blank">chausner/PriTools</a></li>
@@ -88,7 +91,8 @@
<li><a href="https://github.com/winjs/winjs" target="_blank">WinJS</a></li> <li><a href="https://github.com/winjs/winjs" target="_blank">WinJS</a></li>
<li><a href="https://github.com/evilstreak/markdown-js" target="_blank">markdown.js</a></li> <li><a href="https://github.com/evilstreak/markdown-js" target="_blank">markdown.js</a></li>
<li><a href="https://codemirror.net/" target="_blank">CodeMirror</a></li> <li><a href="https://codemirror.net/" target="_blank">CodeMirror</a></li>
<li><a href="https://www.newtonsoft.com/json" target="_blank">Newtonsoft.Json</a></li> <li><a href="https://www.newtonsoft.com/json" target="_blank">Newtonsoft.Json</a></li>
<li><a href="https://icsharpcode.github.io/SharpZipLib/" target="_blank">SharpZipLib</a></li>
</ul> </ul>
<script> <script>
(function() { (function() {
@@ -184,7 +188,6 @@
}); });
eventutil.addEvent(aboutProjectDescription, "click", function() { eventutil.addEvent(aboutProjectDescription, "click", function() {
function decodeBase64(base64) { function decodeBase64(base64) {
// GitHub 的 content 有换行,必须清理
base64 = base64.replace(/\s/g, ""); base64 = base64.replace(/\s/g, "");
return atob(base64); return atob(base64);
} }
@@ -299,6 +302,22 @@
body.style.color = "black"; body.style.color = "black";
}, 0); }, 0);
}); });
var aboutThanks = document.getElementById("about-thanks");
eventutil.addEvent(aboutThanks, "click", function() {
var content = document.createElement("div");
var p = document.createElement("p");
p.textContent = getPublicRes(231);
content.appendChild(p);
var contributes = '<a href="https://github.com/modernw/App-Installer-For-Windows-8.x-Reset/graphs/contributors" target="_blank">\n \x3C!-- Made with [contrib.rocks](https://contrib.rocks). -->\n <img src="https://contrib.rocks/image?repo=modernw/App-Installer-For-Windows-8.x-Reset&columns=10" style="max-width:100%" />\n</a>\n';
content.innerHTML += contributes;
var p1 = document.createElement("p");
p1.textContent = getPublicRes(232);
content.appendChild(p1);
var dlg = new MsgBox();
dlg.text = content;
dlg.title = getPublicRes(230);
dlg.show();
});
})(); })();
</script> </script>
</div> </div>

View File

@@ -23,6 +23,7 @@
var settingItems = { var settingItems = {
appinstaller: getSettingsItem("appinstaller.html", getLibRes("appinstaller.exe", 300)), appinstaller: getSettingsItem("appinstaller.html", getLibRes("appinstaller.exe", 300)),
manager: getSettingsItem("manager.html", getStringRes("MANAGER_APPTITLE")), manager: getSettingsItem("manager.html", getStringRes("MANAGER_APPTITLE")),
reader: getSettingsItem("reader.html", getStringRes("READER_APPTITLE")),
settings: getSettingsItem("settings.html", getLibRes("settings.exe", 200)), settings: getSettingsItem("settings.html", getLibRes("settings.exe", 200)),
}; };
Object.defineProperty(global, "settingPages", { Object.defineProperty(global, "settingPages", {

View File

@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<title>Package Manager Settings</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="../js/module.js"></script>
<script type="text/javascript" src="../js/polyfill-ie.js"></script>
<link rel="stylesheet" href="../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
<script type="text/javascript" src="../libs/winjs/1.0/js/base.js"></script>
<script type="text/javascript" src="../libs/winjs/1.0/js/ui.js"></script>
<script type="text/javascript" src="../js/color.js"></script>
<script type="text/javascript" src="../js/promise.js"></script>
<script type="text/javascript" src="../js/bridge.js"></script>
<script type="text/javascript" src="../js/dpimodes.js"></script>
<script type="text/javascript" src="../js/resources.js"></script>
<script type="text/javascript" src="../js/animation.js"></script>
<link rel="stylesheet" href="../fonts/fonts.css">
<script type="text/javascript" src="../js/event.js"></script>
<script type="text/javascript" src="../js/tileback.js"></script>
<script type="text/javascript" src="../js/load.js"></script>
<link rel="stylesheet" type="text/css" href="../libs/msgbox/contentdlg.css">
<script type="text/javascript" src="../libs/msgbox/contentdlg.js"></script>
<link rel="stylesheet" type="text/css" href="../libs/msgbox/msgbox.css">
<script type="text/javascript" src="../libs/msgbox/msgbox.js"></script>
<script type="text/javascript" src="../js/init.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<link rel="stylesheet" type="text/css" href="page.css">
<script type="text/javascript" src="reader/preinit.js"></script>
<script type="text/javascript" src="reader/items.js"></script>
<script type="text/javascript" src="reader/init.js"></script>
</head>
<body>
<div id="settingpage" class="pagecontainer full">
<div class="page full guide">
<aside class="left win-ui-dark">
<header aria-label="Header content" role="banner" class="titlebanner" id="pagebanner" style="height: 120px;">
<button id="back" class="win-backbutton pagetitlewb-backbutton" onclick="Bridge.Frame.callEvent ('InvokeBackPage')" style="margin-left: 20px; transform: scale(0.72);"></button>
<h2 class="titlearea win-type-ellipsis" id="apptitle" style="">
<span class="pagetitlewb-title" id="apptitlestr" style="margin-left: 10px; margin-right: 20px;" data-res-resxml="READER_APPTITLE"></span>
</h2>
</header>
<nav class="container">
<ul class="list">
</ul>
</nav>
</aside>
<iframe class="main right" defer loading="lazy" async></iframe>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,158 @@
<!DOCTYPE html>
<html>
<head>
<title>App Installer Settings</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="../../js/module.js"></script>
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
<script type="text/javascript" src="../../js/color.js"></script>
<script type="text/javascript" src="../../js/promise.js"></script>
<script type="text/javascript" src="../../js/bridge.js"></script>
<script type="text/javascript" src="../../js/dpimodes.js"></script>
<script type="text/javascript" src="../../js/resources.js"></script>
<script type="text/javascript" src="../../js/animation.js"></script>
<link rel="stylesheet" href="../../fonts/fonts.css">
<script type="text/javascript" src="../../js/event.js"></script>
<script type="text/javascript" src="../../js/tileback.js"></script>
<script type="text/javascript" src="../../js/load.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/toggle/toggle.css">
<script type="text/javascript" src="../../libs/toggle/toggle.js"></script>
<script type="text/javascript" src="../../js/init.js"></script>
<link rel="stylesheet" type="text/css" href="../page.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script type="text/javascript" src="preinit.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<script>
try {
window.parent.setItemHighlight("appitems");
} catch (e) {}
</script>
</head>
<body>
<div class="pagecontainer full pagesection">
<div class="section padding">
<div class="bottom-compensate">
<h2 id="page-title" data-res-resxml="READER_SETTINGS_APPITEMS"></h2>
<div class="win-settings-section">
<p data-res-resxml="READER_SETTINGS_APPITEMS_DESC"></p>
<style>
table {
border-collapse: collapse;
}
table th,
table td {
border: 1px solid #ccc;
padding: 5px;
}
</style>
<table style="max-width: 100%;">
<thead>
<tr>
<th></th>
<th data-res-resxml="READER_SETTINGS_APPITEMS_ITEM"></th>
<th data-res-resxml="READER_SETTINGS_APPITEMS_DESCRIPTION"></th>
</tr>
</thead>
<tbody id="appitem-list"></tbody>
</table>
<script>
(function() {
"use strict";
var appItemList = document.getElementById("appitem-list");
var ini = Bridge.External.Config.GetConfig();
var appitemset = ini.getSection("PackageReader:AppMetadatas");
var appitems = [
"Id",
"StartPage",
"EntryPoint",
"Executable",
"BackgroundColor",
"DisplayName",
"Description",
"ShortName",
"ForegroundText",
"SmallLogo",
"Square30x30Logo",
"Square44x44Logo",
"Square70x70Logo",
"Square71x71Logo",
"Logo",
"Square150x150Logo",
"WideLogo",
"Wide310x150Logo",
"Square310x310Logo",
"Tall150x310Logo",
"LockScreenLogo",
"LockScreenNotification",
"DefaultSize",
"AppListEntry",
"VisualGroup",
"MinWidth",
];
var defaultItems = [
"Id",
"DisplayName",
"BackgroundColor",
"ForegroundText",
"ShortName",
"Square44x44Logo",
"SmallLogo"
];
for (var i = 0; i < appitems.length; i++) {
var item = appitems[i];
var isenable = appitemset.getKey(item).value;
if (isenable === null || isenable === void 0 || isenable === "") {
isenable = defaultItems.indexOf(item) >= 0;
}
var dispItem = stringRes("APPMETADATA_" + item);
var tr = document.createElement("tr");
var tdCheck = document.createElement("td");
var tdItem = document.createElement("td");
var tdDesc = document.createElement("td");
tr.appendChild(tdCheck);
tr.appendChild(tdItem);
tr.appendChild(tdDesc);
var checkbox = document.createElement("input");
tdCheck.appendChild(checkbox);
checkbox.type = "checkbox";
checkbox.checked = isenable;
checkbox.id = "appitem_" + item;
checkbox.setAttribute("data-metadata", item);
var label = document.createElement("label");
tdItem.appendChild(label);
label.setAttribute("for", checkbox.id);
label.style.fontWeight = "normal";
label.textContent = item;
label.title = item;
var labelDesc = document.createElement("label");
tdDesc.appendChild(labelDesc);
labelDesc.textContent = dispItem;
labelDesc.title = dispItem;
labelDesc.setAttribute("for", checkbox.id);
labelDesc.style.fontWeight = "normal";
appItemList.appendChild(tr);
checkbox.onchange = function() {
appitemset.getKey(this.getAttribute("data-metadata")).value = this.checked;
}
}
})();
</script>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,192 @@
<!DOCTYPE html>
<html>
<head>
<title>App Installer Settings</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="../../js/module.js"></script>
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
<script type="text/javascript" src="../../js/color.js"></script>
<script type="text/javascript" src="../../js/promise.js"></script>
<script type="text/javascript" src="../../js/bridge.js"></script>
<script type="text/javascript" src="../../js/dpimodes.js"></script>
<script type="text/javascript" src="../../js/resources.js"></script>
<script type="text/javascript" src="../../js/animation.js"></script>
<link rel="stylesheet" href="../../fonts/fonts.css">
<script type="text/javascript" src="../../js/event.js"></script>
<script type="text/javascript" src="../../js/tileback.js"></script>
<script type="text/javascript" src="../../js/load.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/toggle/toggle.css">
<script type="text/javascript" src="../../libs/toggle/toggle.js"></script>
<script type="text/javascript" src="../../js/init.js"></script>
<link rel="stylesheet" type="text/css" href="../page.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script type="text/javascript" src="preinit.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<script>
try {
window.parent.setItemHighlight("general");
} catch (e) {}
</script>
</head>
<body>
<div class="pagecontainer full pagesection">
<div class="section padding">
<div class="bottom-compensate">
<h2 id="page-title" data-res-fromfile="publicRes (101)"></h2>
<div class="win-settings-section">
<br>
<label class="win-label" for="save-wnd-size" id="save-wnd-size-label" data-res-fromfile="publicRes (125)"></label>
<script>
(function() {
"use strict";
var label = document.getElementById("save-wnd-size-label");
var toggle = new Toggle();
toggle.create();
toggle.parent = label.parentNode;
toggle.showlabel = true;
var winjsres = Bridge.External.WinJsStringRes;
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
toggle.inputId = "save-wnd-size";
var ini = Bridge.External.Config.GetConfig();
toggle.addEventListener("change", function() {
ini.set("Settings", "PackageReader:SavePosAndSizeBeforeCancel", toggle.checked);
});
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:SavePosAndSizeBeforeCancel").value);
})();
</script>
</div>
<div class="win-settings-section">
<br>
<label class="win-label" for="default-wndwidth" data-res-fromfile="publicRes(126)"></label><br>
<input type="number" id="default-wndwidth" inputmode="numeric"><br><br>
<label class="win-label" for="default-wndheight" data-res-fromfile="publicRes(127)"></label><br>
<input type="number" id="default-wndheight" inputmode="numeric">
<script>
(function() {
"use strict";
var ini = Bridge.External.Config.GetConfig();
var defWndWInput = document.getElementById("default-wndwidth");
var defWndHInput = document.getElementById("default-wndheight");
var setsect = ini.getSection("Settings");
var defwk = setsect.getKey("PackageReader:DefaultWidth");
var defhk = setsect.getKey("PackageReader:DefaultHeight");
defWndWInput.value = defwk.value;
defWndHInput.value = defhk.value;
var eventutil = Windows.UI.Event.Util;
function inputDefaultWidthChangeEvent(e) {
defwk.value = parseInt(defWndWInput.value);
}
function inputDefaultHeightChangeEvent(e) {
defhk.value = parseInt(defWndHInput.value);
}
var debounced_idwc = debounce(inputDefaultWidthChangeEvent, 500);
var debounced_idhc = debounce(inputDefaultHeightChangeEvent, 500);
eventutil.addEvent(defWndWInput, "input", debounced_idwc);
eventutil.addEvent(defWndWInput, "propertychange", debounced_idwc);
eventutil.addEvent(defWndWInput, "change", debounced_idwc);
eventutil.addEvent(defWndHInput, "input", debounced_idhc);
eventutil.addEvent(defWndHInput, "propertychange", debounced_idhc);
eventutil.addEvent(defWndHInput, "change", debounced_idhc);
})();
</script>
</div>
<div class="win-settings-section">
<br>
<label class="win-label" for="min-wndwidth" data-res-fromfile="publicRes (128)"></label><br>
<input type="number" id="min-wndwidth" inputmode="numeric"><br><br>
<label class="win-label" for="min-wndheight" data-res-fromfile="publicRes (129)"></label><br>
<input type="number" id="min-wndheight" inputmode="numeric">
<script>
(function() {
"use strict";
var ini = Bridge.External.Config.GetConfig();
var minWndWInput = document.getElementById("min-wndwidth");
var minWndHInput = document.getElementById("min-wndheight");
var setsect = ini.getSection("Settings");
var minwk = setsect.getKey("PackageReader:MinimumWidth");
var minhk = setsect.getKey("PackageReader:MinimumHeight");
minWndWInput.value = minwk.value;
minWndHInput.value = minhk.value;
var eventutil = Windows.UI.Event.Util;
function inputDefaultWidthChangeEvent(e) {
minwk.value = parseInt(minWndWInput.value);
}
function inputDefaultHeightChangeEvent(e) {
minhk.value = parseInt(minWndHInput.value);
}
var debounced_idwc = debounce(inputDefaultWidthChangeEvent, 500);
var debounced_idhc = debounce(inputDefaultHeightChangeEvent, 500);
eventutil.addEvent(minWndWInput, "input", debounced_idwc);
eventutil.addEvent(minWndWInput, "propertychange", debounced_idwc);
eventutil.addEvent(minWndWInput, "change", debounced_idwc);
eventutil.addEvent(minWndHInput, "input", debounced_idhc);
eventutil.addEvent(minWndHInput, "propertychange", debounced_idhc);
eventutil.addEvent(minWndHInput, "change", debounced_idhc);
})();
</script>
</div>
<div class="win-settings-section">
<br>
<label class="win-label" for="enable-usepri" id="enable-usepri-label" data-res-resxml="READER_SETTINGS_USEPRI"></label>
<script>
(function() {
"use strict";
var label = document.getElementById("enable-usepri-label");
var toggle = new Toggle();
toggle.create();
toggle.parent = label.parentNode;
toggle.showlabel = true;
var winjsres = Bridge.External.WinJsStringRes;
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
toggle.inputId = "enable-usepri";
var ini = Bridge.External.Config.GetConfig();
toggle.addEventListener("change", function() {
ini.set("Settings", "PackageReader:DefaultParsingPriFile", toggle.checked);
});
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:DefaultParsingPriFile").value);
})();
</script>
</div>
<div class="win-settings-section">
<br>
<label class="win-label" for="enable-acquire" id="enable-acquire-label" data-res-resxml="READER_SETTINGS_ENABLEACQUIRE"></label>
<script>
(function() {
"use strict";
var label = document.getElementById("enable-acquire-label");
var toggle = new Toggle();
toggle.create();
toggle.parent = label.parentNode;
toggle.showlabel = true;
var winjsres = Bridge.External.WinJsStringRes;
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
toggle.inputId = "enable-acquire";
var ini = Bridge.External.Config.GetConfig();
toggle.addEventListener("change", function() {
ini.set("Settings", "PackageReader:EnableAcquire", toggle.checked);
});
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:EnableAcquire").value);
})();
</script>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<title>App Installer Settings</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="../../js/module.js"></script>
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
<script type="text/javascript" src="../../js/color.js"></script>
<script type="text/javascript" src="../../js/promise.js"></script>
<script type="text/javascript" src="../../js/bridge.js"></script>
<script type="text/javascript" src="../../js/dpimodes.js"></script>
<script type="text/javascript" src="../../js/resources.js"></script>
<script type="text/javascript" src="../../js/animation.js"></script>
<link rel="stylesheet" href="../../fonts/fonts.css">
<script type="text/javascript" src="../../js/event.js"></script>
<script type="text/javascript" src="../../js/tileback.js"></script>
<script type="text/javascript" src="../../js/load.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
<script type="text/javascript" src="../../js/init.js"></script>
<link rel="stylesheet" type="text/css" href="../page.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script type="text/javascript" src="preinit.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<script>
try {
window.parent.setItemHighlight("guide");
} catch (e) {}
</script>
</head>
<body>
<div class="pagecontainer full pagesection">
<div class="section padding">
<div class="bottom-compensate">
<h2 id="guide-title"></h2>
<p id="guide-desc" style="white-space: pre-wrap;"></p>
</div>
</div>
<script>
(function() {
"use strict";
var res = Bridge.Resources;
var stru = Bridge.String;
var title = document.getElementById("guide-title");
title.textContent = stru.format(res.byname("IDS_TITLEFORMAT"), stringRes("READER_APPTITLE"));
var text = document.getElementById("guide-desc");
text.textContent = res.byname("IDS_GUIDETEXT_COMMON");
})();
</script>
</div>
</body>
</html>

View File

@@ -0,0 +1,96 @@
(function(global) {
"use strict";
function ready(e) {
var page = document.querySelector("#settingpage");
var guide = page.querySelector(".page.guide");
var slide = guide.querySelector("aside");
setTimeout(function() {
var barcolor = visual["BackgroundColor"];
slide.style.backgroundColor = barcolor;
slide.style.color = Color.getSuitableForegroundTextColor(Color.parse(barcolor), [Color.Const.white, Color.Const.black]).stringify();
}, 50);
var content = guide.querySelector(".main");
var list = slide.querySelector("ul");
var backbtn = slide.querySelector("#back");
var title = slide.querySelector("#apptitle");
list.innerHTML = "";
var items = pages;
var tags = Object.keys(items);
var eventutil = Windows.UI.Event.Util;
for (var i = 0; i < tags.length; i++) {
var tag = tags[i];
var item = items[tag];
var li = document.createElement("li");
li.setAttribute("data-page", item.page);
li.setAttribute("data-tag", item.tag);
li.innerHTML = item.title;
eventutil.addEvent(li, "click", function() {
if (li.hasAttribute("data-require-disabled")) return;
content.style.display = "none";
for (var j = 0; j < list.children.length; j++) {
var child = list.children[j];
if (child.classList.contains("selected"))
child.classList.remove("selected");
}
content.src = this.getAttribute("data-page");
setTimeout(function() {
content.style.display = "";
Windows.UI.Animation.runAsync(content, [Windows.UI.Animation.Keyframes.Flyout.toLeft, Windows.UI.Animation.Keyframes.Opacity.visible]);
}, 0);
this.classList.add("selected");
});
list.appendChild(li);
}
content.src = guidePage.page;
/*for (var i = 0; i < list.children.length; i++) {
var child = list.children[i];
child.click();
break;
}*/
var jumppage = "";
try { var args = cmdargs; if (args.length > 1) jumppage = args[1]; } catch (e) {}
if (jumppage && jumppage.length > 0 && !Bridge.External.jump2) {
for (var i = 0; i < list.children.length; i++) {
var child = list.children[i];
if (Bridge.NString.equals(child.getAttribute("data-tag"), jumppage)) {
Bridge.External.jump2 = true;
setTimeout(function(thisnode) {
thisnode.click();
}, 0, child)
break;
}
}
}
global.setDisabledForOperation = function(disabled) {
var list = document.querySelector("#settingpage .guide aside ul");
for (var i = 0; i < list.children.length; i++) {
var child = list.children[i];
if (disabled) {
child.setAttribute("data-require-disabled", "true");
} else {
child.removeAttribute("data-require-disabled");
}
}
if (disabled) {
backbtn.disabled = true;
title.style.marginLeft = backbtn.style.marginLeft;
} else {
backbtn.disabled = false;
title.style.marginLeft = "";
}
}
global.setItemHighlight = function(tag) {
var list = document.querySelector("#settingpage .guide aside ul");
for (var i = 0; i < list.children.length; i++) {
var child = list.children[i];
if (Bridge.NString.equals(child.getAttribute("data-tag"), tag)) {
if (!child.classList.contains("selected")) child.classList.add("selected");
} else {
if (child.classList.contains("selected")) child.classList.remove("selected");
}
}
}
}
OnLoad.add(ready);
})(this);

View File

@@ -0,0 +1,21 @@
(function(global) {
"use strict";
function ready(e) {
Windows.UI.DPI.mode = 1
var pagesection = document.querySelector(".pagesection");
if (pagesection) {
var backcolor = slideback;
setTimeout(function() {
var h2style = document.getElementById("h2-style");
if (!h2style) {
h2style = document.createElement("style");
h2style.id = "h2-style";
}
h2style.innerHTML = ".main h2 { color: " + Color.getSuitableForegroundTextColor(Color.parse("#F3F3F3"), [Color.parse(backcolor), Color.Const.black]).RGBA.stringify() + " }";
document.head.appendChild(h2style);
}, 0);
}
}
OnLoad.add(ready);
})(this);

View File

@@ -0,0 +1,25 @@
(function(global) {
"use strict";
function getPage(tag, page, display) {
return {
tag: tag,
page: page,
title: display
};
}
var pages = {
general: getPage("general", "reader/general.html", getPublicRes(101)),
appitems: getPage("appitems", "reader/appitems.html", stringRes("READER_SETTINGS_APPITEMS")),
};
Object.defineProperty(global, "pages", {
get: function() {
return pages;
}
});
Object.defineProperty(global, "guidePage", {
get: function() {
return getPage("guide", "reader/guide.html", "guide");
}
});
})(this);

View File

@@ -0,0 +1,30 @@
(function(global) {
var storage = Bridge.External.Storage;
var path = storage.path;
var root = path.getDir(path.program);
var exepath = path.combine(root, "settings.exe");
var id = "Reader";
var ve = Bridge.External.VisualElements.get(id);
var slideback = ve["BackgroundColor"];
global.slideback = slideback;
global.exepath = exepath;
global.visual = ve;
var strutil = Bridge.External.String;
var nstrutil = Bridge.NString;
var boolTrue = ["true", "1", "yes", "on", "y", "t", "zhen", "真"];
var boolFalse = ["false", "0", "no", "off", "n", "f", "jia", "假"];
global.parseBool = function(str) {
str = "" + str;
for (var i = 0; i < boolTrue.length; i++) {
if (nstrutil.equals(str, boolTrue[i])) {
return true;
}
}
for (var i = 0; i < boolFalse.length; i++) {
if (nstrutil.equals(str, boolFalse[i])) {
return false;
}
}
return null;
};
})(this);

BIN
shared/icons/32_reader.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

View File

@@ -1,21 +1,202 @@
MIT License
Copyright (c) 2025 Windows Modern Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Permission is hereby granted, free of charge, to any person obtaining a copy TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all 1. Definitions.
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR "License" shall mean the terms and conditions for use, reproduction,
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, and distribution as defined by Sections 1 through 9 of this document.
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER "Licensor" shall mean the copyright owner or entity authorized by
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, the copyright owner that is granting the License.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. "Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,17 @@
Copyright © 2000-2018 SharpZipLib Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

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