diff --git a/AppInstaller.sln b/AppInstaller.sln new file mode 100644 index 0000000..39e9805 --- /dev/null +++ b/AppInstaller.sln @@ -0,0 +1,179 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppInstaller", "AppInstaller\AppInstaller.vcxproj", "{D417C165-3F17-40C4-8C7B-0F5AACEF62C5}" + ProjectSection(ProjectDependencies) = postProject + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856} = {B897969C-6EA9-4DFC-B7E0-94F1C6D94856} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppLauncher", "AppLauncher\AppLauncher.vcxproj", "{285130BC-CBF1-4C7A-A28D-6F5EE6C68384}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageManager", "PackageManagerAdd\AddPackageSample.vcxproj", "{59131AB7-2A7D-9A09-8223-174C3F5E0F57}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Base64Img", "Base64Img\Base64Img.vcxproj", "{911EDC63-DB20-4D61-9420-583A1C35427F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ToastNotification", "ToastNotification\ToastNotification.vcxproj", "{E10C6272-B876-4DC6-9E13-7CA646863B50}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PriReader2", "PriReader2\PriReader2.vcxproj", "{B897969C-6EA9-4DFC-B7E0-94F1C6D94856}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CertificateManager", "CertificateManager\CertificateManager.vcxproj", "{22702832-C3FD-48E5-BC7D-3879CA50A2ED}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|Any CPU.Build.0 = Debug|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|ARM.ActiveCfg = Debug|ARM + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|ARM.Build.0 = Debug|ARM + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|Win32.ActiveCfg = Debug|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|Win32.Build.0 = Debug|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|x64.ActiveCfg = Debug|x64 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|x64.Build.0 = Debug|x64 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|x86.ActiveCfg = Debug|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Debug|x86.Build.0 = Debug|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|Any CPU.ActiveCfg = Release|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|Any CPU.Build.0 = Release|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|ARM.ActiveCfg = Release|ARM + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|ARM.Build.0 = Release|ARM + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|Win32.ActiveCfg = Release|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|Win32.Build.0 = Release|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|x64.ActiveCfg = Release|x64 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|x64.Build.0 = Release|x64 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|x86.ActiveCfg = Release|Win32 + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5}.Release|x86.Build.0 = Release|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|Any CPU.Build.0 = Debug|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|ARM.ActiveCfg = Debug|ARM + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|ARM.Build.0 = Debug|ARM + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|Win32.ActiveCfg = Debug|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|Win32.Build.0 = Debug|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|x64.ActiveCfg = Debug|x64 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|x64.Build.0 = Debug|x64 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|x86.ActiveCfg = Debug|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Debug|x86.Build.0 = Debug|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|Any CPU.ActiveCfg = Release|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|Any CPU.Build.0 = Release|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|ARM.ActiveCfg = Release|ARM + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|ARM.Build.0 = Release|ARM + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|Win32.ActiveCfg = Release|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|Win32.Build.0 = Release|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|x64.ActiveCfg = Release|x64 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|x64.Build.0 = Release|x64 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|x86.ActiveCfg = Release|Win32 + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384}.Release|x86.Build.0 = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Any CPU.Build.0 = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|ARM.ActiveCfg = Debug|ARM + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|ARM.Build.0 = Debug|ARM + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Win32.ActiveCfg = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Win32.Build.0 = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|x64.ActiveCfg = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|x86.ActiveCfg = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|x86.Build.0 = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Any CPU.ActiveCfg = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Any CPU.Build.0 = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|ARM.ActiveCfg = Release|ARM + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|ARM.Build.0 = Release|ARM + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Win32.ActiveCfg = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Win32.Build.0 = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|x64.ActiveCfg = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|x64.Build.0 = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|x86.ActiveCfg = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|x86.Build.0 = Release|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|Any CPU.Build.0 = Debug|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|ARM.ActiveCfg = Debug|ARM + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|ARM.Build.0 = Debug|ARM + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|Win32.ActiveCfg = Debug|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|Win32.Build.0 = Debug|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|x64.ActiveCfg = Debug|x64 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|x64.Build.0 = Debug|x64 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|x86.ActiveCfg = Debug|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Debug|x86.Build.0 = Debug|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|Any CPU.ActiveCfg = Release|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|Any CPU.Build.0 = Release|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|ARM.ActiveCfg = Release|ARM + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|ARM.Build.0 = Release|ARM + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|Win32.ActiveCfg = Release|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|Win32.Build.0 = Release|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|x64.ActiveCfg = Release|x64 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|x64.Build.0 = Release|x64 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|x86.ActiveCfg = Release|Win32 + {911EDC63-DB20-4D61-9420-583A1C35427F}.Release|x86.Build.0 = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|Any CPU.Build.0 = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|ARM.ActiveCfg = Debug|ARM + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|ARM.Build.0 = Debug|ARM + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|Win32.ActiveCfg = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|Win32.Build.0 = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|x64.ActiveCfg = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|x86.ActiveCfg = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|x86.Build.0 = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|Any CPU.ActiveCfg = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|Any CPU.Build.0 = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|ARM.ActiveCfg = Release|ARM + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|ARM.Build.0 = Release|ARM + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|Win32.ActiveCfg = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|Win32.Build.0 = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|x64.ActiveCfg = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|x64.Build.0 = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|x86.ActiveCfg = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|x86.Build.0 = Release|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|Any CPU.Build.0 = Debug|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|ARM.ActiveCfg = Debug|ARM + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|ARM.Build.0 = Debug|ARM + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|Win32.ActiveCfg = Debug|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|Win32.Build.0 = Debug|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|x64.ActiveCfg = Debug|x64 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|x64.Build.0 = Debug|x64 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|x86.ActiveCfg = Debug|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Debug|x86.Build.0 = Debug|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|Any CPU.ActiveCfg = Release|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|Any CPU.Build.0 = Release|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|ARM.ActiveCfg = Release|ARM + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|ARM.Build.0 = Release|ARM + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|Win32.ActiveCfg = Release|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|Win32.Build.0 = Release|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|x64.ActiveCfg = Release|x64 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|x64.Build.0 = Release|x64 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|x86.ActiveCfg = Release|Win32 + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856}.Release|x86.Build.0 = Release|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|Any CPU.Build.0 = Debug|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|ARM.ActiveCfg = Debug|ARM + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|ARM.Build.0 = Debug|ARM + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|Win32.ActiveCfg = Debug|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|Win32.Build.0 = Debug|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|x64.ActiveCfg = Debug|x64 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|x64.Build.0 = Debug|x64 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|x86.ActiveCfg = Debug|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Debug|x86.Build.0 = Debug|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|Any CPU.ActiveCfg = Release|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|Any CPU.Build.0 = Release|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|ARM.ActiveCfg = Release|ARM + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|ARM.Build.0 = Release|ARM + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|Win32.ActiveCfg = Release|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|Win32.Build.0 = Release|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|x64.ActiveCfg = Release|x64 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|x64.Build.0 = Release|x64 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|x86.ActiveCfg = Release|Win32 + {22702832-C3FD-48E5-BC7D-3879CA50A2ED}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AppInstaller/AppInstaller.rc b/AppInstaller/AppInstaller.rc new file mode 100644 index 0000000..46fe03a --- /dev/null +++ b/AppInstaller/AppInstaller.rc @@ -0,0 +1,529 @@ +// Microsoft Visual C++ generated resource script. +// +#include +#include "resource.h" +///////////////////////////////////////////////////////////////////////////// +// (壬й) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +#pragma code_page(936) + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_MAINICON ICON "res/Icons/Main.ico" + +ICON_TASKBAR ICON "res/Icons/Main.ico" + +ICON_FILE ICON "res/Icons/FileIcon.ico" + +ICON_WHITE ICON "res/Icons/IconWhite.ico" + +ICON_COLOR ICON "res/Icons/IconColor.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// IMAGE +// + +BLANK_NORMAL IMAGE "res/Button/Normal/blank.png" + +BLANK_LIGHT IMAGE "res/Button/Normal/blank_light.png" + +BLANK_PRESS IMAGE "res/Button/Normal/blank_press.png" + +MIN_NORMAL IMAGE "res/Button/Normal/min_back.png" + +MIN_LIGHT IMAGE "res/Button/Normal/min_light.png" + +MIN_PRESS IMAGE "res/Button/Normal/min_press.png" + +MAX_NORMAL IMAGE "res/Button/Normal/max_back.png" + +MAX_LIGHT IMAGE "res/Button/Normal/max_light.png" + +MAX_PRESS IMAGE "res/Button/Normal/max_press.png" + +RESTORE_NORMAL IMAGE "res/Button/Normal/restore_back.png" + +RESTORE_LIGHT IMAGE "res/Button/Normal/restore_light.png" + +RESTORE_PRESS IMAGE "res/Button/Normal/restore_press.png" + +CANCEL_NORMAL IMAGE "res/Button/Normal/cancel_back.png" + +CANCEL_LIGHT IMAGE "res/Button/Normal/cancel_light.png" + +CANCEL_PRESS IMAGE "res/Button/Normal/cancel_press.png" + +BLANK_LARGR_NORMAL IMAGE "res/Button/Large/blank.png" + +BLANK_LARGR_LIGHT IMAGE "res/Button/Large/blank_light.png" + +BLANK_LARGR_PRESS IMAGE "res/Button/Large/blank_press.png" + +MIN_LARGR_NORMAL IMAGE "res/Button/Large/min_normal.png" + +MIN_LARGE_LIGHT IMAGE "res/Button/Large/min_light.png" + +MIN_LARGR_PRESS IMAGE "res/Button/Large/min_press.png" + +MAX_LARGE_NORMAL IMAGE "res/Button/Large/max_normal.png" + +MAX_LARGE_LIGHT IMAGE "res/Button/Large/max_light.png" + +MAX_LARGE_PRESS IMAGE "res/Button/Large/max_press.png" + +RESTORE_LARGE_NORMAL IMAGE "res/Button/Large/restore_normal.png" + +RESTORE_LARGE_LIGHT IMAGE "res/Button/Large/restore_light.png" + +RESTORE_LARGE_PRESS IMAGE "res/Button/Large/restore_press.png" + +CANCEL_LARGE_NORMAL IMAGE "res/Button/Large/cancel_window_normal.png" + +CANCEL_LARGE_LIGHT IMAGE "res/Button/Large/cancel_window_light.png" + +CANCEL_LARGE_PRESS IMAGE "res/Button/Large/cancel_window_press.png" + + +///////////////////////////////////////////////////////////////////////////// +// +// RCDATA +// + +ICON_METRO RCDATA "res/Icons/IconTitleBar.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// RT_MANIFEST +// + +IDR_MANIFEST1 RT_MANIFEST "res/manifest.xml" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +IDR_VERSION_ZH_CN VERSIONINFO + FILEVERSION 1,0,1,7 + PRODUCTVERSION 1,0,1,7 + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080404b0" + BEGIN + VALUE "CompanyName", "Bruce Winter" + VALUE "FileDescription", "Ӧðװ" + VALUE "FileVersion", "1.0.1.7" + VALUE "LegalCopyright", "\\xA9Bruce Winter. All rights reserved." + VALUE "ProductVersion", "1.0.1.7" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x804, 1200 + END +END + +IDR_VERSION_EN_US VERSIONINFO + FILEVERSION 1,0,1,7 + PRODUCTVERSION 1,0,1,7 + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e6" + BEGIN + VALUE "CompanyName", "Bruce Winter" + VALUE "FileDescription", "App Installer" + VALUE "FileVersion", "1.0.1.7" + VALUE "LegalCopyright", "\\xA9Bruce Winter. All rights reserved." + VALUE "ProductVersion", "1.0.1.7" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1254 + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + WIN_TITLE "Ӧðװ" + PAGE_LOADING "Ժ..." + PAGE_1_TITLE "װ %ls" + PAGE_INFO_PUBLISHER ": %ls" +END + +STRINGTABLE +BEGIN + PAGE_INFO_VERSION "汾: %ls" + PAGE_FUNCTIONS ":" + PAGE_CHECK_RUNWHENREADY "׼ʱ" + PAGE_2_LOADCERT "ڵ֤..." + PAGE_2_INSTALL "ڰװ..." + PAGE_3_TITLE "ѡһЧİװԴԼ" + PAGE_4_TITLE "%ls Ѱװ" + PAGE_5_TITLE "%ls װʧ" + DIALOG_SELLET_APPX "Windows Ӧðļ (*.appx, *.appxbundle)" + DIALOG_SELLET_UNI "ļ (*.*)" + BUTTON_1_SER1 "װ" + BUTTON_3_SER1 "ļ" + BUTTON_4_SER1 "" + BUTTON_5_SER1 "ر" + DIALOG_WINTITLE "ѡЧ Windows Ӧðļ" + PAGE_1_APPHASINSTALLED "%ls Ѱװ" +END + +STRINGTABLE +BEGIN + PAGE_2_TITLE "ڰװ %ls" + PAGE_1_APP "Microsoft Store Ӧ" + PAGE_2_LOADING "Ժ..." + PAGE_2_INSTALLING "ڰװ %d%%" + CLHELP_1 "в˵\n\n" + CLHELP_2 "\t/?, /Help\n\tʾ (в˵)\n\n" + CLHELP_3 "\t/DisableFrame\n\tֹʹԻĴڱ߿\n\n" + CLHELP_4 "\t/Win32Window\n\tʹ WebUI Win32 \n\n" + CLHELP_5 "\t/Silent\n\tһ»Զװװɺڼ\n\n" + CLHELP_6 "\t/VerySilent\n\tĬװװʱʾκϢװɺԶ\n\n" +END + +STRINGTABLE +BEGIN + textSupportCPU "ֵ֧Ĵܹ: " + textSupportSystem "ֵ֧ Windows 汾: %ls ߰汾Ӧϵͳ汾: %ls" + textSupportLanguage "ֵ֧: " + textDependency "Ӧ: " + textDependencyItem "%ls, Ͱ汾: %ls" +END + +STRINGTABLE +BEGIN + INITWIDTH "656" + INITHEIGHT "412" + LIMITWIDTH "504" + LIMITHEIGHT "412" +END + +STRINGTABLE +BEGIN + CLHELP_7 "\t/NoGUI\n\tʹ WSAppPkgIns װװʱᵯдڣװɺֶرմ\n\n" +END + +STRINGTABLE +BEGIN + internetClient " Internet " + internetClientServer " Internet Ӳ䵱" + privateNetworkClientServer "ļͥ" + documentsLibrary "ʹĵ" + picturesLibrary "ʹͼƬ" + videosLibrary "ʹƵ" + musicLibrary "ʹֿ" + enterpriseAuthentication "ʹҵƾ" + sharedUserCertificates "ʹ豸ϿõӲ֤" + removableStorage "ʹô洢ⲿ洢豸ϵ" + appointments "ʹе¼" + contacts "ʹϵ" +END + +STRINGTABLE +BEGIN + phoneCall "豸ϵе绰·" + backgroundMediaPlayback "ں̨ý" + pointOfService "ʹɨǺʹſ" + allJoyn "ֲ֧ AllJoyn Ӧú豸" + phoneCallHistoryPublic "绰йʷ¼" + microphone "ʹ˷" + offlineMapsManagement "Ӧóߵͼ" + objects3D "Ա̷ʽ 3D " + graphicsCaptureWithoutBorder "ޱ߿ͼβ" + bluetooth "Ե豸ͨ" + lowLevelDevices "ͼӲ" + location "ʹλ" + humaninterfacedevice "ʹ֧˻ӿ豸 (HID) Э豸" + recordedCallsFolder "ͨ¼" + proximity "ʹֽ֧ͨ (NFC) 豸" + webcam "ʹͷ" +END + +STRINGTABLE +BEGIN + graphicsCaptureProgrammatic "ʹͼβ" + userNotificationListener "Ӧó֪ͨõĵǰ״̬" + userDataTasks "Ӧóõĵǰ״̬" + userAccountInformation "ʻûͼƬ" + usb " USB 豸" + systemManagement "ϵͳ" + spatialPerception "鿴ǰ͹ȥΧ" + smsSend " SMS MMS Ϣ" + blockedChatMessages "ĶʼӦֹ SMS MMS Ϣ" + chat "ĶɾıϢ" + codeGeneration "̬ɴ" + voipCall "ʹ豸 IP (VoIP) " + enterpriseDataPolicy "Ϊ豸ҵض" + inputInjectionBrokered "ӦóԱ̷ʽʽעϵͳ HIDʡ̻ꡣ" + remoteSystem "Ӧóû Microsoft ʻ豸б" +END + +STRINGTABLE +BEGIN + inProcessMediaExtension "ýչ" + webPlatformMediaExtension "Web ƽ̨ýչ" + previewStore "Microsoft Store Ԥ" + confirmAppClose "رԼԼĴڣӳٹرӦó" + runFullTrust "ʹϵͳԴ" + previewUiComposition "Ԥ Windows UI Composition API Խշ" + slapiQueryLicenseValue "ѯ" + localSystemServices "ʹȨеļϰװ" + packageManagement "ֱӹӦ" + packageQuery "ѼйӦõϢ" + packagePolicySystem "밲װ豸ϵӦصϵͳ" + storeAppInstall "Ӧðװ" + appLicensing "Ӧ" + broadFileSystemAccess "ļϵͳ" + allowElevation "ԹԱ" + unvirtualizedResources "джʱעļ" +END + +STRINGTABLE +BEGIN + extendedExecution "Ӧóڽִ̨һʱIJ" + appointmentsSystem "Ӧöȡ޸ûϵ¼" + contactsSystem "ӦöȡָΪ޻еϵϢԼ޸еϵϢ" + phoneCallSystem "Ӧ÷豸ϵе绰" + userDataAccounts "ɷʵʼϵˡȵûʻ" + userDataTasksSystem "ɷϵͳ" +END + +#endif // (壬й) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Ӣ() resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + WIN_TITLE "App Installer" + PAGE_LOADING "Please wait..." + PAGE_1_TITLE "Install %ls?" + PAGE_INFO_PUBLISHER "Publisher: %ls" +END + +STRINGTABLE +BEGIN + PAGE_INFO_VERSION "Version: %ls" + PAGE_FUNCTIONS "Functions:" + PAGE_CHECK_RUNWHENREADY "Launch when ready" + PAGE_2_LOADCERT "Importing certificates..." + PAGE_2_INSTALL "Installing..." + PAGE_3_TITLE "Please select a valid installation source to continue" + PAGE_4_TITLE "%ls is ready" + PAGE_5_TITLE "%ls is failed" + DIALOG_SELLET_APPX "Windows App Package (*.appx, *.appxbundle)" + DIALOG_SELLET_UNI "All files (*.*)" + BUTTON_1_SER1 "Install" + BUTTON_3_SER1 "Open File" + BUTTON_4_SER1 "Launch" + BUTTON_5_SER1 "Cancel" + DIALOG_WINTITLE "Please select a valid app package file" + PAGE_1_APPHASINSTALLED "%ls has been installed" +END + +STRINGTABLE +BEGIN + PAGE_2_TITLE "Installing %s" + PAGE_1_APP "Microsoft Store App" + PAGE_2_LOADING "Please wait..." + PAGE_2_INSTALLING "Installing %d%%" + CLHELP_1 "Usage:\n\n" + CLHELP_2 "\t/?, /Help\n\tDisplay help window (command line parameter description).\n\n" + CLHELP_3 "\t/DisableFrame\n\tDisable the use of self-drawn window borders.\n\n" + CLHELP_4 "\t/Win32Window\n\tDo not use WebUI, use Win32 window instead.\n\n" + CLHELP_5 "\t/Silent\n\tUnder normal circumstances, it will be automatically installed and will end after a few seconds.\n\n" + CLHELP_6 "\t/VerySilent\n\tSilent installation, no information will be displayed during installation, and the installation task will automatically end after completion.\n\n" +END + +STRINGTABLE +BEGIN + textSupportCPU "Supported processor architectures: " + textSupportSystem "Supported Windows versions: %ls and later (minimum running system version of the app: %ls)" + textSupportLanguage "Supported languages:" + textDependency "The following are the dependencies required by the application:" + textDependencyItem "%ls, minimum required version: %ls" +END + +STRINGTABLE +BEGIN + CLHELP_7 "\t/NoGUI\n\tUse WSAppPkgIns to install. A command line window will pop up during installation, and you need to manually close the window after installation.\n\n" +END + +STRINGTABLE +BEGIN + internetClient "Access your Internet connection" + internetClientServer "Access your Internet connection and act as a server." + privateNetworkClientServer "Access your home or work networks" + documentsLibrary "Use your documents library" + picturesLibrary "Use your pictures library" + videosLibrary "Use your video library" + musicLibrary "Use your music library" + enterpriseAuthentication "Use your enterprise domain credentials" + sharedUserCertificates "Use the software and hardware certificates available on your device" + removableStorage "Use data stored on an external storage device" + appointments "Use the appointments in your calendar" + contacts "Use your contacts" +END + +STRINGTABLE +BEGIN + phoneCall "Access all the phone lines on your device" + backgroundMediaPlayback "Play media in the background" + pointOfService "Use barcode scanners and magnetic card readers" + allJoyn "Discover and interact with AllJoyn enabled apps and devices" + phoneCallHistoryPublic "Phone Calls Public History" + microphone "Use your microphone" + offlineMapsManagement "Allows the application to access offline maps." + objects3D "Programmatically access your 3D Objects" + graphicsCaptureWithoutBorder "Allows borderless graphics capture" + bluetooth "Communicate with already paired Bluetooth devices" + lowLevelDevices "IoT Low-Level Bus Hardware" + location "Use your location" + humaninterfacedevice "Use your devices that support the Human Interface Device (HID) protocol" + recordedCallsFolder "Access your recorded calls" + proximity "Use devices that support Near Field Communication (NFC) services" + webcam "Use your webcam" +END + +STRINGTABLE +BEGIN + graphicsCaptureProgrammatic "Allows use of graphics capture" + userNotificationListener + "Allows an application to access the current state of notification settings" + userDataTasks "Allows an application to access the current state of task settings" + userAccountInformation "Access to your Account's username and picture" + usb "Access your USB connected devices" + systemManagement "IoT System Adminstration" + spatialPerception "See your current and past surroundings" + smsSend "Send SMS and MMS messages" + blockedChatMessages "Read SMS and MMS messages that have been blocked by the Spam Filter app" + chat "Read and delete Text Messages" + codeGeneration "Generate code dynamically" + voipCall "Use your device's voice over IP (VoIP) services" + enterpriseDataPolicy "Define enterprise-specific policies for your device" + inputInjectionBrokered "Allows an application to programmatically inject various forms of input into the system, such as HID, touch, pen, keyboard, or mouse." + remoteSystem "Allows the application to access the list of devices associated with the user's Microsoft account" +END + +STRINGTABLE +BEGIN + inProcessMediaExtension "In-process Media Extension" + webPlatformMediaExtension "Web Platform Media Extension" + previewStore "Microsoft Store Preview Features" + confirmAppClose "Close themselves and their own windows, and delay the closing of their app" + runFullTrust "Uses all system resources" + previewUiComposition "Preview the Windows UI Composition API to receive feedback" + slapiQueryLicenseValue "Query software licensing policies" + localSystemServices "Install a service on the machine that runs with maximum privileges" + packageManagement "Manage other apps directly" + packageQuery "Gather information about other apps" + packagePolicySystem "Control system policies related to apps that are installed on the device" + storeAppInstall "Store app installation" + appLicensing "App Licensing" + broadFileSystemAccess "File System" + allowElevation "Run as administrator" + unvirtualizedResources "Write registry entries and files that are not cleaned up on uninstall" +END + +STRINGTABLE +BEGIN + extendedExecution "Allows the app to continue to perform operations for a period of time after entering the background" + appointmentsSystem "Allows the app to read and modify all appointments on the user's calendar" + contactsSystem "Allows the app to read information about contacts that have been designated as restricted or sensitive, and to modify existing contact information." + phoneCallSystem "Allows the app to access all phone lines on the device" + userDataAccounts "Allows the program to access user data such as email, contacts, calendar, etc." + userDataTasksSystem "Access to system tasks" +END + +#endif // Ӣ() resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/AppInstaller/AppInstaller.vcxproj b/AppInstaller/AppInstaller.vcxproj new file mode 100644 index 0000000..90b29e4 --- /dev/null +++ b/AppInstaller/AppInstaller.vcxproj @@ -0,0 +1,333 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Release + ARM + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {D417C165-3F17-40C4-8C7B-0F5AACEF62C5} + Win32Proj + AppInstaller + + + + Application + true + v140 + Unicode + true + false + + + Application + true + v140 + Unicode + true + false + + + Application + false + v140 + true + Unicode + true + + + Application + false + v140 + true + Unicode + true + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + ($SolutionDir)\AppLauncher;($SolutionDir)\PackageManagerAdd;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\AppLauncher;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\PackageManagerAdd;($SolutionDir)\Base64Img;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\Base64Img;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\ToastNotification;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\PriReader2;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\CertificateManager;$(IncludePath) + + + true + ($SolutionDir)\AppLauncher;($SolutionDir)\PackageManagerAdd;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\AppLauncher;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\PackageManagerAdd;($SolutionDir)\Base64Img;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\Base64Img;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\ToastNotification;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\PriReader2;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\CertificateManager;$(IncludePath) + + + true + + + false + ($SolutionDir)\AppLauncher;($SolutionDir)\PackageManagerAdd;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\AppLauncher;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\PackageManagerAdd;($SolutionDir)\Base64Img;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\Base64Img;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\ToastNotification;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\PriReader2;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\CertificateManager;$(IncludePath) + + + false + ($SolutionDir)\AppLauncher;($SolutionDir)\PackageManagerAdd;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\AppLauncher;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\PackageManagerAdd;($SolutionDir)\Base64Img;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\Base64Img;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\ToastNotification;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\PriReader2;E:\Profiles\Bruce\Documents\Visual Studio 2015\Projects\AppInstaller\CertificateManager;$(IncludePath) + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + shlwapi.lib;dwmapi.lib;crypt32.lib;$(OutDir)PackageManager.lib;$(OutDir)AppLauncher.lib;$(OutDir)Base64Img.lib;$(OutDir)ToastNotification.lib;$(OutDir)PriReader2.lib;$(OutDir)CertificateManager.lib + RequireAdministrator + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + shlwapi.lib;dwmapi.lib;crypt32.lib;$(OutDir)PackageManager.lib;$(OutDir)AppLauncher.lib;$(OutDir)Base64Img.lib;$(OutDir)ToastNotification.lib;$(OutDir)PriReader2.lib;$(OutDir)CertificateManager.lib + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + + + Full + true + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + + + Windows + true + true + true + shlwapi.lib;dwmapi.lib;crypt32.lib;$(OutDir)PackageManager.lib;$(OutDir)AppLauncher.lib;$(OutDir)Base64Img.lib;$(OutDir)ToastNotification.lib;$(OutDir)PriReader2.lib;$(OutDir)CertificateManager.lib + RequireAdministrator + + + false + + + + + Level3 + + + Full + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + shlwapi.lib;dwmapi.lib;crypt32.lib;$(OutDir)PackageManager.lib;$(OutDir)AppLauncher.lib;$(OutDir)Base64Img.lib;$(OutDir)ToastNotification.lib;$(OutDir)PriReader2.lib;$(OutDir)CertificateManager.lib + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Drawing.dll + + + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Drawing.Design.dll + + + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Windows.Forms.dll + + + + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Xml.Linq.dll + + + + + {285130bc-cbf1-4c7a-a28d-6f5ee6c68384} + + + {911edc63-db20-4d61-9420-583a1c35427f} + + + {22702832-c3fd-48e5-bc7d-3879ca50a2ed} + + + {59131ab7-2a7d-9a09-8223-174c3f5e0f57} + + + {b897969c-6ea9-4dfc-b7e0-94f1c6d94856} + + + {e10c6272-b876-4dc6-9e13-7ca646863b50} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AppInstaller/AppInstaller.vcxproj.filters b/AppInstaller/AppInstaller.vcxproj.filters new file mode 100644 index 0000000..e075e93 --- /dev/null +++ b/AppInstaller/AppInstaller.vcxproj.filters @@ -0,0 +1,178 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + + + 资源文件 + + + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + + + + \ No newline at end of file diff --git a/AppInstaller/base64logo.h b/AppInstaller/base64logo.h new file mode 100644 index 0000000..7457968 --- /dev/null +++ b/AppInstaller/base64logo.h @@ -0,0 +1,291 @@ +#pragma once +#include "Base64Img.h" +#include +#include +#include +#include "pkgcode.h" +#include "priread.h" + +std::string GetFileNameWithoutExtension (LPCSTR filePath) +{ + char pathCopy [MAX_PATH]; + lstrcpynA (pathCopy, filePath, MAX_PATH); + char *fileName = PathFindFileNameA (pathCopy); + PathRemoveExtensionA (fileName); + return std::string (fileName); +} +std::wstring GetFileNameWithoutExtension (LPCWSTR filePath) +{ + wchar_t pathCopy [MAX_PATH]; + lstrcpynW (pathCopy, filePath, MAX_PATH); + wchar_t *fileName = PathFindFileNameW (pathCopy); + PathRemoveExtensionW (fileName); + return std::wstring (fileName); +} +std::string GetFileNameWithoutExtension (const std::string &filePath) +{ + return GetFileNameWithoutExtension (filePath.c_str ()); +} +std::wstring GetFileNameWithoutExtension (const std::wstring &filePath) +{ + return GetFileNameWithoutExtension (filePath.c_str ()); +} + +std::string GetLogoBase64FromReader (PackageReader &reader, IStream **getOutput = NULL) +{ + if (!&reader) return std::string (""); + if (!reader.isAvailable ()) return std::string (""); + std::wstring logoPath = reader.getPropertyLogo (); + if (logoPath.empty () || logoPath.length () == 0) return std::string (""); + PriReader pri (reader.getPriFileStream ()); + if (pri.isAvailable ()) + { + std::wstring logoPathFromPri = pri.findFilePathValue (logoPath); + if (!logoPathFromPri.empty () && logoPath.length () > 0) logoPath = logoPathFromPri; + } + IStream *imgfile = reader.extractFileToStream (logoPath); + if (getOutput) *getOutput = imgfile; + if (!imgfile) + { + std::wstring fileName = GetFileNameWithoutExtension (logoPath); + IAppxPackageReader *appxreader = reader.getAppxPackageReader (); + CComPtr fe = NULL; + HRESULT hr = appxreader->GetPayloadFiles (&fe); + if (SUCCEEDED (hr) && fe) + { + std::vector files; + BOOL hasCurrent = FALSE; + hr = fe->GetHasCurrent (FALSE); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr ifile = NULL; + hr = fe->GetCurrent (&ifile); + if (SUCCEEDED (hr) && ifile) + { + LPWSTR lpstr = NULL; + if (SUCCEEDED (ifile->GetName (&lpstr)) && lpstr) + { + std::wstring strWillSearch = StringToUpper (StringTrim (lpstr)); + std::wstring strWillToSearch = StringToUpper (StringTrim (fileName)); + if (StrStrW (strWillSearch.c_str (), strWillToSearch.c_str ())) + { + bool isFind = LabelEqual (PathFindExtensionW (lpstr), L".png"); + if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".jpg"); + if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".jpeg"); + if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".bmp"); + if (isFind) + { + std::wstring temp (L""); + if (lpstr) temp += lpstr; + if (temp.length () > 0) push_no_repeat (files, temp); + } + } + } + } + } + bool isFindSuit = false; + { + std::map scaleFiles; + std::wregex pattern (L"(scale-(\\d+))"); + for (auto it : files) + { + if (StrStrW (it.c_str (), L"contrast-")) continue; + std::wsmatch match; + if (std::regex_search (it, match, pattern)) + { + int temp = StrToIntW (match [1].str ().c_str ()); + if (!temp) + { + scaleFiles [temp] = it; + } + } + } + if (scaleFiles.find (GetDPI ()) != scaleFiles.end ()) + { + isFindSuit = true; + logoPath = scaleFiles [GetDPI ()]; + } + else + { + bool isFindScale = false; + for (auto it : scaleFiles) + { + if (it.first >= GetDPI ()) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + if (!isFindScale) + { + for (auto it : scaleFiles) + { + if (it.first >= 100) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + } + if (!isFindScale) + { + for (auto it : scaleFiles) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + isFindSuit = isFindScale; + } + } + if (!isFindSuit) + { + std::map scaleFiles; + std::wregex pattern (L"(scale-(\\d+))"); + for (auto it : files) + { + if (StrStrW (it.c_str (), L"contrast-white")) continue; + std::wsmatch match; + if (std::regex_search (it, match, pattern)) + { + int temp = StrToIntW (match [1].str ().c_str ()); + if (!temp) + { + scaleFiles [temp] = it; + } + } + } + if (scaleFiles.find (GetDPI ()) != scaleFiles.end ()) + { + isFindSuit = true; + logoPath = scaleFiles [GetDPI ()]; + } + else + { + bool isFindScale = false; + for (auto it : scaleFiles) + { + if (it.first >= GetDPI ()) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + if (!isFindScale) + { + for (auto it : scaleFiles) + { + if (it.first >= 100) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + } + if (!isFindScale) + { + for (auto it : scaleFiles) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + isFindSuit = isFindScale; + } + } + if (!isFindSuit) + { + std::map scaleFiles; + std::wregex pattern (L"(scale-(\\d+))"); + for (auto it : files) + { + if (StrStrW (it.c_str (), L"contrast-black")) continue; + std::wsmatch match; + if (std::regex_search (it, match, pattern)) + { + int temp = StrToIntW (match [1].str ().c_str ()); + if (!temp) + { + scaleFiles [temp] = it; + } + } + } + if (scaleFiles.find (GetDPI ()) != scaleFiles.end ()) + { + isFindSuit = true; + logoPath = scaleFiles [GetDPI ()]; + } + else + { + bool isFindScale = false; + for (auto it : scaleFiles) + { + if (it.first >= GetDPI ()) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + if (!isFindScale) + { + for (auto it : scaleFiles) + { + if (it.first >= 100) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + } + if (!isFindScale) + { + for (auto it : scaleFiles) + { + isFindScale = true; + logoPath = scaleFiles [GetDPI ()]; + break; + } + } + isFindSuit = isFindScale; + } + } + if (!isFindSuit) + { + for (auto it : files) + { + logoPath = std::wstring (L"") + it; + break; + } + } + } + imgfile = reader.extractFileToStream (logoPath); + } + if (getOutput) *getOutput = imgfile; + if (!imgfile) return std::string (""); + std::string b64res (""); + LPSTR szRes = StreamToBase64 (imgfile); + if (!getOutput) + { + if (imgfile) + { + imgfile->Release (); + imgfile = NULL; + } + } + if (!szRes) return b64res; + if (szRes) b64res += szRes; + free (szRes); + if (b64res.length () > 0) + { + b64res = "data:image/png;base64," + b64res; + } + return b64res; +} \ No newline at end of file diff --git a/AppInstaller/initread.h b/AppInstaller/initread.h new file mode 100644 index 0000000..da43915 --- /dev/null +++ b/AppInstaller/initread.h @@ -0,0 +1,194 @@ +#pragma once +#include +#include +#include +#include +#include "pkgcode.h" + +unsigned _wtou (const wchar_t *str) +{ + unsigned value = 0; + if (str) + { + swscanf (str, L"%u", &value); + } + return value; +} +unsigned long _wtoul (const wchar_t *str) +{ + unsigned value = 0; + if (str) + { + swscanf (str, L"%'u", &value); + } + return value; +} +unsigned long long _wtou64 (const wchar_t *str) +{ + unsigned long long value = 0; + if (str) + { + swscanf (str, L"%llu", &value); + } + return value; +} +double _wtod (const wchar_t *str) +{ + if (!str || !*str) return 0.0; // ַָ + double value = 0.0; + if (swscanf (str, L"%lg", &value) == 1) + { + return value; + } + return 0.0; // ʧʱ 0.0 +} + +std::string GetPrivateProfileStringA (std::string filePath, std::string section, std::string key, LPCSTR defaultValue = "") +{ + char buf [32768] = {0}; + GetPrivateProfileStringA (section.c_str (), key.c_str (), defaultValue, buf, 32767, filePath.c_str ()); + return buf; +} +std::wstring GetPrivateProfileStringW (std::wstring filePath, std::wstring section, std::wstring key, LPCWSTR defaultValue = L"") +{ + WCHAR buf [32768] = {0}; + GetPrivateProfileStringW (section.c_str (), key.c_str (), defaultValue, buf, 32767, filePath.c_str ()); + return buf; +} +UINT GetPrivateProfileIntA (std::string filePath, std::string section, std::string key, INT defaultValue = 0) +{ + return GetPrivateProfileIntA (section.c_str (), key.c_str (), defaultValue, filePath.c_str ()); +} +UINT GetPrivateProfileIntW (std::wstring filePath, std::wstring section, std::wstring key, INT defaultValue = 0) +{ + return GetPrivateProfileIntW (section.c_str (), key.c_str (), defaultValue, filePath.c_str ()); +} + +class WInitFile +{ + private: + std::wstring m_filePath; + template std::wstring numberToString (t src, std::wstring format) + { + WCHAR buf [256] = {0}; + swprintf (buf, format.c_str (), src); + return buf; + } + public: + WInitFile (LPCWSTR lpswFilePath = L""): m_filePath (lpswFilePath) {} + void setFilePath (std::wstring filePath) + { + this->m_filePath = L""; + this->m_filePath += filePath; + } + std::wstring getFilePath () const { return this->m_filePath; } + std::wstring readStringValue (std::wstring section, std::wstring key, std::wstring defaultValue = L"") + { + return GetPrivateProfileStringW (this->m_filePath, section, key, defaultValue.c_str ()); + } + bool readBoolValue (std::wstring section, std::wstring key, bool defaultValue = false) + { + std::wstring res = this->readStringValue (section, key, (defaultValue ? L"true" : L"false")); + if (LabelEqual (res, L"true") || LabelEqual (res, L"zhen") || LabelEqual (res, L"1") || LabelEqual (res, L"yes") || LabelEqual (res, L"")) + { + return true; + } + else if (LabelEqual (res, L"false") || LabelEqual (res, L"jia") || LabelEqual (res, L"0") || LabelEqual (res, L"no") || LabelEqual (res, L"")) + { + return false; + } + return false; + } + int readIntValue (std::wstring section, std::wstring key, int defaultValue = 0) + { + WCHAR buf [256] = {0}; + swprintf (buf, L"%d", defaultValue); + return _wtoi (this->readStringValue (section, key, buf).c_str ()); + } + unsigned readUIntValue (std::wstring section, std::wstring key, unsigned defaultValue = 0) + { + WCHAR buf [256] = {0}; + swprintf (buf, L"%u", defaultValue); + return _wtou (this->readStringValue (section, key, buf).c_str ()); + } + long readLongValue (std::wstring section, std::wstring key, long defaultValue = 0) + { + WCHAR buf [256] = {0}; + swprintf (buf, L"%ld", defaultValue); + return _wtol (this->readStringValue (section, key, buf).c_str ()); + } + unsigned long readULongValue (std::wstring section, std::wstring key, unsigned long defaultValue = 0) + { + WCHAR buf [256] = {0}; + swprintf (buf, L"%lu", defaultValue); + return _wtoul (this->readStringValue (section, key, buf).c_str ()); + } + long long readLongLongValue (std::wstring section, std::wstring key, long long defaultValue = 0) + { + WCHAR buf [256] = {0}; + swprintf (buf, L"%lld", defaultValue); + return _wtoll (this->readStringValue (section, key, buf).c_str ()); + } + unsigned long long readULongLongValue (std::wstring section, std::wstring key, unsigned long long defaultValue = 0) + { + WCHAR buf [256] = {0}; + swprintf (buf, L"%llu", defaultValue); + return _wtou64 (this->readStringValue (section, key, buf).c_str ()); + } + float readFloatValue (std::wstring section, std::wstring key, float defaultValue = 0) + { + WCHAR buf [256] = {0}; + swprintf (buf, L"%f", defaultValue); + return _wtof (this->readStringValue (section, key, buf).c_str ()); + } + double readDoubleValue (std::wstring section, std::wstring key, double defaultValue = 0) + { + WCHAR buf [256] = {0}; + swprintf (buf, L"%lf", defaultValue); + return _wtod (this->readStringValue (section, key, buf).c_str ()); + } + bool writeStringValue (std::wstring section, std::wstring key, std::wstring value) + { + return WritePrivateProfileStringW (section.c_str (), key.c_str (), value.c_str (), this->m_filePath.c_str ()); + } + bool writeBoolValue (std::wstring section, std::wstring key, bool value) + { + return this->writeBoolValue (section, key, value ? L"true" : L"false"); + } + bool writeIntValue (std::wstring section, std::wstring key, int value) + { + return this->writeStringValue (section, key, this->numberToString (value, L"%d")); + } + bool writeUIntValue (std::wstring section, std::wstring key, unsigned value) + { + return this->writeStringValue (section, key, this->numberToString (value, L"%u")); + } + bool writeLongValue (std::wstring section, std::wstring key, long value) + { + return this->writeStringValue (section, key, this->numberToString (value, L"%ld")); + } + bool writeULongValue (std::wstring section, std::wstring key, unsigned long value) + { + return this->writeStringValue (section, key, this->numberToString (value, L"%lu")); + } + bool writeLongLongValue (std::wstring section, std::wstring key, long long value) + { + return this->writeStringValue (section, key, this->numberToString (value, L"%lld")); + } + bool writeULongLongValue (std::wstring section, std::wstring key, unsigned long long value) + { + return this->writeStringValue (section, key, this->numberToString (value, L"%llu")); + } + bool writeFloatValue (std::wstring section, std::wstring key, float value) + { + return this->writeStringValue (section, key, this->numberToString (value, L"%g")); + } + bool writeDoublegValue (std::wstring section, std::wstring key, double value) + { + return this->writeStringValue (section, key, this->numberToString (value, L"%g")); + } + bool isAvaliable () + { + return IsFileExists (this->m_filePath); + } +}; \ No newline at end of file diff --git a/AppInstaller/localeex.h b/AppInstaller/localeex.h new file mode 100644 index 0000000..326b816 --- /dev/null +++ b/AppInstaller/localeex.h @@ -0,0 +1,111 @@ +#pragma once +#include +#include +#include +#include + +std::wstring StringToWString (const std::string &str, UINT codePage = CP_ACP) +{ + if (str.empty ()) return std::wstring (); + int len = MultiByteToWideChar (codePage, 0, str.c_str (), -1, nullptr, 0); + if (len == 0) return std::wstring (); + std::wstring wstr (len - 1, L'\0'); + MultiByteToWideChar (codePage, 0, str.c_str (), -1, &wstr [0], len); + return wstr; +} + +std::string GetLocaleInfoA (LCID code, LCTYPE type) +{ + char buf [LOCALE_NAME_MAX_LENGTH] = {0}; + GetLocaleInfoA (code, type, buf, LOCALE_NAME_MAX_LENGTH); + return buf; +} +std::wstring GetLocaleInfoW (LCID code, LCTYPE type) +{ + WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0}; + GetLocaleInfoW (code, type, buf, LOCALE_NAME_MAX_LENGTH); + return buf; +} +int GetLocaleInfoEx (std::wstring lpLocaleName, LCTYPE type, std::wstring &output) +{ + WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0}; + int res = GetLocaleInfoEx (lpLocaleName.c_str (), type, buf, LOCALE_NAME_MAX_LENGTH); + if (&output) output = std::wstring (buf); + return res; +} +BOOL SetLocaleInfoA (LCID code, LCTYPE type, const std::string lcData) +{ + return SetLocaleInfoA (code, type, lcData.c_str ()); +} +BOOL SetLocaleInfoW (LCID code, LCTYPE type, const std::wstring lcData) +{ + return SetLocaleInfoW (code, type, lcData.c_str ()); +} +std::string GetLocaleRestrictedCodeFromLcidA (LCID lcid) +{ + return GetLocaleInfoA (lcid, 89); +} +std::wstring GetLocaleRestrictedCodeFromLcidW (LCID lcid) +{ + return GetLocaleInfoW (lcid, 89); +} +std::string GetLocaleElaboratedCodeFromLcidA (LCID lcid) +{ + return GetLocaleInfoA (lcid, 90); +} +std::wstring GetLocaleElaboratedCodeFromLcidW (LCID lcid) +{ + return GetLocaleInfoW (lcid, 90); +} +LCID LocaleCodeToLcidW (LPCWSTR localeCode) +{ + BYTE buf [LOCALE_NAME_MAX_LENGTH * sizeof (WCHAR)] = {0}; + int res = GetLocaleInfoEx (localeCode, LOCALE_RETURN_NUMBER | LOCALE_ILANGUAGE, (LPWSTR)buf, LOCALE_NAME_MAX_LENGTH); + LCID lcid = *((LCID *)buf); + return lcid; +} +LCID LocaleCodeToLcidA (LPCSTR localeCode) +{ + std::wstring lcWide = StringToWString (std::string (localeCode)); + return LocaleCodeToLcidW (lcWide.c_str ()); +} +std::string GetLocaleRestrictedCodeA (LPCSTR lc) +{ + return GetLocaleInfoA (LocaleCodeToLcidA (lc), 89); +} +std::string GetLocaleRestrictedCodeA (const std::string lc) +{ + return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 89); +} +std::wstring GetLocaleRestrictedCodeW (LPCWSTR lc) +{ + return GetLocaleInfoW (LocaleCodeToLcidW (lc), 89); +} +std::wstring GetLocaleRestrictedCodeW (const std::wstring lc) +{ + return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 89); +} +std::string GetLocaleElaboratedCodeA (LPCSTR lc) +{ + return GetLocaleInfoA (LocaleCodeToLcidA (lc), 90); +} +std::string GetLocaleElaboratedCodeA (const std::string lc) +{ + return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 90); +} +std::wstring GetLocaleElaboratedCodeW (LPCWSTR lc) +{ + return GetLocaleInfoW (LocaleCodeToLcidW (lc), 90); +} +std::wstring GetLocaleElaboratedCodeW (const std::wstring lc) +{ + return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 90); +} +std::string LcidToLocaleCodeA (LCID lcid, char divide = '-') +{ + return GetLocaleRestrictedCodeFromLcidA (lcid) + divide + GetLocaleElaboratedCodeFromLcidA (lcid); +} +std::wstring LcidToLocaleCodeW (LCID lcid, WCHAR divide = L'-') +{ + return GetLocaleRestrictedCodeFromLcidW (lcid) + divide + GetLocaleElaboratedCodeFromLcidW (lcid); +} diff --git a/AppInstaller/mainwnd.cpp b/AppInstaller/mainwnd.cpp new file mode 100644 index 0000000..df82696 --- /dev/null +++ b/AppInstaller/mainwnd.cpp @@ -0,0 +1,1464 @@ +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#ifndef _CRT_NON_CONFORMING_SWPRINTFS +#define _CRT_NON_CONFORMING_SWPRINTFS +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pkgcode.h" +#include "resource.h" +#include "res2.h" +#include "PackageManager.h" +#include "base64logo.h" +#include "AppLauncher.h" +#include "ToastNotification.h" +#include "pkginfo.h" +#include "CertificateManager.h" +#include "initread.h" +#include + +using namespace System; +using namespace System::Windows::Forms; +using namespace System::Threading; + +#define toInt(_String_Managed_Object_) Int32::Parse (_String_Managed_Object_) +#define toDouble(_String_Managed_Object_) Double::Parse (_String_Managed_Object_) +#define toBool(_String_Managed_Object_) Boolean::Parse (_String_Managed_Object_) +#define toDateTime(_String_Managed_Object_) DateTime::Parse (_String_Managed_Object_) + +String ^GetRCString_NET (UINT resID) +{ + size_t bufferSize = 256; + wchar_t* buffer = nullptr; + int length = 0; + do + { + delete [] buffer; + buffer = new wchar_t [bufferSize]; + length = LoadStringW (GetModuleHandle (nullptr), resID, buffer, bufferSize); + if ((size_t)length >= bufferSize) + { + bufferSize += 20; + } + } while ((size_t)length >= bufferSize); + String^ result = gcnew String (buffer); + delete [] buffer; + return result; +} +std::wstring GetRCString_cpp (UINT resID) +{ + size_t bufferSize = 256; + wchar_t* buffer = nullptr; + int length = 0; + do + { + delete [] buffer; + buffer = new wchar_t [bufferSize]; + length = LoadStringW (GetModuleHandle (nullptr), resID, buffer, bufferSize); + if ((size_t)length >= bufferSize) + { + bufferSize += 20; + } + } while ((size_t)length >= bufferSize); + std::wstring result = L""; + result += buffer; + delete [] buffer; + return result; +} +#define GetRCString GetRCString_NET +#define GetRCIntValue(_UINT__resID_) toInt (GetRCString (_UINT__resID_)) +#define GetRCDoubleValue(_UINT__resID_) toDouble (GetRCString (_UINT__resID_)) +#define GetRCBoolValue(_UINT__resID_) toBool (GetRCString (_UINT__resID_)) +#define GetRCDateTimeValue(_UINT__resID_) toDateTime (GetRCString (_UINT__resID_)) +#define rcString(resID) GetRCString (resID) +#define rcInt(resID) GetRCIntValue (resID) +#define rcDouble(resID) GetRCDoubleValue (resID) +#define rcBool(resID) GetRCBoolValue (resID) +#define rcDTime(resID) GetRCDateTimeValue (resID) +#define rcIcon(resID) LoadRCIcon (resID) + +HICON LoadRCIcon (UINT resID) +{ + // Դͼ + HICON hIcon = (HICON)LoadImage (GetModuleHandle (nullptr), MAKEINTRESOURCE (resID), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); + if (hIcon == nullptr) return nullptr; + return hIcon; +} +HRSRC FindResourceByName (LPCWSTR resourceName, LPCWSTR resourceType) +{ + return FindResourceW (GetModuleHandle (nullptr), resourceName, resourceType); +} +HRSRC FindResourceByName (const std::wstring &resourceName, LPCWSTR resourceType) +{ + return FindResourceByName (resourceName.c_str (), resourceType); +} + +System::Drawing::Color GetAeroColor () +{ + DWORD color = 0; + BOOL opaqueBlend = FALSE; + // DwmGetColorizationColor ȡ Aero ɫ + HRESULT hr = DwmGetColorizationColor (&color, &opaqueBlend); + if (SUCCEEDED (hr)) { + BYTE r = (BYTE)((color & 0x00FF0000) >> 16); + BYTE g = (BYTE)((color & 0x0000FF00) >> 8); + BYTE b = (BYTE)(color & 0x000000FF); + return System::Drawing::Color::FromArgb (r, g, b); + } + else { + // ȡʧܣĬɫ + return System::Drawing::Color::FromArgb (0, 120, 215); + } +} +// ɫתΪ HTML ɫֵ (#RRGGBB ʽ) +String ^ColorToHtml (System::Drawing::Color color) +{ + return String::Format ("#{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B); +} +bool IsAppInDarkMode () +{ + HKEY hKey; + DWORD dwValue; + if (RegOpenKeyEx (HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + DWORD dwSize = sizeof (dwValue); + if (RegQueryValueEx (hKey, L"AppsUseLightTheme", NULL, NULL, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS) + { + RegCloseKey (hKey); + return dwValue == 0; + } + RegCloseKey (hKey); + } + return false; +} + +std::wstring StrPrintFormatW (LPCWSTR format, ...) +{ + va_list args; + va_start (args, format); + size_t sizeBuf = 256; + wchar_t* buffer = (wchar_t*)malloc (sizeBuf * sizeof (wchar_t)); + if (!buffer) + { + va_end (args); + return L""; + } + int written = -1; + while (true) + { + written = vswprintf (buffer, sizeBuf, format, args); + if (written >= 0 && static_cast(written) < sizeBuf) + { + break; + } + sizeBuf += 256; + wchar_t* newBuffer = (wchar_t*)realloc (buffer, sizeBuf * sizeof (wchar_t)); + if (!newBuffer) + { + free (buffer); + va_end (args); + return L""; + } + buffer = newBuffer; + } + va_end (args); + std::wstring result (buffer); + free (buffer); + return result; +} + +void SetWebBrowserEmulation () +{ + // ȡӦóĿִļ + String ^appName = System::IO::Path::GetFileNameWithoutExtension (System::Windows::Forms::Application::ExecutablePath); + const wchar_t *appNameWChar = (const wchar_t *)(void *)System::Runtime::InteropServices::Marshal::StringToHGlobalUni (appName); + BOOL is64Bit = FALSE; + IsWow64Process (GetCurrentProcess (), &is64Bit); + HKEY hKey; + long regOpenResult = ERROR_SUCCESS; + if (is64Bit) + { + regOpenResult = RegOpenKeyExW (HKEY_CURRENT_USER, L"SOFTWARE\\WOW6432Node\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", 0, KEY_WRITE, &hKey); + } + else + { + regOpenResult = RegOpenKeyExW (HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", 0, KEY_WRITE, &hKey); + } + if (regOpenResult == ERROR_SUCCESS) + { + DWORD ie11Mode = 11001; + RegSetValueExW (hKey, appNameWChar, 0, REG_DWORD, (const BYTE *)&ie11Mode, sizeof (DWORD)); + RegCloseKey (hKey); + } +} + +#include +#include + +bool IsIeVersion10 () +{ + HKEY hKey; + const wchar_t* ieKeyPath = L"SOFTWARE\\Microsoft\\Internet Explorer"; + const wchar_t* valueName = L"svcVersion"; + DWORD dwType = REG_SZ; + wchar_t version [32]; + DWORD cbData = sizeof (version); + REGSAM samDesired = KEY_READ | KEY_WOW64_64KEY; + if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, ieKeyPath, 0, samDesired, &hKey) != ERROR_SUCCESS) + { + samDesired = KEY_READ | KEY_WOW64_32KEY; + if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, ieKeyPath, 0, samDesired, &hKey) != ERROR_SUCCESS) + { + return false; + } + } + bool isIe10 = false; + if (RegQueryValueExW (hKey, valueName, NULL, &dwType, (LPBYTE)version, &cbData) == ERROR_SUCCESS) + { + std::wstring verStr (version); + size_t dotPos = verStr.find (L'.'); + if (dotPos != std::wstring::npos) + { + int majorVersion = std::stoi (verStr.substr (0, dotPos)); + if (majorVersion == 10) + { + isIe10 = true; + } + } + } + RegCloseKey (hKey); + return isIe10; +} + +size_t EnumerateFilesW (const std::wstring &directory, const std::wstring &filter, + std::vector &outFiles, bool recursive = false) +{ + std::wstring searchPath = directory; + if (!searchPath.empty () && searchPath.back () != L'\\') + { + searchPath += L'\\'; + } + searchPath += filter; + WIN32_FIND_DATAW findData; + HANDLE hFind = FindFirstFileW (searchPath.c_str (), &findData); + if (hFind != INVALID_HANDLE_VALUE) + { + do { + if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + outFiles.push_back (directory + L"\\" + findData.cFileName); + } + } while (FindNextFileW (hFind, &findData)); + FindClose (hFind); + } + if (recursive) { + std::wstring subDirSearchPath = directory + L"\\*"; + hFind = FindFirstFileW (subDirSearchPath.c_str (), &findData); + if (hFind != INVALID_HANDLE_VALUE) + { + do { + if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + wcscmp (findData.cFileName, L".") != 0 && wcscmp (findData.cFileName, L"..") != 0) + { + EnumerateFilesW (directory + L"\\" + findData.cFileName, filter, outFiles, true); + } + } while (FindNextFileW (hFind, &findData)); + FindClose (hFind); + } + } + return outFiles.size (); +} + +std::wstring GetFileDirectoryW (const std::wstring &filePath) +{ + std::wstring directory (L""); + WCHAR *buf = (WCHAR *)calloc (filePath.capacity () + 1, sizeof (WCHAR)); + lstrcpyW (buf, filePath.c_str ()); + PathRemoveFileSpecW (buf); + directory += buf; + free (buf); + return directory; +} + +std::wstring pkgPath = L""; +pkgreader reader; +bool m_silentMode = false; +LPCWSTR m_idenName = L"Microsoft.DesktopAppInstaller"; +PackageInfomation m_pkgInfo; +WInitFile m_initConfig; + +HRESULT SetCurrentAppUserModelID (PCWSTR appID) +{ + typedef HRESULT (WINAPI *SetAppUserModelIDFunc)(PCWSTR); + HMODULE shell32 = LoadLibraryW (L"shell32.dll"); + if (!shell32) return E_FAIL; + auto SetAppUserModelID = (SetAppUserModelIDFunc)GetProcAddress (shell32, "SetCurrentProcessExplicitAppUserModelID"); + if (!SetAppUserModelID) + { + FreeLibrary (shell32); + return E_FAIL; + } + HRESULT hr = SetAppUserModelID (appID); + FreeLibrary (shell32); + return hr; +} + +void ProgressCallback (unsigned progress); + +public ref class MainWnd: public Form +{ + private: + WebBrowser ^webUI; + int page; + System::Collections::Generic::Dictionary ^jsFunctionHandlers; + public: + MainWnd (): page (-1) + { + jsFunctionHandlers = gcnew System::Collections::Generic::Dictionary (); + initWnd (); + } + private: + void initWnd () + { + this->Visible = false; + this->webUI = gcnew WebBrowser (); + this->SuspendLayout (); + this->webUI->Dock = DockStyle::Fill; + this->webUI->DocumentCompleted += gcnew WebBrowserDocumentCompletedEventHandler (this, &MainWnd::eventOnDocumentCompleted); + this->webUI->IsWebBrowserContextMenuEnabled = false; + this->webUI->PreviewKeyDown += gcnew System::Windows::Forms::PreviewKeyDownEventHandler (this, &MainWnd::eventOnPreviewKeyDown_WebBrowser); + this->Controls->Add (this->webUI); + HICON tempIco = LoadRCIcon (ICON_TASKBAR); + if (tempIco) + { + this->Icon = System::Drawing::Icon::FromHandle (IntPtr (tempIco)); + // DestroyIcon (tempIco); + } + unsigned wid = 0, hei = 0; + if (m_initConfig.readBoolValue (L"Settings", L"SavePosBeforeClosing")) + { + wid = m_initConfig.readUIntValue (L"Settings", L"SavePosWidth", + m_initConfig.readUIntValue (L"Settings", L"PosWidth", + (unsigned)_wtol (GetRCString_cpp (INITWIDTH).c_str ()) + ) + ); + hei = m_initConfig.readUIntValue (L"Settings", L"SavePosHeight", + m_initConfig.readUIntValue (L"Settings", L"PosHeight", + (unsigned)_wtol (GetRCString_cpp (INITHEIGHT).c_str ()) + ) + ); + } + else + { + wid = m_initConfig.readUIntValue (L"Settings", L"SavePosWidth", + (unsigned)_wtol (GetRCString_cpp (INITWIDTH).c_str ()) + ); + hei = m_initConfig.readUIntValue (L"Settings", L"SavePosHeight", + (unsigned)_wtol (GetRCString_cpp (INITHEIGHT).c_str ()) + ); + } + this->MinimumSize = System::Drawing::Size ( + m_initConfig.readUIntValue (L"Settings", L"MinPosWidth", (unsigned)_wtol (GetRCString_cpp (LIMITWIDTH).c_str ())), + m_initConfig.readUIntValue (L"Settings", L"MinPosHeight", (unsigned)_wtol (GetRCString_cpp (LIMITHEIGHT).c_str ())) + ); + this->WindowState = (System::Windows::Forms::FormWindowState)m_initConfig.readIntValue (L"Settings", L"WindowPos", (int)System::Windows::Forms::FormWindowState::Normal); + this->ClientSize = System::Drawing::Size (wid, hei); + this->Text = GetRCString (WIN_TITLE); + this->Load += gcnew EventHandler (this, &MainWnd::eventOnCreate); + this->ResizeEnd += gcnew EventHandler (this, &MainWnd::eventOnResizeEnd); + this->ResumeLayout (false); + this->Resize += gcnew System::EventHandler (this, &MainWnd::eventOnResize); + } + void eventOnCreate (System::Object ^sender, System::EventArgs ^e) + { + SetWebBrowserEmulation (); + String ^rootDir = System::IO::Path::GetDirectoryName (System::Windows::Forms::Application::ExecutablePath); + String ^htmlFilePath = System::IO::Path::Combine (rootDir, "HTML\\Index.html"); + if (IsIeVersion10 ()) htmlFilePath = System::IO::Path::Combine (rootDir, "HTML\\IndexIE10.html"); // IE10 (Win8) ع + webUI->Navigate (htmlFilePath); + webUI->ObjectForScripting = this; + } + void eventOnPreviewKeyDown_WebBrowser (System::Object ^sender, System::Windows::Forms::PreviewKeyDownEventArgs ^e) + { + if (e->KeyCode == System::Windows::Forms::Keys::F5 || (e->KeyCode == System::Windows::Forms::Keys::R && e->Control)) + e->IsInputKey = true; + } + void eventOnDocumentCompleted (Object ^sender, WebBrowserDocumentCompletedEventArgs ^e) + { + if (e->Url->ToString () == webUI->Url->ToString ()) + { + eventOnPageLoad (); + } + } + void eventOnResizeEnd (Object ^sender, EventArgs ^e) + { + if (this->WindowState == FormWindowState::Maximized) + { + this->changeMaxDisplayPicJS (true); + } + else if (this->WindowState == FormWindowState::Normal) + { + this->changeMaxDisplayPicJS (false); + } + } + void eventOnResize (Object ^sender, EventArgs ^e) + { + if (this->WindowState == FormWindowState::Maximized) + { + this->changeMaxDisplayPicJS (true); + m_initConfig.writeIntValue (L"Settings", L"WindowPos", (int)this->WindowState); + } + else + { + m_initConfig.writeIntValue (L"Settings", L"WindowPos", 0); + this->changeMaxDisplayPicJS (false); + if (m_initConfig.readBoolValue (L"Settings", L"SavePosBeforeClosing")) + { + m_initConfig.writeUIntValue (L"Settings", L"SavePosWidth", this->Width); + m_initConfig.writeUIntValue (L"Settings", L"SavePosHeight", this->Height); + } + } + } + void eventOnPageLoad () + { + this->Visible = true; + this->setLaunchWhenReadyJS (m_initConfig.readBoolValue (L"Settings", L"LaunchWhenReady", true)); + if (IsIeVersion10 ()) hideFrameJS (false); + Thread ^thread = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskReadFile)); + thread->Start (); + Thread ^thread2 = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskCountDarkMode)); + thread2->Start (); + } + void eventOnPress_button1 () + { + //MessageBox::Show ("һ򵥵Ϣ"); + switch (page) + { + case 1: + { + OpenFileDialog^ openFileDialog = gcnew OpenFileDialog (); + openFileDialog->Title = rcString (DIALOG_WINTITLE); + openFileDialog->Filter = rcString (DIALOG_SELLET_APPX) + "|*.appx;*appxbundle|" + rcString (DIALOG_SELLET_UNI) + "|*.*"; + openFileDialog->FilterIndex = 1; + openFileDialog->RestoreDirectory = true; + if (openFileDialog->ShowDialog () == System::Windows::Forms::DialogResult::OK) + { + System::String^ filePath = openFileDialog->FileName; + std::wstring stdFilePath = msclr::interop::marshal_as (filePath); + pkgPath = stdFilePath; + invokeSetPage (0); + Thread ^thread = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskReadFile)); + thread->SetApartmentState (ApartmentState::STA); + thread->Start (); + } + } break; + case 2: + { + invokeSetPage (3); + Thread ^thread = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskInstallPackage)); + thread->SetApartmentState (ApartmentState::STA); + thread->Start (); + } break; + case 4: + { + // this->setButtonDisabledJS (true); + if (!m_pkgInfo.isPackageApplication ()) + { + this->Close (); break; + } + else + { + std::vector ids; + m_pkgInfo.getApplicationUserModelIDs (ids); + DWORD dwPId = 0; + if (ids.size () == 1) LaunchApp (ids [0].c_str (), &dwPId); + } + // this->setButtonDisabledJS (false); + } break; + case 5: + { + this->Close (); + } break; + } + } + void eventOnPress_button2 () + { + + } + void eventOnPress_buttonBack () + { + + } + void eventOnPress_buttonOption () + { + + } + void eventOnPress_buttonNext () + { + + } + void eventOnPress_buttonMin () + { + if (this->WindowState == System::Windows::Forms::FormWindowState::Minimized) this->WindowState = System::Windows::Forms::FormWindowState::Normal; + else this->WindowState = System::Windows::Forms::FormWindowState::Minimized; + } + void eventOnPress_buttonMax () + { + if (this->WindowState == System::Windows::Forms::FormWindowState::Maximized) + { + this->WindowState = System::Windows::Forms::FormWindowState::Normal; + this->changeMaxDisplayPicJS (false); + } + else + { + this->WindowState = System::Windows::Forms::FormWindowState::Maximized; + this->changeMaxDisplayPicJS (true); + } + } + void eventOnPress_buttonCancel () + { + this->Close (); + } + Object ^CallJSFunction (String ^functionName, ... array ^args) + { + if (webUI->Document != nullptr) + { + try + { + return webUI->Document->InvokeScript (functionName, args); + } + catch (Exception^ ex) + { + MessageBox::Show ("Error calling JavaScript function: " + ex->Message); + return nullptr; + } + } + return nullptr; + } + void setPageJS (int pageSerial) + { + CallJSFunction ("SetPage", gcnew array { pageSerial }); + } + void setLogoBackgroundColorJS (String ^color) + { + if (color == "transparent") + { + color = ColorToHtml (GetAeroColor ()); + } + CallJSFunction ("setImgBackground", gcnew array { color }); + } + void setLogoBackgroundColorJS (System::Drawing::Color ^color) + { + CallJSFunction ("setImgBackground", gcnew array { color }); + } + void setLaunchWhenReadyJS (bool value) + { + CallJSFunction ("SetLaunchWhenReady", gcnew array { value }); + } + void invokeSetLaunchWhenReady (bool value) + { + if (this->InvokeRequired) + { + this->Invoke (gcnew Action (this, &MainWnd::setLaunchWhenReadyJS), value); + } + else + { + setLaunchWhenReadyJS (value); + } + } + void setDisableLaunchWhenReadyJS (bool value) + { + CallJSFunction ("SetLaunchWhenReadyDisable", gcnew array { value }); + } + void invokeSetDisableLaunchWhenReady (bool value) + { + if (this->InvokeRequired) + { + this->Invoke (gcnew Action (this, &MainWnd::setDisableLaunchWhenReadyJS), value); + } + else + { + setDisableLaunchWhenReadyJS (value); + } + } + bool getLaunchWhenReadyJS () + { + return (bool)CallJSFunction ("GetLaunchWhenReady", gcnew array {}); + } + void setWindowTitleJS (String ^value) + { + CallJSFunction ("SetWindowTitle", gcnew array { value }); + } + void setStoreLogoJS (String ^value) + { + CallJSFunction ("SetStoreLogo", gcnew array { value }); + } + void hideFrameJS (bool value) + { + CallJSFunction ("HideFrame", gcnew array { value }); + } + void setTextJS (String ^comID, String ^content) + { + try + { + CallJSFunction ("SetText", gcnew array { comID, content }); + } + catch (System::Exception^ e) + { + Console::WriteLine ("Error setting text for component '" + comID + "': " + e->Message); + } + } + void setProgressTextJS (String ^content) + { + this->setTextJS ("caption-status", content); + } + void changeMaxDisplayPicJS (bool value) + { + CallJSFunction ("ChangeMaxDisplayPic", gcnew array { value }); + } + size_t getTextLineNumberJS (String ^comID) + { + Object ^result = CallJSFunction ("GetTextLineNumber", gcnew array { comID }); + int lineCount = Convert::ToInt32 (result); + if (lineCount < 0) + { + throw gcnew ArgumentException ("Element with ID '" + comID + "' does not exist."); + } + return static_cast(lineCount); + } + size_t getTextOmitAdviceJS (String ^comID, String ^text, size_t limitLines) + { + Object ^result = CallJSFunction ("GetTextOmitAdvice", gcnew array { comID, text, limitLines }); + int lineCount = Convert::ToInt32 (result); + if (lineCount < 0) + { + throw gcnew ArgumentException ("Element with ID '" + comID + "' does not exist."); + } + return static_cast(lineCount); + } + void setPicBoxVisibilityJS (bool value) + { + + CallJSFunction ("SetPicBoxVisibility", gcnew array { value }); + } + void setButtonDisabledJS (bool value) + { + CallJSFunction ("SetButtonDisabled", gcnew array { value }); + } + void setProgressJS (unsigned value) + { + CallJSFunction ("SetProgress", gcnew array { value }); + } + void setDarkModeJS (bool value) + { + CallJSFunction ("SetDarkMode", gcnew array { value }); + } + void invokeSetDarkMode (bool value) + { + if (this->InvokeRequired) + { + this->Invoke (gcnew Action (this, &MainWnd::setDarkModeJS), value); + } + else + { + setDarkModeJS (value); + } + } + void invokeSetProgress (unsigned value) + { + if (this->InvokeRequired) + { + this->Invoke (gcnew Action (this, &MainWnd::setProgressJS), value); + } + else + { + setProgressJS (value); + } + } + void invokeSetProgressText (String ^content) + { + if (this->InvokeRequired) + { + this->Invoke (gcnew Action (this, &MainWnd::setProgressTextJS), content); + } + else + { + setProgressTextJS (content); + } + } + void setPage (int serial) + { + switch (serial) + { + case 0: + setTextJS ("file-loading-text", rcString (PAGE_LOADING)); + break; + case 1: + setTextJS ("caption-title", rcString (PAGE_3_TITLE)); + setTextJS ("button-serial-1-title", rcString (BUTTON_3_SER1)); + setTextJS ("button-serial-1", rcString (BUTTON_3_SER1)); + break; + case 2: + { + std::wstring title = m_pkgInfo.getPropertyName (), titleF = StrPrintFormatW (GetRCString_cpp (PAGE_1_TITLE).c_str (), title.c_str ()); + size_t reduce = getTextOmitAdviceJS (gcnew String ("caption-title"), gcnew String (titleF.c_str ()), (size_t)2); + std::wstring sub = title.substr (0, title.length () - reduce) + (reduce > 3 ? L"..." : L""); + setTextJS ("caption-title", gcnew String (StrPrintFormatW (GetRCString_cpp (PAGE_1_TITLE).c_str (), sub.c_str ()).c_str ())); + } + setTextJS ("caption-ms-store-app", rcString (PAGE_1_APP)); + setTextJS ("caption-publisher", gcnew String (StrPrintFormatW (GetRCString_cpp (PAGE_INFO_PUBLISHER).c_str (), m_pkgInfo.getPropertyPublisher ().c_str ()).c_str ())); + setTextJS ("caption-version", gcnew String (StrPrintFormatW (GetRCString_cpp (PAGE_INFO_VERSION).c_str (), m_pkgInfo.getIdentityVersion ().toStringW ().c_str ()).c_str ())); + setTextJS ("caption-textarea-title", rcString (PAGE_FUNCTIONS)); + { + std::wstring temp = L""; + std::vector caps; + if (m_pkgInfo.getCapabilities (caps)) + { + for (auto it : caps) + { + temp += L'\u2022'; + temp += GetRCString_cpp (CapabilitiesNameToID (it.c_str ())); + temp += L"\n"; + } + } + VERSION pver = m_pkgInfo.getPrerequisiteOSMinVersion (); + if (!pver.isEmpty ()) + { + temp += StrPrintFormatW (GetRCString_cpp (textSupportSystem).c_str (), GetPrerequistOSVersionText (pver).c_str (), pver.toStringW ().c_str ()); + temp += L"\n"; + } + std::vector avec; + if (m_pkgInfo.getIdentityProcessorArchitecture (avec)) + { + temp += GetRCString_cpp (textSupportCPU); + for (size_t cnt = 0; cnt < avec.size (); cnt ++) + { + switch (avec [cnt]) + { + case APPX_PACKAGE_ARCHITECTURE_NEUTRAL: temp += L"Neutral"; break; + case APPX_PACKAGE_ARCHITECTURE_X86: temp += L"x86"; break; + case APPX_PACKAGE_ARCHITECTURE_X64: temp += L"x64"; break; + case APPX_PACKAGE_ARCHITECTURE_ARM: temp += L"Arm"; break; + default: + if ((UINT)avec [cnt] == 12) temp += L"Arm64"; + } + if (cnt + 1 != avec.size ()) temp += L", "; + } + temp += L"\n"; + } + std::vector deps; + if (m_pkgInfo.getDependencies (deps)) + { + temp += GetRCString_cpp (textDependency) + L"\n"; + for (size_t cnt = 0; cnt < deps.size (); cnt ++) + { + temp += StrPrintFormatW (GetRCString_cpp (textDependencyItem).c_str (), deps [cnt].name.c_str (), deps [cnt].versionMin.toStringW ().c_str ()); + temp += L"\n"; + } + } + std::vector lvec; + if (m_pkgInfo.getResourceLanguages (lvec)) + { + WCHAR buf [86] = {0}; + for (auto it : lvec) + { + int res = GetLocaleInfoEx (it.c_str (), 2, buf, 86); + if (lstrlenW (buf) > 0) + { + temp += L'\u2022' + std::wstring (buf) + L"\n"; + } + } + } + setTextJS ("caption-more-info", gcnew String (temp.c_str ())); + } + setTextJS ("caption-check-box-label", rcString (PAGE_CHECK_RUNWHENREADY)); + setTextJS ("button-serial-1-title", rcString (BUTTON_1_SER1)); + setTextJS ("button-serial-1", rcString (BUTTON_1_SER1)); + break; + case 3: + { + invokeSetProgressText (rcString (PAGE_2_LOADING)); + std::wstring title = m_pkgInfo.getPropertyName (), titleF = StrPrintFormatW (GetRCString_cpp (PAGE_2_TITLE).c_str (), title.c_str ()); + size_t reduce = getTextOmitAdviceJS (gcnew String ("caption-title"), gcnew String (titleF.c_str ()), (size_t)2); + std::wstring sub = title.substr (0, title.length () - reduce) + (reduce > 3 ? L"..." : L""); + setTextJS ("caption-title", gcnew String (StrPrintFormatW (GetRCString_cpp (PAGE_2_TITLE).c_str (), sub.c_str ()).c_str ())); + } + break; + case 4: + { + std::wstring title = m_pkgInfo.getPropertyName (), titleF = StrPrintFormatW (GetRCString_cpp (PAGE_4_TITLE).c_str (), title.c_str ()); + size_t reduce = getTextOmitAdviceJS (gcnew String ("caption-title"), gcnew String (titleF.c_str ()), (size_t)2); + std::wstring sub = title.substr (0, title.length () - reduce) + (reduce > 3 ? L"..." : L""); + setTextJS ("caption-title", gcnew String (StrPrintFormatW (GetRCString_cpp (PAGE_4_TITLE).c_str (), sub.c_str ()).c_str ())); + } + { + std::vector avec; + if (m_pkgInfo.getApplicationUserModelIDs (avec)) + { + setTextJS ("button-serial-1-title", rcString (BUTTON_4_SER1)); + setTextJS ("button-serial-1", rcString (BUTTON_4_SER1)); + } + else + { + setTextJS ("button-serial-1-title", rcString (BUTTON_5_SER1)); + setTextJS ("button-serial-1", rcString (BUTTON_5_SER1)); + } + } + break; + case 5: + { + std::wstring title = m_pkgInfo.getPropertyName (), titleF = StrPrintFormatW (GetRCString_cpp (PAGE_5_TITLE).c_str (), title.c_str ()); + size_t reduce = getTextOmitAdviceJS (gcnew String ("caption-title"), gcnew String (titleF.c_str ()), (size_t)2); + std::wstring sub = title.substr (0, title.length () - reduce) + (reduce > 3 ? L"..." : L""); + setTextJS ("caption-title", gcnew String (StrPrintFormatW (GetRCString_cpp (PAGE_5_TITLE).c_str (), sub.c_str ()).c_str ())); + if (GetLastErrorDetailTextLength ()) setTextJS ("caption-more-info", gcnew String (GetLastErrorDetailText ())); + else setTextJS ("caption-more-info", gcnew String (L"")); + } + setTextJS ("button-serial-1-title", rcString (BUTTON_5_SER1)); + setTextJS ("button-serial-1", rcString (BUTTON_5_SER1)); + } + setPageJS (serial); + if (serial > 1) + { + std::string res = m_pkgInfo.getPropertyLogoBase64 (); + if (!res.empty () && res.length () > 0) + { + std::string b64logo = res; + // MessageBox::Show (gcnew String ((std::string ("Base 64 String: ") + b64logo).c_str ())); + this->setStoreLogoJS (gcnew String (res.c_str ())); + setPicBoxVisibilityJS (true); + } + else setPicBoxVisibilityJS (false); + } + else + { + setPicBoxVisibilityJS (false); + } + page = serial; + } + void invokeSetPage (int page) + { + if (this->InvokeRequired) + { + this->Invoke (gcnew Action (this, &MainWnd::setPage), page); + } + else + { + setPage (page); + } + } + void invokeSetColor (String ^color) + { + if (this->InvokeRequired) + { + this->Invoke (gcnew Action (this, &MainWnd::setLogoBackgroundColorJS), color); + } + else + { + setLogoBackgroundColorJS (color); + } + } + void setTaskbarProgress (int progress) + { + IntPtr hwnd = this->Handle; + ITaskbarList3* pTaskbarList = nullptr; + HRESULT hr = CoCreateInstance (CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&pTaskbarList); + if (SUCCEEDED (hr) && pTaskbarList) + { + pTaskbarList->HrInit (); + pTaskbarList->SetProgressState ((HWND)hwnd.ToPointer (), TBPF_NORMAL); + pTaskbarList->SetProgressValue ((HWND)hwnd.ToPointer (), progress, 100); + pTaskbarList->Release (); + } + } + void clearTaskbarProgress () + { + IntPtr hwnd = this->Handle; + // ȡ ITaskbarList3 ӿ + ITaskbarList3* pTaskbarList = nullptr; + HRESULT hr = CoCreateInstance (CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&pTaskbarList); + if (SUCCEEDED (hr) && pTaskbarList) + { + pTaskbarList->HrInit (); + // ״̬ + pTaskbarList->SetProgressState ((HWND)hwnd.ToPointer (), TBPF_NOPROGRESS); + // ͷ ITaskbarList3 ӿ + pTaskbarList->Release (); + } + } + bool invokeGetLaunchWhenReady () + { + if (this->InvokeRequired) + { + return (bool)this->Invoke (gcnew Func (this, &MainWnd::getLaunchWhenReadyJS)); + } + else + { + return getLaunchWhenReadyJS (); + } + } + [STAThread] + void taskReadFile () + { + m_pkgInfo.destroy (); + if (IsFileExistsW (pkgPath.c_str ())) reader.create (pkgPath); + if (reader.isAvailable ()) + { + m_pkgInfo.create (reader); + std::vector color; + m_pkgInfo.getApplicationVisualElementsBackgroundColor (color); + // if (page < 0) invokeSetPage (2); + if (color.size () > 0) + { + invokeSetColor (gcnew String (color [0].c_str ())); + } + invokeSetPage (2); + if (m_silentMode) + { + invokeSetDisableLaunchWhenReady (true); + invokeSetLaunchWhenReady (false); + invokeSetPage (3); + Thread ^thread = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskInstallPackage)); + thread->SetApartmentState (ApartmentState::STA); + thread->Start (); + } + } + else + { + if (m_silentMode) + { + // ڴ˰汾УھĬģʽ´ЧİԶرմڽ + this->Close (); + } + else + { + invokeSetPage (1); + } + } + this->invokeSetDarkMode (IsAppInDarkMode ()); + EmptyWorkingSet ((HANDLE)-1); + } + void taskInstallPackage () + { + invokeSetProgressText (rcString (PAGE_2_LOADCERT)); + /* + std::vector cerfiles; + EnumerateFilesW (GetFileDirectoryW (pkgPath.c_str ()), L"*.cer", cerfiles, false); + for (auto it : cerfiles) + { + bool res = LoadCertFromCertFile (it.c_str ()); + std::wstring outputDe = L"File: " + it + L", Result: " + (res ? L"true" : L"false"); + OutputDebugStringW (outputDe.c_str ()); + } + */ + LoadCertFromSignedFile (pkgPath.c_str ()); + invokeSetProgressText (rcString (PAGE_2_INSTALL)); + InstallStatus status = AddPackageFromPath (pkgPath.c_str (), &ProgressCallback); + // MessageBeep (MB_OK); + if (status == InstallStatus::Success) + { + invokeSetPage (4); + if (this->invokeGetLaunchWhenReady ()) + { + if (reader.isPackageApplication ()) this->eventOnPress_button1 (); // APP + } + Thread ^closeThread = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskCountCancel)); + closeThread->IsBackground = true; + closeThread->Start (); + } + else + { + invokeSetPage (5); + if (m_silentMode) + { + Thread ^closeThread = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskCountCancel)); + closeThread->IsBackground = true; + closeThread->Start (); + } + } + this->clearTaskbarProgress (); + std::wstring title = StrPrintFormatW (GetRCString_cpp (PAGE_4_TITLE).c_str (), m_pkgInfo.getPropertyName ().c_str ()); + std::wstring text (L""); + if (GetLastErrorDetailTextLength ()) text += GetLastErrorDetailText (); + bool res = CreateToastNotification (m_idenName, title.c_str (), text.c_str (), NULL, m_pkgInfo.getPropertyLogoIStream ()); + #ifdef _DEBUG + //MessageBox::Show (res ? "Toast has create! " : "Toast created failed! "); + #endif + EmptyWorkingSet ((HANDLE)-1); + } + void taskCountCancel () + { + for (char cnt = 0; cnt < 100; cnt ++) + { + if (!this->IsHandleCreated) break; + Thread::Sleep (50); + } + if (this->IsHandleCreated) + { + this->Invoke (gcnew MethodInvoker (this, &MainWnd::Close)); + } + } + void taskCountDarkMode () + { + for (char cnt = 0; cnt < 8; cnt ++) + { + if (!this->IsHandleCreated) + { + break; + } + else + { + if (!this->webUI->IsHandleCreated) + { + break; + } + } + Thread::Sleep (50); + } + if (this->IsHandleCreated) + { + if (this->webUI->IsHandleCreated) + { + this->invokeSetDarkMode (IsAppInDarkMode ()); + } + } + } + public: + [STAThread] + void Button1_PressEvent () { eventOnPress_button1 (); } + [STAThread] + void Button2_PressEvent () { eventOnPress_button2 (); } + [STAThread] + void PageBackEvent () { eventOnPress_buttonBack (); } + [STAThread] + void WinOptionEvent () { eventOnPress_buttonOption (); } + [STAThread] + void PageNextEvent () { eventOnPress_buttonNext (); } + [STAThread] + void WinMinEvent () { eventOnPress_buttonMin (); } + [STAThread] + void WinMaxEvent () { eventOnPress_buttonMax (); } + [STAThread] + void WinCancelEvent () { eventOnPress_buttonCancel (); } + void funcSetProgress (unsigned value) + { + this->invokeSetProgress (value); + invokeSetProgressText ( + gcnew String ( + StrPrintFormatW (GetRCString_cpp (PAGE_2_INSTALLING).c_str (), (int)value).c_str () + ) + ); + this->setTaskbarProgress ((unsigned)value); + } +}; + +typedef struct _CMDARGUMENT +{ + std::vector front; + std::vector body; + std::vector rear; + int flag; +} CMDARGUMENT; + +std::vector cmdargs = +{ + {{L"", L"/", L"-"}, {L"DISABLEFRAME", L"NOCUSTOM", L"WIN32FRAME", L"ORIGINALBORDER"}, {}, 1}, + {{L"", L"/", L"-"}, {L"SILENT", L"QUIET", L"PASSIVE"}, {}, 2}, + {{L"", L"/", L"-"}, {L"VERYSILENT", L"VERYQUIET"}, {}, 3}, + {{L"", L"/", L"-"}, {L"NOGUI", L"CMD"}, {}, 4}, + {{L"", L"/", L"-"}, {L"HELP", L"?", L"H"}, {}, 5}, + {{L"", L"/", L"-"}, {L"ENABLEFRAME", L"CUSTOM", L"EXFRAME", L"CUSTOMBORDER", L"NEWFRAME"}, {}, 6}, + {{L"", L"/", L"-"}, {L"WIN32WINDOW", L"USEWIN32", L"USEWIN32WINDOW", L"NOWEBUI", L"DISABLEWEBUI"}, {}, 7}, + {{L"", L"/", L"-"}, {L"CREATESHORTCUT", L"SHORTCUT", L"CREATELNK"}, {}, 8}, + {{L"", L"/", L"-"}, {L"DELETESHORTCUT", L"DELSHORTCUT", L"DELETELNK"}, {}, 9}, + {{L"", L"/", L"-"}, {L"DEVTOOL", L"DEVTOOLS", L"DEVMODE", L"DEVELOP"}, {}, 10}, + {{L"", L"/", L"-"}, {L"USEEPROGRAM", L"EPROGRAM", L"ESUPPORT", L"USEE"}, {}, 11} +}; + +// Ϊ 0 ʧܷط +int GetCmdArgSerial (std::wstring cmdparam) +{ +#define tolabel(__std_wstring__) StringToUpper (StringTrim (__std_wstring__)) + std::wstring arg = tolabel (cmdparam); + for (size_t cnt = 0; cnt < cmdargs.size (); cnt ++) + { + CMDARGUMENT &tca = cmdargs [cnt]; + std::wstring tempP = L""; + for (size_t i = 0; i < tca.body.size (); i ++) + { + if (tca.rear.size () > 0) + { + if (tca.front.size () > 0) + { + for (size_t j = 0; j < tca.front.size (); j ++) + { + for (size_t k = 0; k < tca.rear.size (); k ++) + { + tempP = tolabel (tca.front [j]) + tolabel (tca.body [i]) + tolabel (tca.rear [k]); + std::wstring t1; + if (tolabel (tca.rear [k]).length () > 0) t1 = arg.substr (0, tempP.length ()); + else t1 = tempP; + if (t1 == arg) return tca.flag; + } + } + } + else + { + for (size_t k = 0; k < tca.rear.size (); k ++) + { + tempP = tolabel (tca.body [i]) + tolabel (tca.rear [k]); + std::wstring t1; + if (tolabel (tca.rear [k]).length () > 0) t1 = arg.substr (0, tempP.length ()); + else t1 = tempP; + if (t1 == arg) return tca.flag; + } + } + } + else + { + if (tca.front.size () > 0) + { + for (size_t j = 0; j < tca.front.size (); j ++) + { + tempP = tolabel (tca.front [j]) + tolabel (tca.body [i]); + std::wstring &t1 = tempP; + if (t1 == arg) return tca.flag; + } + } + else + { + tempP = tolabel (tca.body [i]); + std::wstring &t1 = tempP; + if (t1 == arg) return tca.flag; + } + } + } + } + return 0; // 0 C/C++ ߼ж +} +int GetCmdArgSerial (LPCWSTR cmdparam) { return GetCmdArgSerial (std::wstring (cmdparam)); } + +// ʱִ GUI +[MTAThread] +bool ReadCommand (int argc, LPWSTR *argv) +{ + std::vector vecObjSwFiles; + bool bWin32Wnd = false, bSilent = false, bVerySilent = false, + bUseConsole = false, bUseNewFrame = false, bDisplayHelp = false, + bCreateLnk = false, bDestroyLnk = false, bDevTool = false, + bUseEProgream = false; + for (size_t cnt = 0; cnt < (size_t)argc; cnt ++) + { + int res = GetCmdArgSerial (argv [cnt]); + if (res > 0) + { + switch (res) + { + case 1: bUseNewFrame = false; break; + case 2: bSilent = true; break; + case 3: bVerySilent = true; break; + case 4: bUseConsole = true; break; + case 5: bDisplayHelp = true; break; + case 6: bUseNewFrame = true; break; + case 7: bWin32Wnd = true; break; + case 8: bCreateLnk = true; break; + case 9: bDestroyLnk = true; break; + case 10: bDevTool = true; break; + case 11: bUseEProgream = true; break; + } + } + else + { + if (IsFileExistsW (argv [cnt])) push_no_repeat (vecObjSwFiles, argv [cnt]); + } + } + bWin32Wnd = bWin32Wnd | !m_initConfig.readBoolValue (L"Settings", L"UseWebUI", true); + bUseEProgream = bUseEProgream | m_initConfig.readBoolValue (L"Settings", L"UseElderWebUI", false); + bUseNewFrame = bUseNewFrame | m_initConfig.readBoolValue (L"WebUI", L"UseNewFrame", false); + if (bDisplayHelp) // ʾ + { + MessageBox::Show ( + rcString (CLHELP_1) + + rcString (CLHELP_2) + + rcString (CLHELP_4) + + rcString (CLHELP_5) + + rcString (CLHELP_7) + ); + return false; + } + if (bCreateLnk) + { + WCHAR expandedPath [MAX_PATH]; + ExpandEnvironmentStringsW (L"%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Desktop App Installer", expandedPath, MAX_PATH); + if (IsDirectoryExists (expandedPath) || CreateDirectoryW (expandedPath, NULL)) + { + WCHAR lnkPath [MAX_PATH]; + PathCombineW (lnkPath, expandedPath, L"App Installer.lnk"); + WCHAR path [MAX_PATH] = {0}; + GetModuleFileNameW (NULL, path, MAX_PATH); + HRESULT hr = CreateShortcutWithAppIdW (lnkPath, path, m_idenName); + if (SUCCEEDED (hr)) + { + WCHAR desktopIni [MAX_PATH]; + PathCombineW (desktopIni, expandedPath, L"desktop.ini"); + WInitFile desktop (desktopIni); + WCHAR resIdStr [16] = {0}; + _itow (WIN_TITLE, resIdStr, 10); + desktop.writeUIntValue (L".ShellClassInfo", L"ConfirmFileOp", 0); + desktop.writeStringValue (L"LocalizedFileNames", L"App Installer.lnk", std::wstring (L"@") + path + L",-" + resIdStr); + DWORD attrs = GetFileAttributesW (desktopIni); + SetFileAttributesW (desktopIni, attrs | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM); + DWORD folderAttrs = GetFileAttributesW (expandedPath); + SetFileAttributesW (expandedPath, folderAttrs | FILE_ATTRIBUTE_SYSTEM); + } + } + return false; + } + if (bDestroyLnk) + { + WCHAR expandedPath [MAX_PATH]; + if (ExpandEnvironmentStringsW (L"%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Desktop App Installer", expandedPath, MAX_PATH)) + { + if (IsDirectoryExists (expandedPath)) + { + WCHAR lnkPath [MAX_PATH]; + PathCombineW (lnkPath, expandedPath, L"App Installer.lnk"); + DeleteFileW (lnkPath); + } + } + return false; + } + m_silentMode = bSilent || bVerySilent; // Զģʽ + if (vecObjSwFiles.size () == 1) + { + pkgPath = vecObjSwFiles [0]; + if (bVerySilent) // Ĭģʽʱֻװʾ GUI + { + LoadCertFromSignedFile (pkgPath.c_str ()); + AddPackageFromPath (pkgPath.c_str (), NULL); + return false; + } + else if (bWin32Wnd) + { + std::wstring root = EnsureTrailingSlash (GetProgramRootDirectoryW ()); + std::wstring exepath = root + L"AppInstaller_win32.exe"; + std::wstring args = L""; + args += L"\"" + pkgPath + L"\" "; + if (bUseNewFrame) args += L"/ENABLEFRAME "; + else args += L"/DISABLEFRAME "; + if (bSilent) args += L"/SILENT "; + if (bVerySilent) args += L"/VERYSILENT "; + if (bUseConsole) args += L"/NOGUI "; + if (bDisplayHelp) args += L"/? "; + std::wstring cmdline = L"\"" + exepath + L"\" " + args; + { + STARTUPINFOW si = {sizeof (STARTUPINFOW)}; + PROCESS_INFORMATION pi = {0}; + if (CreateProcessW (NULL, (LPWSTR)cmdline.c_str (), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + WaitForSingleObject (pi.hProcess, INFINITE); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return false; + } + } + } + else if (bUseEProgream) + { + std::wstring root = EnsureTrailingSlash (GetProgramRootDirectoryW ()); + std::wstring exepath = root + L"AppInstallerE.exe"; + std::wstring args = L""; + args += L"\"" + pkgPath + L"\" "; + if (bUseNewFrame) args += L"/ENABLEFRAME "; + else args += L"/DISABLEFRAME "; + if (bSilent) args += L"/SILENT "; + if (bVerySilent) args += L"/VERYSILENT "; + if (bUseConsole) args += L"/NOGUI "; + if (bDisplayHelp) args += L"/? "; + std::wstring cmdline = L"\"" + exepath + L"\" " + args; + { + STARTUPINFOW si = {sizeof (STARTUPINFOW)}; + PROCESS_INFORMATION pi = {0}; + if (CreateProcessW (NULL, (LPWSTR)cmdline.c_str (), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + WaitForSingleObject (pi.hProcess, INFINITE); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return false; + } + } + } + else if (bUseConsole) + { + std::wstring root = EnsureTrailingSlash (GetProgramRootDirectoryW ()); + std::wstring exepath = root + L"WSAppPkgIns.exe"; + std::wstring args = L""; + args += L"\"" + pkgPath + L"\" "; + std::wstring cmdline = L"\"" + exepath + L"\" " + args; + { + STARTUPINFOW si = {sizeof (STARTUPINFOW)}; + PROCESS_INFORMATION pi = {0}; + if (CreateProcessW (NULL, (LPWSTR)cmdline.c_str (), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + WaitForSingleObject (pi.hProcess, INFINITE); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return false; + } + } + } + return true; + } + else if (vecObjSwFiles.size () <= 0) + { + if (bWin32Wnd) + { + std::wstring root = EnsureTrailingSlash (GetProgramRootDirectoryW ()); + std::wstring exepath = root + L"AppInstaller_win32.exe"; + std::wstring args = L""; + if (bUseNewFrame) args += L"/ENABLEFRAME "; + else args += L"/DISABLEFRAME "; + if (bSilent) args += L"/SILENT "; + if (bVerySilent) args += L"/VERYSILENT "; + if (bUseConsole) args += L"/NOGUI "; + if (bDisplayHelp) args += L"/? "; + std::wstring cmdline = L"\"" + exepath + L"\" " + args; + { + STARTUPINFOW si = {sizeof (STARTUPINFOW)}; + PROCESS_INFORMATION pi = {0}; + if (CreateProcessW (NULL, (LPWSTR)cmdline.c_str (), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + WaitForSingleObject (pi.hProcess, INFINITE); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return false; + } + } + } + else if (bUseEProgream) + { + std::wstring root = EnsureTrailingSlash (GetProgramRootDirectoryW ()); + std::wstring exepath = root + L"AppInstallerE.exe"; + std::wstring args = L""; + if (bUseNewFrame) args += L"/ENABLEFRAME "; + else args += L"/DISABLEFRAME "; + if (bSilent) args += L"/SILENT "; + if (bVerySilent) args += L"/VERYSILENT "; + if (bUseConsole) args += L"/NOGUI "; + if (bDisplayHelp) args += L"/? "; + if (bDevTool) args += L"/DEVTOOL "; + std::wstring cmdline = L"\"" + exepath + L"\" " + args; + { + STARTUPINFOW si = {sizeof (STARTUPINFOW)}; + PROCESS_INFORMATION pi = {0}; + if (CreateProcessW (NULL, (LPWSTR)cmdline.c_str (), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + WaitForSingleObject (pi.hProcess, INFINITE); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return false; + } + } + } + else return true; + } + else if (vecObjSwFiles.size () > 1) // Զļ + { + for (auto it : vecObjSwFiles) + { + wchar_t path [MAX_PATH] = {0}; + if (GetModuleFileNameW (NULL, path, MAX_PATH)) + { + std::wstring args = L""; + args += L"\"" + it + L"\" "; + if (bUseNewFrame) args += L"/ENABLEFRAME "; + else args += L"/DISABLEFRAME "; + if (bSilent) args += L"/SILENT "; + if (bVerySilent) args += L"/VERYSILENT "; + if (bUseConsole) args += L"/NOGUI "; + if (bDisplayHelp) args += L"/? "; + if (bWin32Wnd) args += L"WIN32WINDOW "; + if (bUseEProgream) args += L"/USEEPROGRAM "; + std::wstring cmdline = L"\"" + std::wstring (path) + L"\" " + args; + { + STARTUPINFOW si = {sizeof (STARTUPINFOW)}; + PROCESS_INFORMATION pi = {0}; + if (CreateProcessW (NULL, (LPWSTR)cmdline.c_str (), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + WaitForSingleObject (pi.hProcess, INFINITE); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + } + } + } + } + return false; + } + return false; +} + +// ʱִ GUI +[MTAThread] +bool ReadCommand (LPWSTR lpCmdLine) +{ + int iArgc = 0; + LPWSTR *lpArgv = CommandLineToArgvW (lpCmdLine, &iArgc); + return ReadCommand (iArgc, lpArgv); +} + +msclr::gcroot mainwndPtr; +void SetProgressDisplayWnd (MainWnd ^ptr) +{ + mainwndPtr = ptr; +} +void ProgressCallback (unsigned progress) +{ + mainwndPtr->funcSetProgress (progress); +} + +void OutputDebugStringFormatted (const wchar_t* format, ...) +{ + wchar_t buffer [1024]; + va_list args; + va_start (args, format); + vswprintf (buffer, sizeof (buffer) / sizeof (wchar_t), format, args); + va_end (args); + OutputDebugString (buffer); +} + +[STAThread] +int APIENTRY wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) +{ + SetCurrentProcessExplicitAppUserModelID (m_idenName); + wchar_t currentPath [MAX_PATH]; + GetCurrentDirectory (MAX_PATH, currentPath); + wchar_t executablePath [MAX_PATH]; + GetModuleFileName (NULL, executablePath, MAX_PATH); + std::wstring executableDir (executablePath); + executableDir = executableDir.substr (0, executableDir.find_last_of (L"\\/")); + if (!wcscmp (currentPath, executableDir.c_str ())) + { + SetCurrentDirectory (executableDir.c_str ()); + } + OutputDebugStringFormatted (L"Current Dir: %ls\n", executableDir.c_str ()); + m_initConfig.setFilePath (EnsureTrailingSlash (GetProgramRootDirectoryW ()) + L"Config.ini"); + CoInitializeEx (NULL, COINIT_MULTITHREADED); + Application::EnableVisualStyles (); + Application::SetCompatibleTextRenderingDefault (false); + MainWnd ^mwnd = gcnew MainWnd (); + SetProgressDisplayWnd (mwnd); + if (ReadCommand (lpCmdLine)) + { + Application::Run (mwnd); + } + reader.destroy (); + return 0; +} \ No newline at end of file diff --git a/AppInstaller/pkgcode.h b/AppInstaller/pkgcode.h new file mode 100644 index 0000000..94ea728 --- /dev/null +++ b/AppInstaller/pkgcode.h @@ -0,0 +1,2062 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +template void push_no_repeat (std::vector &vec, t1 &member) +{ + for (size_t cnt = 0; cnt < vec.size (); cnt ++) if (member == vec [cnt]) return; + vec.push_back (member); +} +template void push_no_repeat (std::vector &vec, t &member) +{ + for (size_t cnt = 0; cnt < vec.size (); cnt ++) if (member == vec [cnt]) return; + vec.push_back (member); +} +#define spush_no_repeat push_no_repeat + +typedef IAppxPackageReader *IAPPXREADER; +typedef IAppxBundleReader *IBUNDLEREADER; + +extern "C" bool IsFileExistsW (LPCWSTR filename) +{ + DWORD dwAttrib = GetFileAttributesW (filename); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +} +extern "C" bool IsFileExistsA (LPCSTR filename) +{ + DWORD dwAttrib = GetFileAttributesA (filename); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +} +bool IsFileExists (LPWSTR filePath) { return IsFileExistsW (filePath); } +bool IsFileExists (LPCSTR filePath) { return IsFileExistsA (filePath); } +bool IsFileExists (std::string filePath) { return IsFileExistsA (filePath.c_str ()); } +bool IsFileExists (std::wstring filePath) { return IsFileExistsW (filePath.c_str ()); } + +void GetCapabilitiesName (APPX_CAPABILITIES caps, std::vector &output) +{ + if (!&output) return; + ULONG packageCap = (ULONG)caps; + if (packageCap & APPX_CAPABILITY_INTERNET_CLIENT) spush_no_repeat (output, L"internetClient"); + if (packageCap & APPX_CAPABILITY_INTERNET_CLIENT_SERVER) spush_no_repeat (output, L"internetClientServer"); + if (packageCap & APPX_CAPABILITY_PRIVATE_NETWORK_CLIENT_SERVER) spush_no_repeat (output, L"privateNetworkClientServer"); + if (packageCap & APPX_CAPABILITY_DOCUMENTS_LIBRARY) spush_no_repeat (output, L"documentsLibrary"); + if (packageCap & APPX_CAPABILITY_PICTURES_LIBRARY) spush_no_repeat (output, L"picturesLibrary"); + if (packageCap & APPX_CAPABILITY_VIDEOS_LIBRARY) spush_no_repeat (output, L"videosLibrary"); + if (packageCap & APPX_CAPABILITY_MUSIC_LIBRARY) spush_no_repeat (output, L"musicLibrary"); + if (packageCap & APPX_CAPABILITY_ENTERPRISE_AUTHENTICATION) spush_no_repeat (output, L"enterpriseAuthentication"); + if (packageCap & APPX_CAPABILITY_SHARED_USER_CERTIFICATES) spush_no_repeat (output, L"sharedUserCertificates"); + if (packageCap & APPX_CAPABILITY_REMOVABLE_STORAGE) spush_no_repeat (output, L"removableStorage"); + if (packageCap & 1024) spush_no_repeat (output, L"appointments"); //APPX_CAPABILITY_APPOINTMENTS + if (packageCap & 2048) spush_no_repeat (output, L"contacts"); //APPX_CAPABILITY_CONTACTS + if (packageCap & 0x00001000) spush_no_repeat (output, L"phoneCall"); //APPX_CAPABILITY_PHONE_CALL + if (packageCap & 0x00002000) spush_no_repeat (output, L"blockedChatMessages"); //APPX_CAPABILITY_BLOCKED_CHAT_MESSAGES + if (packageCap & 0x00004000) spush_no_repeat (output, L"objects3D"); //APPX_CAPABILITY_OBJECTS3D + if (packageCap & 0x00008000) spush_no_repeat (output, L"allJoyn"); //APPX_CAPABILITY_ALLJOYN + if (packageCap & 0x00010000) spush_no_repeat (output, L"codeGeneration"); //APPX_CAPABILITY_CODE_GENERATION + if (packageCap & 0x00020000) spush_no_repeat (output, L"remoteSystem"); //APPX_CAPABILITY_REMOTE_SYSTEM + if (packageCap & 0x00040000) spush_no_repeat (output, L"userAccountInformation"); //APPX_CAPABILITY_USER_ACCOUNT_INFORMATION + if (packageCap & 0x00080000) spush_no_repeat (output, L"extendedExecution"); //APPX_CAPABILITY_EXTENDED_EXECUTION + if (packageCap & 0x00100000) spush_no_repeat (output, L"location"); //APPX_CAPABILITY_LOCATION + if (packageCap & 0x00200000) spush_no_repeat (output, L"microphone"); //APPX_CAPABILITY_MICROPHONE + if (packageCap & 0x00400000) spush_no_repeat (output, L"proximity"); //APPX_CAPABILITY_PROXIMITY + if (packageCap & 0x00800000) spush_no_repeat (output, L"webcam"); //APPX_CAPABILITY_WEBCAM + if (packageCap & 0x01000000) spush_no_repeat (output, L"spatialPerception"); //APPX_CAPABILITY_SPATIAL_PERCEPTION + if (packageCap & 0x02000000) spush_no_repeat (output, L"appointmentsSystem"); //APPX_CAPABILITY_APPOINTMENTS_SYSTEM + if (packageCap & 0x04000000) spush_no_repeat (output, L"contactsSystem"); //APPX_CAPABILITY_CONTACTS_SYSTEM + if (packageCap & 0x08000000) spush_no_repeat (output, L"phoneCallSystem"); //APPX_CAPABILITY_PHONE_CALL_SYSTEM + if (packageCap & 0x10000000) spush_no_repeat (output, L"smsSend"); //APPX_CAPABILITY_SMS_SEND + if (packageCap & 0x20000000) spush_no_repeat (output, L"userDataTasks"); //APPX_CAPABILITY_USER_DATA_TASKS + if (packageCap & 0x40000000) spush_no_repeat (output, L"userDataTasksSystem"); //APPX_CAPABILITY_USER_DATA_TASKS_SYSTEM + if (packageCap & 0x80000000) spush_no_repeat (output, L"userDataAccounts"); //APPX_CAPABILITY_USER_DATA_ACCOUNTS +} + +HRESULT GetBundleReader (_In_ LPCWSTR inputFileName, _Outptr_ IAppxBundleReader** bundleReader) +{ + HRESULT hr = S_OK; + IAppxBundleFactory* appxBundleFactory = NULL; + IStream* inputStream = NULL; + hr = CoCreateInstance (__uuidof(AppxBundleFactory), NULL, CLSCTX_INPROC_SERVER, __uuidof(IAppxBundleFactory), (LPVOID*)(&appxBundleFactory)); + if (SUCCEEDED (hr)) + { + hr = SHCreateStreamOnFileEx (inputFileName, STGM_READ | STGM_SHARE_DENY_NONE, 0, FALSE, NULL, &inputStream); + } + if (SUCCEEDED (hr)) + { + hr = appxBundleFactory->CreateBundleReader (inputStream, bundleReader); + } + if (inputStream != NULL) + { + inputStream->Release (); + inputStream = NULL; + } + if (appxBundleFactory != NULL) + { + appxBundleFactory->Release (); + appxBundleFactory = NULL; + } + return hr; +} +HRESULT GetPackageReader (_In_ LPCWSTR inputFileName, _Outptr_ IAppxPackageReader** reader) +{ + HRESULT hr = S_OK; + IAppxFactory* appxFactory = NULL; + IStream* inputStream = NULL; + hr = CoCreateInstance (__uuidof(AppxFactory), NULL, CLSCTX_INPROC_SERVER, __uuidof(IAppxFactory), (LPVOID*)(&appxFactory)); + if (SUCCEEDED (hr)) + { + hr = SHCreateStreamOnFileEx (inputFileName, STGM_READ | STGM_SHARE_DENY_NONE, 0, FALSE, NULL, &inputStream); + } + if (SUCCEEDED (hr)) hr = appxFactory->CreatePackageReader (inputStream, reader); + if (inputStream != NULL) + { + inputStream->Release (); + inputStream = NULL; + } + if (appxFactory != NULL) + { + appxFactory->Release (); + appxFactory = NULL; + } + return hr; +} +HRESULT GetAppxPackageReader (_In_ IStream* inputStream, _Outptr_ IAppxPackageReader** packageReader) +{ + HRESULT hr = S_OK; + IAppxFactory* appxFactory = NULL; + hr = CoCreateInstance (__uuidof(AppxFactory), NULL, CLSCTX_INPROC_SERVER, __uuidof(IAppxFactory), (LPVOID*)(&appxFactory)); + if (SUCCEEDED (hr)) + { + hr = appxFactory->CreatePackageReader (inputStream, packageReader); + } + if (appxFactory != NULL) + { + appxFactory->Release (); + appxFactory = NULL; + } + return hr; +} + +typedef struct VERSION +{ + UINT16 build, maintenance, minor, major; + VERSION (UINT16 major, UINT16 minor, UINT16 maintenance, UINT16 build); + VERSION (UINT64 ver); + VERSION (); + virtual ~VERSION (); + std::wstring toStringW (); + std::string toString (); + bool isEmpty (); + UINT64 getUInt64 (); + INT64 compare (VERSION &another); + bool equals (VERSION &another); + bool operator == (VERSION &another) { return this->equals (another); } + bool operator > (VERSION &another) { return this->getUInt64 () > another.getUInt64 (); } + bool operator < (VERSION &another) { return this->getUInt64 () < another.getUInt64 (); } + bool operator >= (VERSION &another) { return !(*this < another); } + bool operator <= (VERSION &another) { return !(*this > another); } + bool operator != (VERSION &another) { return !this->equals (another); } + static VERSION stringTo (const std::string &str); + static VERSION stringTo (const std::wstring &str); + static VERSION stringTo (LPCSTR str); + static VERSION stringTo (LPCWSTR str); + VERSION setFromString (const std::string &str) + { + VERSION v = stringTo (str); + this->major = v.major; + this->minor = v.minor; + this->maintenance = v.maintenance; + this->build = v.build; + return *this; + } + VERSION setFromString (const std::wstring &str) + { + VERSION v = stringTo (str); + this->major = v.major; + this->minor = v.minor; + this->maintenance = v.maintenance; + this->build = v.build; + return *this; + } + private: + static std::vector splitVersionString (const std::string &str); + static std::vector splitVersionString (const std::wstring &str); +} _VERSION, VERSION, Version, version; +VERSION::VERSION (UINT16 major, UINT16 minor, UINT16 maintenance, UINT16 build): + major (major), minor (minor), maintenance (maintenance), build (build) {} +VERSION::VERSION (UINT64 verdata) : major ((verdata >> 0x30) & 0xFFFF), minor ((verdata >> 0x20) & 0xFFFF), +maintenance ((verdata >> 0x10) & 0xFFFF), build ((verdata) & 0xFFFF) {} +VERSION::VERSION (): major (0), minor (0), maintenance (0), build (0) {} +VERSION::~VERSION () +{ + this->major = 0; + this->minor = 0; + this->maintenance = 0; + this->build = 0; +} +std::wstring VERSION::toStringW () +{ + std::wstringstream ss; + ss << this->major << L'.' << this->minor << L'.' << this->maintenance << L'.' << this->build << std::ends; + std::wstring st (L""); + st += ss.str (); + return st; +} +std::string VERSION::toString () +{ + std::stringstream ss; + ss << this->major << '.' << this->minor << '.' << this->maintenance << '.' << this->build << std::ends; + std::string st (""); + st += ss.str (); + return st; +} +bool VERSION::isEmpty () +{ + return this->getUInt64 () == 0; +} +UINT64 VERSION::getUInt64 () +{ + UINT64 u64 = (((UINT64)major) << 0x30) | (((UINT64)minor) << 0x20) | (((UINT64)maintenance) << 0x10) | ((UINT64)build); + return u64; +} +INT64 VERSION::compare (VERSION &another) +{ + UINT64 u1 = this->getUInt64 (), u2 = another.getUInt64 (); + return u1 - u2; +} +bool VERSION::equals (VERSION &another) +{ + return !this->compare (another); +} +std::vector VERSION::splitVersionString (const std::string &str) +{ + std::vector result; + std::stringstream ss (str); + std::string segment; + while (std::getline (ss, segment, '.')) // Ȱ '.' + { + size_t pos = 0; + while ((pos = segment.find (',')) != std::string::npos) // ٰ ',' + { + result.push_back (segment.substr (0, pos)); + segment.erase (0, pos + 1); + } + result.push_back (segment); + } + return result; +} +std::vector VERSION::splitVersionString (const std::wstring &str) +{ + std::vector result; + std::wstringstream ss (str); + std::wstring segment; + while (std::getline (ss, segment, L'.')) // Ȱ '.' + { + size_t pos = 0; + while ((pos = segment.find (L',')) != std::wstring::npos) // ٰ ',' + { + result.push_back (segment.substr (0, pos)); + segment.erase (0, pos + 1); + } + result.push_back (segment); + } + return result; +} +VERSION VERSION::stringTo (const std::string &str) +{ + std::vector parts = splitVersionString (str); + UINT16 major = (parts.size () > 0) ? static_cast(std::stoi (parts [0])) : 0; + UINT16 minor = (parts.size () > 1) ? static_cast(std::stoi (parts [1])) : 0; + UINT16 maintenance = (parts.size () > 2) ? static_cast(std::stoi (parts [2])) : 0; + UINT16 build = (parts.size () > 3) ? static_cast(std::stoi (parts [3])) : 0; + return VERSION (major, minor, maintenance, build); +} +VERSION VERSION::stringTo (const std::wstring &str) +{ + std::vector parts = splitVersionString (str); + UINT16 major = (parts.size () > 0) ? static_cast(std::stoi (parts [0])) : 0; + UINT16 minor = (parts.size () > 1) ? static_cast(std::stoi (parts [1])) : 0; + UINT16 maintenance = (parts.size () > 2) ? static_cast(std::stoi (parts [2])) : 0; + UINT16 build = (parts.size () > 3) ? static_cast(std::stoi (parts [3])) : 0; + return VERSION (major, minor, maintenance, build); +} +VERSION VERSION::stringTo (LPCSTR str) +{ + return stringTo (std::string (str)); +} +VERSION VERSION::stringTo (LPCWSTR str) +{ + return stringTo (std::wstring (str)); +} +std::wstring GetPrerequistOSVersionText (VERSION &ver) +{ + if (ver >= VERSION (10, 0, 22621, 0)) return std::wstring (L"Windows 11 Version 22H2"); + else if (ver >= VERSION (10, 0, 22159, 0)) return std::wstring (L"Windows 11 Initial Release (Version 21H2)"); + else if (ver >= VERSION (10, 0, 19645, 0)) return std::wstring (L"Windows 10 Insider Preview (Build 19645)"); + else if (ver >= VERSION (10, 0, 19541, 0)) return std::wstring (L"Windows 10 Insider Preview (Build 19541)"); + else if (ver >= VERSION (10, 0, 19045, 0)) return std::wstring (L"Windows 10 Version 22H2"); + else if (ver >= VERSION (10, 0, 19044, 0)) return std::wstring (L"Windows 10 Version 21H2 (November 2021 Update)"); + else if (ver >= VERSION (10, 0, 19043, 0)) return std::wstring (L"Windows 10 Version 21H2 (May 2021 Update)"); + else if (ver >= VERSION (10, 0, 19042, 0)) return std::wstring (L"Windows 10 Version 20H2"); + else if (ver >= VERSION (10, 0, 18362, 0)) return std::wstring (L"Windows 10 May 2019 Update"); + else if (ver >= VERSION (10, 0, 17763, 0)) return std::wstring (L"Windows 10 October 2018 Update"); + else if (ver >= VERSION (10, 0, 17134, 0)) return std::wstring (L"Windows 10 April 2018 Update"); + else if (ver >= VERSION (10, 0, 16299, 0)) return std::wstring (L"Windows 10 Fall Creators Update"); + else if (ver >= VERSION (10, 0, 15063, 0)) return std::wstring (L"Windows 10 Creators Update"); + else if (ver >= VERSION (10, 0, 14393, 0)) return std::wstring (L"Windows 10 Anniversary Update"); + else if (ver >= VERSION (10, 0, 10240, 0)) return std::wstring (L"Windows 10"); + else if (ver >= VERSION (10, 0, 0, 0)) return std::wstring (L"Windows 10"); + else if (ver >= VERSION (6, 4, 9807, 0)) return std::wstring (L"Windows 10 Technical Preview"); + else if (ver >= VERSION (6, 3, 0, 0)) return std::wstring (L"Windows 8.1"); + else if (ver >= VERSION (6, 2, 0, 0)) return std::wstring (L"Windows 8"); + return std::wstring (L""); +} + +std::vector applicationItems = +{ + L"Id", + L"DisplayName", + L"BackgroundColor", + L"ForegroundText", + L"ShortName" +}; +typedef std::wstring strlabel, StringLabel; +std::wstring StringTrim (const std::wstring &str) +{ + if (str.empty ()) return L""; + LPCWSTR start = str.c_str (); + LPCWSTR end = start + str.size () - 1; +#define isblankstrlabelw(wch) (wch == L' ' || wch == L'\t' || wch == L'\n') + while (*start != L'\0' && isblankstrlabelw (*start)) ++start; + while (end >= start && isblankstrlabelw (*end)) --end; + if (start > end) return L""; + return std::wstring (start, end + 1); +} +std::string StringTrim (const std::string &str) +{ + if (str.empty ()) return ""; + LPCSTR start = str.c_str (); + LPCSTR end = start + str.size () - 1; +#define isblankstrlabela(wch) (wch == ' ' || wch == '\t' || wch == '\n') + while (*start != L'\0' && isblankstrlabela (*start)) ++start; + while (end >= start && isblankstrlabela (*end)) --end; + if (start > end) return ""; + return std::string (start, end + 1); +} +namespace l0km +{ + template < typename E, + typename TR = std::char_traits, + typename AL = std::allocator < E >> + inline std::basic_string toupper (const std::basic_string &src) + { + std::basic_string dst = src; + static const std::locale loc; + const std::ctype &ctype = std::use_facet> (loc); + for (typename std::basic_string::size_type i = 0; i < src.size (); ++i) + { + dst [i] = ctype.toupper (src [i]); + } + return dst; + } + + template < typename E, + typename TR = std::char_traits, + typename AL = std::allocator < E >> + inline std::basic_string tolower (const std::basic_string &src) + { + std::basic_string dst = src; + static const std::locale loc; + const std::ctype &ctype = std::use_facet> (loc); + for (typename std::basic_string::size_type i = 0; i < src.size (); ++i) + { + dst [i] = ctype.tolower (src [i]); + } + return dst; + } +} // namespace l0km +#define StringToUpper l0km::toupper +#define StringToLower l0km::tolower +int LabelCompare (const std::wstring &l1, const std::wstring &l2) +{ + std::wstring s1 = StringToUpper (StringTrim (l1)), + s2 = StringToUpper (StringTrim (l2)); + return lstrcmpW (s1.c_str (), s2.c_str ()); +} +int LabelCompare (LPCWSTR l1, LPCWSTR l2) +{ + return LabelCompare (std::wstring (l1), std::wstring (l2)); +} +int LabelCompare (const std::string &l1, const std::string &l2) +{ + std::string s1 = StringToUpper (StringTrim (l1)), + s2 = StringToUpper (StringTrim (l2)); + return lstrcmpA (s1.c_str (), s2.c_str ()); +} +int LabelCompare (LPCSTR l1, LPCSTR l2) +{ + return LabelCompare (std::string (l1), std::string (l2)); +} +bool LabelEqual (const std::wstring &l1, const std::wstring &l2) +{ + return !LabelCompare (l1, l2); +} +bool LabelEqual (LPCWSTR l1, LPCWSTR l2) +{ + return !LabelCompare (l1, l2); +} +bool LabelEqual (const std::string &l1, const std::string &l2) +{ + return !LabelCompare (l1, l2); +} +bool LabelEqual (LPCSTR l1, LPCSTR l2) +{ + return !LabelCompare (l1, l2); +} + +typedef class ApplicationMap: public std::map +{ + public: + std::wstring getAppUserModelID (); + friend bool operator == (ApplicationMap &a1, ApplicationMap &a2) + { + const LPWSTR lpKey = L"AppUserModelID"; + std::wstring wKey (lpKey); + if (a1.find (wKey) == a1.end () && a2.find (wKey) == a2.end ()) return true; + else if (a1.find (wKey) != a1.end () && a2.find (wKey) != a2.end ()) + { + return a1 [wKey] == a2 [wKey]; + } + else return false; + } + friend bool operator != (ApplicationMap &a1, ApplicationMap &a2) + { + return !(a1 == a2); + } +} appmap; +std::wstring ApplicationMap::getAppUserModelID () +{ + if (this->find (L"AppUserModelID") == this->end ()) return std::wstring (L""); + else return (*this) [std::wstring (L"AppUserModelID")]; +} + +class DEPINFO +{ + public: + std::wstring name; + std::wstring publisher; + VERSION versionMin; + DEPINFO (LPWSTR name, LPWSTR publisher, UINT64 versionLimit); + DEPINFO (IAppxManifestPackageDependency *dependency); + DEPINFO (); + bool operator == (DEPINFO &another) { return this->name == another.name; } + bool isEmpty () { return name.length () == 0; } +}; +DEPINFO::DEPINFO (LPWSTR name, LPWSTR publisher, UINT64 versionLimit): + name (name), publisher (publisher), versionMin (*((VERSION *)&versionLimit)) +{ +} +DEPINFO::DEPINFO (IAppxManifestPackageDependency *dependency) +{ + LPWSTR deName = NULL; + LPWSTR dePub = NULL; + UINT64 deMinVer; + dependency->GetName (&deName); + dependency->GetPublisher (&dePub); + dependency->GetMinVersion (&deMinVer); + name = std::wstring (L""); + publisher = std::wstring (L""); + if (deName) name += deName; + if (dePub) publisher += dePub; + versionMin = VERSION (deMinVer); + if (deName) CoTaskMemFree (deName); + if (dePub) CoTaskMemFree (dePub); +} +DEPINFO::DEPINFO (): name (L""), publisher (L""), versionMin (0) {} + +class AppxReader +{ + private: + std::wstring m_filePath = L""; + IAPPXREADER m_appxReader = NULL; + public: + // ÿһεĴٴԴʧ֮ǰɹҲᱻ١ + AppxReader (LPCWSTR swFilePath); + AppxReader (const std::wstring swFilePath); + AppxReader (IStream *objcomFile); + AppxReader (IAppxFile *objcomFile); + AppxReader (); + ~AppxReader (); + bool create (LPCWSTR swFilePath); + bool create (const std::wstring &objswFile); + bool create (IStream *objcomFile); + bool create (IAppxFile *objAppxFile); + // ע⣺ִٲʱĶȡҲ٣˷ǺΣյIJ + bool create (IAppxPackageReader *objAppxReader); + bool destroy (); + // ڴ˶ȡļΪҪȡҪжļǷãʹôˡ + bool isFileExists (); + // ж϶ȡǷãǷļʽ򿪡 + bool isAvailable (); + // ļ򿪵Ķȡ + bool isFileReaderAvailable (); + // ֶͷţָŴ˶ٶͷ + const IAPPXREADER getPackageReader () const { return this->m_appxReader; } + // ֶͷţָŴ˶ٶͷ + LPCWSTR getFilePath (); + IAppxManifestReader *getManifest (); + IAppxManifestPackageId *getIdentity (); + std::wstring getIdentityName (); + std::wstring getIdentityPublisher (); + VERSION getIdentityVersion (); + size_t getIdentityProcessorArchitecture (std::vector &arrOut); + size_t getResourceLanguages (std::vector &vec); + IAppxManifestProperties *getProperties (); + std::wstring getPropertiesStringValue (LPCWSTR lpswName); + std::wstring getPropertiesStringValue (const std::wstring objswName); + HRESULT getPropertiesBoolValue (LPCWSTR lpswName, BOOL &bOutput); + HRESULT getPropertiesBoolValue (const std::wstring objswName, BOOL &bOutput); + std::wstring getPropertyName (); + std::wstring getPropertyDescription (); + std::wstring getPropertyPublisher (); + std::wstring getPropertyLogo (); + UINT64 getPrerequisite (LPCWSTR lpswName); + UINT64 getPrerequisite (const std::wstring objswName); + VERSION getPrerequisiteOSMinVersion (); + IAppxManifestApplicationsEnumerator *getApplicationsEnumerator (); + bool isPackageApplication (); + size_t getApplications (std::vector &output); + size_t getApplicationUserModelIDs (std::vector &output); + size_t getApplicationIDs (std::vector &output); + size_t getApplicationVisualElementsBackgroundColor (std::vector &output); + APPX_CAPABILITIES getCapabilitiesFlag (); + size_t getDeviceCapabilities (std::vector &output); + // getCapabilitiesFlag getDeviceCapabilities + size_t getCapabilities (std::vector &output); + IAppxManifestPackageDependenciesEnumerator *getDependenciesEnumerator (); + size_t getDependencies (std::vector &output); + IStream *getPriFileStream (); + IStream *extractFileToStream (LPCWSTR lpswFilePath); + IStream *extractFileToStream (std::wstring objswFilePath); +}; +AppxReader::AppxReader (LPCWSTR swFilePath) { this->create (swFilePath); } +AppxReader::AppxReader (std::wstring swFilePath) { this->create (swFilePath); } +AppxReader::AppxReader (): m_appxReader (NULL), m_filePath (L"") {} +AppxReader::AppxReader (IStream *objcomFile) : m_filePath (L"") +{ + this->create (objcomFile); +} +AppxReader::AppxReader (IAppxFile *objcomFile) : m_filePath (L"") +{ + this->create (objcomFile); +} +AppxReader::~AppxReader () { this->destroy (); } +bool AppxReader::isFileExists () +{ + return !this->m_filePath.empty () && this->m_filePath.length () > 0 && IsFileExists (this->m_filePath); +} +bool AppxReader::isAvailable () +{ + return this->m_appxReader != NULL; +} +bool AppxReader::isFileReaderAvailable () +{ + return this->isFileExists () && this->isAvailable (); +} +bool AppxReader::destroy () +{ + if (!this->isAvailable ()) return false; // ʾٵ + this->m_appxReader->Release (); + this->m_appxReader = NULL; + this->m_filePath = std::wstring (L""); + return true; +} +bool AppxReader::create (LPCWSTR swFilePath) +{ + this->destroy (); + if (!swFilePath) return false; + if (!lstrlenW (swFilePath)) return false; + if (!IsFileExists (swFilePath)) return false; + HRESULT hr = GetPackageReader (swFilePath, &this->m_appxReader); + if (FAILED (hr)) + { + if (this->m_appxReader) this->m_appxReader->Release (); + this->m_appxReader = NULL; + return false; + } + if (!this->m_appxReader) return false; + this->m_filePath = L""; + this->m_filePath += std::wstring (swFilePath); + return this->isAvailable (); +} +bool AppxReader::create (const std::wstring &objswFile) { return this->create (objswFile.c_str ()); } +bool AppxReader::create (IStream *objcomFile) +{ + this->destroy (); + if (!objcomFile) return false; + HRESULT hr = GetAppxPackageReader (objcomFile, &this->m_appxReader); + if (!this->m_appxReader) return false; + if (FAILED (hr)) + { + if (this->m_appxReader) this->m_appxReader->Release (); + this->m_appxReader = NULL; + return false; + } + return true; +} +bool AppxReader::create (IAppxFile *objAppxFile) +{ + this->destroy (); + IStream *ifile = NULL; + if (!objAppxFile) return false; + HRESULT hr = objAppxFile->GetStream (&ifile); + if (FAILED (hr)) + { + if (ifile) ifile->Release (); + return false; + } + return this->create (ifile); +} +bool AppxReader::create (IAppxPackageReader *objAppxReader) +{ + this->destroy (); + if (!objAppxReader) return false; + this->m_appxReader = objAppxReader; + return objAppxReader != NULL; +} +LPCWSTR AppxReader::getFilePath () { return this->m_filePath.c_str (); } +IAppxManifestReader *AppxReader::getManifest () +{ + if (!this->isAvailable ()) return NULL; + IAppxManifestReader *manifest = NULL; + HRESULT hr = this->m_appxReader->GetManifest (&manifest); + if (!manifest) return NULL; + if (FAILED (hr)) + { + if (manifest) manifest->Release (); + return NULL; + } + return manifest; +} +IAppxManifestPackageId *AppxReader::getIdentity () +{ + if (!this->isAvailable ()) return NULL; + IAppxManifestReader *manifest = this->getManifest (); + if (!manifest) return NULL; + IAppxManifestPackageId *packageId = NULL; + HRESULT hr = manifest->GetPackageId (&packageId); + if (manifest) { manifest->Release (); manifest = NULL; } + if (!packageId) return NULL; + if (FAILED (hr)) + { + if (packageId) packageId->Release (); + return NULL; + } + return packageId; +} +std::wstring AppxReader::getIdentityName () +{ + std::wstring temp (L""); + IAppxManifestPackageId *packageId = this->getIdentity (); + if (!packageId) return temp; + LPWSTR lpwzName = NULL; + HRESULT hr = packageId->GetName (&lpwzName); + if (FAILED (hr)) + { + if (lpwzName) CoTaskMemFree (lpwzName); + packageId->Release (); + return temp; + } + if (lpwzName) temp += lpwzName; + if (lpwzName) CoTaskMemFree (lpwzName); + packageId->Release (); + return temp; +} +std::wstring AppxReader::getIdentityPublisher () +{ + std::wstring temp (L""); + IAppxManifestPackageId *packageId = this->getIdentity (); + if (!packageId) return temp; + LPWSTR lpwzName = NULL; + HRESULT hr = packageId->GetPublisher (&lpwzName); + if (FAILED (hr)) + { + if (lpwzName) CoTaskMemFree (lpwzName); + packageId->Release (); + return temp; + } + if (lpwzName) temp += lpwzName; + if (lpwzName) CoTaskMemFree (lpwzName); + packageId->Release (); + return temp; +} +VERSION AppxReader::getIdentityVersion () +{ + VERSION temp (0); + IAppxManifestPackageId *packageId = this->getIdentity (); + if (!packageId) return temp; + UINT64 u64 = 0; + HRESULT hr = packageId->GetVersion (&u64); + temp = VERSION (u64); + packageId->Release (); + return temp; +} +size_t AppxReader::getIdentityProcessorArchitecture (std::vector &arrOut) +{ + if (!&arrOut) return 0; + arrOut.clear (); + IAppxManifestPackageId *packageId = this->getIdentity (); + if (!packageId) return 0; + APPX_PACKAGE_ARCHITECTURE apa = APPX_PACKAGE_ARCHITECTURE_NEUTRAL; + packageId->GetArchitecture (&apa); + push_no_repeat (arrOut, apa); + return arrOut.size (); +} +size_t AppxReader::getResourceLanguages (std::vector &vec) +{ + if (!&vec) return 0; + vec.clear (); + CComPtr manifest = NULL; + HRESULT hr = this->m_appxReader->GetManifest (&manifest); + if (FAILED (hr)) return 0; + CComPtr manifest2 = NULL; + hr = manifest->QueryInterface (__uuidof(IAppxManifestReader2), (void**)&manifest2); + if (FAILED (hr)) return 0; + CComPtr qres = NULL; + hr = manifest2->GetQualifiedResources (&qres); + if (FAILED (hr)) return 0; + BOOL hasCurrent = FALSE; + hr = qres->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr res = NULL; + hr = qres->GetCurrent (&res); + if (FAILED (hr)) goto Loop_MoveNext; + LPWSTR lpswLCode = NULL; + hr = res->GetLanguage (&lpswLCode); + if (FAILED (hr)) goto Loop_MoveNext; + if (lpswLCode && lstrlenW (lpswLCode) > 0) + { + std::wstring tempStr (lpswLCode), tempLowerStr; + tempLowerStr = StringToLower (tempStr); + push_no_repeat (vec, lpswLCode); + } + Loop_MoveNext: + hr = qres->MoveNext (&hasCurrent); + } + return vec.size (); +} +IAppxManifestProperties *AppxReader::getProperties () +{ + IAppxManifestReader *manifest = this->getManifest (); + if (!manifest) return NULL; + IAppxManifestProperties *properties = NULL; + HRESULT hr = manifest->GetProperties (&properties); + if (manifest) { manifest->Release (); manifest = NULL; } + if (!properties) return NULL; + if (FAILED (hr)) { if (properties) properties->Release (); return NULL; } + return properties; +} +std::wstring AppxReader::getPropertiesStringValue (LPCWSTR lpswName) +{ + std::wstring temp (L""); + if (!lpswName) return NULL; + IAppxManifestProperties *properties = this->getProperties (); + if (!properties) return temp; + LPWSTR lpswValue = NULL; + HRESULT hr = properties->GetStringValue (lpswName, &lpswValue); + properties->Release (); + if (lpswValue) { temp += lpswValue; CoTaskMemFree (lpswValue); lpswValue = NULL; } + return temp; +} +std::wstring AppxReader::getPropertiesStringValue (const std::wstring objswName) +{ + return this->getPropertiesStringValue (objswName.c_str ()); +} +HRESULT AppxReader::getPropertiesBoolValue (LPCWSTR lpswName, BOOL &bOutput) +{ + HRESULT hr = E_FAIL; + if (!lpswName || !&bOutput) return hr; + IAppxManifestProperties *properties = this->getProperties (); + if (!properties) return hr; + hr = properties->GetBoolValue (lpswName, &bOutput); + properties->Release (); + return hr; +} +HRESULT AppxReader::getPropertiesBoolValue (const std::wstring objswName, BOOL &bOutput) +{ + return this->getPropertiesBoolValue (objswName.c_str (), bOutput); +} +std::wstring AppxReader::getPropertyName () +{ + return this->getPropertiesStringValue (L"DisplayName"); +} +std::wstring AppxReader::getPropertyDescription () +{ + return this->getPropertiesStringValue (L"Description"); +} +std::wstring AppxReader::getPropertyPublisher () +{ + return this->getPropertiesStringValue (L"PublisherDisplayName"); +} +std::wstring AppxReader::getPropertyLogo () +{ + return this->getPropertiesStringValue (L"Logo"); +} +// ʧܷ NULL +UINT64 AppxReader::getPrerequisite (LPCWSTR lpswName) +{ + IAppxManifestReader *manifest = this->getManifest (); + if (!manifest) return NULL; + UINT64 u64t = 0; + HRESULT hr = manifest->GetPrerequisite (lpswName, &u64t); + if (manifest) manifest->Release (); + if (FAILED (hr)) return NULL; + return u64t; +} +// ʧܷ NULL +UINT64 AppxReader::getPrerequisite (const std::wstring objswName) +{ + return this->getPrerequisite (objswName.c_str ()); +} +VERSION AppxReader::getPrerequisiteOSMinVersion () +{ + UINT64 temp = this->getPrerequisite (L"OSMinVersion"); + return VERSION (temp); +} +IAppxManifestApplicationsEnumerator *AppxReader::getApplicationsEnumerator () +{ + IAppxManifestReader *manifest = this->getManifest (); + if (!manifest) return NULL; + IAppxManifestApplicationsEnumerator *temp = NULL; + HRESULT hr = manifest->GetApplications (&temp); + manifest->Release (); + if (!temp) return NULL; + if (FAILED (hr)) { if (temp) temp->Release (); return NULL; } + return temp; +} +bool AppxReader::isPackageApplication () +{ + IAppxManifestApplicationsEnumerator *aenum = this->getApplicationsEnumerator (); + if (!aenum) return false; + BOOL hasCurrent = FALSE; + HRESULT hr = aenum->GetHasCurrent (&hasCurrent); + aenum->Release (); + return SUCCEEDED (hr) && hasCurrent; +} +size_t AppxReader::getApplications (std::vector &output) +{ + if (!&output) return false; + output.clear (); + CComPtr aenum = this->getApplicationsEnumerator (); + if (!aenum) return 0; + BOOL hasCurrent = FALSE; + HRESULT hr = aenum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr app = NULL; + hr = aenum->GetCurrent (&app); + if (SUCCEEDED (hr)) + { + appmap map; + LPWSTR lpswTemp = NULL; + hr = app->GetAppUserModelId (&lpswTemp); + if (!lpswTemp) { hr = aenum->MoveNext (&hasCurrent); continue; } + if (SUCCEEDED (hr)) + { + { + std::wstring objT (L""); + if (lpswTemp) objT += lpswTemp; + if (objT.length () <= 0) + { + if (lpswTemp) CoTaskMemFree (lpswTemp); + lpswTemp = NULL; + hr = aenum->MoveNext (&hasCurrent); + continue; + } + map [StringLabel (L"AppUserModelID")] = objT; + } + for (auto it : applicationItems) + { + LPWSTR lpswTemp2 = NULL; + hr = app->GetStringValue (it.c_str (), &lpswTemp2); + if (FAILED (hr) || !lpswTemp2) + { + if (lpswTemp2) CoTaskMemFree (lpswTemp2); + continue; + } + if (lstrlenW (lpswTemp2) <= 0) + { + if (lpswTemp2) CoTaskMemFree (lpswTemp2); + continue; + } + std::wstring objT (L""); + if (lpswTemp2) objT += lpswTemp2; + map [StringLabel (it)] = objT; + } + push_no_repeat (output, map); + } + if (!lpswTemp) CoTaskMemFree (lpswTemp); + } + hr = aenum->MoveNext (&hasCurrent); + } + return output.size (); +} +size_t AppxReader::getApplicationUserModelIDs (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + std::vector maps; + this->getApplications (maps); + for (auto it : maps) + { + std::wstring t (L""); + t += it.getAppUserModelID (); + push_no_repeat (output, t); + } + return output.size (); +} +size_t AppxReader::getApplicationIDs (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + std::vector maps; + this->getApplications (maps); + for (auto it : maps) + { + std::wstring t (L""); + t += it [StringLabel (L"Id")]; + push_no_repeat (output, t); + } + return output.size (); +} +size_t AppxReader::getApplicationVisualElementsBackgroundColor (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + std::vector maps; + this->getApplications (maps); + for (auto it : maps) + { + std::wstring t (L""); + t += it [StringLabel (L"BackgroundColor")]; + push_no_repeat (output, t); + } + return output.size (); +} +APPX_CAPABILITIES AppxReader::getCapabilitiesFlag () +{ + CComPtr manifest = this->getManifest (); + if (!manifest) return (APPX_CAPABILITIES)NULL; + APPX_CAPABILITIES temp; + HRESULT hr = manifest->GetCapabilities (&temp); + if (FAILED (hr)) return (APPX_CAPABILITIES)NULL; + return temp; +} +size_t AppxReader::getDeviceCapabilities (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + CComPtr manifest = this->getManifest (); + if (!manifest) return 0; + CComPtr denum = NULL; + HRESULT hr = manifest->GetDeviceCapabilities (&denum); + if (!denum) return 0; + if (FAILED (hr)) return 0; + BOOL hasCurrent = FALSE; + hr = denum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + LPWSTR lpswT = NULL; + hr = denum->GetCurrent (&lpswT); + if (lpswT) + { + if (SUCCEEDED (hr)) + { + std::wstring objswT (L""); + if (lpswT) objswT += lpswT; + if (objswT.length () > 0) push_no_repeat (output, objswT); + if (lpswT) CoTaskMemFree (lpswT); + } + } + hr = denum->MoveNext (&hasCurrent); + } + return output.size (); +} +size_t AppxReader::getCapabilities (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + std::vector dcap; + GetCapabilitiesName (this->getCapabilitiesFlag (), output); + this->getDeviceCapabilities (dcap); + for (auto it : dcap) + { + std::wstring temp (L""); + temp += it; + push_no_repeat (output, temp); + } + return output.size (); +} +IAppxManifestPackageDependenciesEnumerator *AppxReader::getDependenciesEnumerator () +{ + CComPtr manifest = this->getManifest (); + if (!manifest) return NULL; + IAppxManifestPackageDependenciesEnumerator *deps; + HRESULT hr = manifest->GetPackageDependencies (&deps); + if (!deps) return NULL; + if (FAILED (hr)) + { + if (deps) deps->Release (); + return NULL; + } + return deps; +} +size_t AppxReader::getDependencies (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + CComPtr deps = this->getDependenciesEnumerator (); + if (!deps) return 0; + BOOL hasCurrent = FALSE; + HRESULT hr = deps->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr dep = NULL; + hr = deps->GetCurrent (&dep); + if (SUCCEEDED (hr)) + { + DEPINFO dinfo (dep); + push_no_repeat (output, dinfo); + } + hr = deps->MoveNext (&hasCurrent); + } + return output.size (); +} +IStream *AppxReader::extractFileToStream (LPCWSTR lpswFilePath) +{ + if (!lpswFilePath) return false; + if (lstrlenW (lpswFilePath) <= 0) return false; + CComPtr ifile = NULL; + HRESULT hr = this->m_appxReader->GetPayloadFile (lpswFilePath, &ifile); + if (!ifile) return NULL; + if (FAILED (hr)) return NULL; + IStream *sfile = NULL; + hr = ifile->GetStream (&sfile); + if (!sfile) return NULL; + if (FAILED (hr)) return NULL; + return sfile; +} +IStream *AppxReader::extractFileToStream (std::wstring objswFilePath) +{ + return this->extractFileToStream (objswFilePath.c_str ()); +} +IStream *AppxReader::getPriFileStream () +{ + return this->extractFileToStream (L"resources.pri"); +} + +class BundleReader +{ + private: + std::wstring m_filePath = L""; + IBUNDLEREADER m_bundleReader = NULL; + public: + // ÿһεĴٴԴʧ֮ǰɹҲᱻ١ + BundleReader (LPCWSTR swFilePath); + BundleReader (const std::wstring swFilePath); + BundleReader (); + ~BundleReader (); + bool create (LPCWSTR swFilePath); + bool create (const std::wstring &objswFile); + // ע⣺ִٲʱĶȡҲ٣˷ǺΣյIJ + bool destroy (); + // ڴ˶ȡļΪҪȡҪжļǷãʹôˡ + bool isFileExists (); + // ж϶ȡǷãǷļʽ򿪡 + bool isAvailable (); + // ļ򿪵Ķȡ + bool isFileReaderAvailable (); + // ֶͷţָŴ˶ٶͷ + const IBUNDLEREADER getPackageReader () const { return this->m_bundleReader; } + // ֶͷ + IAPPXREADER getAppxPackageReader (); + // ֶͷţָŴ˶ٶͷ + LPCWSTR getFilePath (); + IAppxBundleManifestReader *getManifest (); + // ȡӰ嵥ΪӦðΪԴ/ + IAppxManifestReader *getAppxManifest (); + IAppxManifestPackageId *getIdentity (); + IAppxManifestPackageId *getAppxIdentity (); + std::wstring getIdentityName (); + std::wstring getIdentityPublisher (); + VERSION getIdentityVersion (); + size_t getIdentityProcessorArchitecture (std::vector &arrOut); + size_t getResourceLanguages (std::vector &vec); + IAppxManifestProperties *getProperties (); + std::wstring getPropertiesStringValue (LPCWSTR lpswName); + std::wstring getPropertiesStringValue (const std::wstring objswName); + HRESULT getPropertiesBoolValue (LPCWSTR lpswName, BOOL &bOutput); + HRESULT getPropertiesBoolValue (const std::wstring objswName, BOOL &bOutput); + std::wstring getPropertyName (); + std::wstring getPropertyDescription (); + std::wstring getPropertyPublisher (); + std::wstring getPropertyLogo (); + UINT64 getPrerequisite (LPCWSTR lpswName); + UINT64 getPrerequisite (const std::wstring objswName); + VERSION getPrerequisiteOSMinVersion (); + IAppxManifestApplicationsEnumerator *getApplicationsEnumerator (); + bool isPackageApplication (); + size_t getApplications (std::vector &output); + size_t getApplicationUserModelIDs (std::vector &output); + size_t getApplicationIDs (std::vector &output); + size_t getApplicationVisualElementsBackgroundColor (std::vector &output); + APPX_CAPABILITIES getCapabilitiesFlag (); + size_t getDeviceCapabilities (std::vector &output); + // getCapabilitiesFlag getDeviceCapabilities + size_t getCapabilities (std::vector &output); + IAppxManifestPackageDependenciesEnumerator *getDependenciesEnumerator (); + size_t getDependencies (std::vector &output); + IStream *getPriFileStream (); + IStream *extractFileToStream (LPCWSTR lpswFilePath); + IStream *extractFileToStream (std::wstring objswFilePath); +}; +BundleReader::BundleReader (LPCWSTR swFilePath) { this->create (swFilePath); } +BundleReader::BundleReader (const std::wstring swFilePath) { this->create (swFilePath); } +BundleReader::BundleReader (): m_filePath (L""), m_bundleReader (NULL) {} +BundleReader::~BundleReader () { this->destroy (); } +bool BundleReader::isFileExists () +{ + return !this->m_filePath.empty () && this->m_filePath.length () > 0 && IsFileExists (this->m_filePath); +} +bool BundleReader::isAvailable () +{ + return this->m_bundleReader != NULL; +} +bool BundleReader::isFileReaderAvailable () +{ + return this->isFileExists () && this->isAvailable (); +} +bool BundleReader::destroy () +{ + if (!this->isAvailable ()) return false; // ʾٵ + this->m_bundleReader->Release (); + this->m_bundleReader = NULL; + this->m_filePath = std::wstring (L""); + return true; +} +bool BundleReader::create (LPCWSTR swFilePath) +{ + this->destroy (); + if (!swFilePath) return false; + if (!lstrlenW (swFilePath)) return false; + if (!IsFileExists (swFilePath)) return false; + HRESULT hr = GetBundleReader (swFilePath, &this->m_bundleReader); + if (FAILED (hr)) + { + if (this->m_bundleReader) this->m_bundleReader->Release (); + this->m_bundleReader = NULL; + return false; + } + if (!this->m_bundleReader) return false; + this->m_filePath = L""; + this->m_filePath += std::wstring (swFilePath); + return this->isAvailable (); +} +bool BundleReader::create (const std::wstring &objswFile) { return this->create (objswFile.c_str ()); } +LPCWSTR BundleReader::getFilePath () { return this->m_filePath.c_str (); } +IAppxBundleManifestReader *BundleReader::getManifest () +{ + if (!this->isAvailable ()) return NULL; + IAppxBundleManifestReader *bmanifest = NULL; + HRESULT hr = this->m_bundleReader->GetManifest (&bmanifest); + if (!bmanifest) return NULL; + if (FAILED (hr)) + { + if (bmanifest) bmanifest->Release (); + return NULL; + } + return bmanifest; +} +IAPPXREADER BundleReader::getAppxPackageReader () +{ + CComPtr bmanifest = this->getManifest (); + if (!bmanifest) return NULL; + CComPtr pienum = NULL; + HRESULT hr = bmanifest->GetPackageInfoItems (&pienum); + if (!pienum || FAILED (hr)) return NULL; + BOOL hasCurrent = FALSE; + hr = pienum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr pinfo = NULL; + hr = pienum->GetCurrent (&pinfo); + if (pinfo && SUCCEEDED (hr)) + { + APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE ftype = APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_RESOURCE; + hr = pinfo->GetPackageType (&ftype); + if (SUCCEEDED (hr) && ftype == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION) + { + LPWSTR lpswSubPkgName = NULL; + hr = pinfo->GetFileName (&lpswSubPkgName); + if (lpswSubPkgName && SUCCEEDED (hr)) + { + CComPtr ifile = NULL; + hr = this->m_bundleReader->GetPayloadPackage (lpswSubPkgName, &ifile); + CoTaskMemFree (lpswSubPkgName); + if (ifile && SUCCEEDED (hr)) + { + CComPtr isfile = NULL; + hr = ifile->GetStream (&isfile); + if (SUCCEEDED (hr) && isfile) + { + IAPPXREADER areader = NULL; + hr = GetAppxPackageReader (isfile, &areader); + if (FAILED (hr)) + { + if (areader) areader->Release (); + return NULL; + } + return areader; + } + } + } + } + } + hr = pienum->MoveNext (&hasCurrent); + } + hr = pienum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr pinfo = NULL; + hr = pienum->GetCurrent (&pinfo); + if (pinfo && SUCCEEDED (hr)) + { + LPWSTR lpswSubPkgName = NULL; + hr = pinfo->GetFileName (&lpswSubPkgName); + if (lpswSubPkgName && SUCCEEDED (hr)) + { + CComPtr ifile = NULL; + hr = this->m_bundleReader->GetPayloadPackage (lpswSubPkgName, &ifile); + CoTaskMemFree (lpswSubPkgName); + if (ifile && SUCCEEDED (hr)) + { + CComPtr isfile = NULL; + hr = ifile->GetStream (&isfile); + if (SUCCEEDED (hr) && isfile) + { + IAPPXREADER areader = NULL; + hr = GetAppxPackageReader (isfile, &areader); + if (FAILED (hr)) + { + if (areader) areader->Release (); + return NULL; + } + return areader; + } + } + } + } + hr = pienum->MoveNext (&hasCurrent); + } + return NULL; +} +IAppxManifestReader* BundleReader::getAppxManifest () +{ + CComPtr bmanifest = this->getManifest (); + if (!bmanifest) return NULL; + CComPtr pienum = NULL; + HRESULT hr = bmanifest->GetPackageInfoItems (&pienum); + if (!pienum || FAILED (hr)) return NULL; + BOOL hasCurrent = FALSE; + hr = pienum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr pinfo = NULL; + hr = pienum->GetCurrent (&pinfo); + if (pinfo && SUCCEEDED (hr)) + { + APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE ftype = APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_RESOURCE; + hr = pinfo->GetPackageType (&ftype); + if (SUCCEEDED (hr) && ftype == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION) + { + LPWSTR lpswSubPkgName = NULL; + hr = pinfo->GetFileName (&lpswSubPkgName); + if (lpswSubPkgName && SUCCEEDED (hr)) + { + CComPtr ifile = NULL; + hr = this->m_bundleReader->GetPayloadPackage (lpswSubPkgName, &ifile); + CoTaskMemFree (lpswSubPkgName); + if (ifile && SUCCEEDED (hr)) + { + AppxReader areader (ifile); + IAppxManifestReader* amanifest = areader.getManifest (); + if (amanifest) return amanifest; + } + } + } + } + hr = pienum->MoveNext (&hasCurrent); + } + hr = pienum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr pinfo = NULL; + hr = pienum->GetCurrent (&pinfo); + if (pinfo && SUCCEEDED (hr)) + { + LPWSTR lpswSubPkgName = NULL; + hr = pinfo->GetFileName (&lpswSubPkgName); + if (lpswSubPkgName && SUCCEEDED (hr)) + { + CComPtr ifile = NULL; + hr = this->m_bundleReader->GetPayloadPackage (lpswSubPkgName, &ifile); + CoTaskMemFree (lpswSubPkgName); + if (ifile && SUCCEEDED (hr)) + { + AppxReader areader (ifile); + IAppxManifestReader* amanifest = areader.getManifest (); + if (amanifest) return amanifest; + } + } + } + hr = pienum->MoveNext (&hasCurrent); + } + return NULL; +} +IAppxManifestPackageId *BundleReader::getIdentity () +{ + CComPtr bmanifest = this->getManifest (); + if (!bmanifest) return NULL; + IAppxManifestPackageId *packageId = NULL; + HRESULT hr = bmanifest->GetPackageId (&packageId); + if (!packageId) return NULL; + if (FAILED (hr)) + { + packageId->Release (); + return NULL; + } + return packageId; +} +IAppxManifestPackageId *BundleReader::getAppxIdentity () +{ + CComPtr amanifest = this->getAppxManifest (); + if (!amanifest) return NULL; + IAppxManifestPackageId *packageId = NULL; + HRESULT hr = amanifest->GetPackageId (&packageId); + if (!packageId) return NULL; + if (FAILED (hr)) + { + packageId->Release (); + return NULL; + } + return packageId; +} +std::wstring BundleReader::getIdentityName () +{ + std::wstring t (L""); + CComPtr packageId = this->getAppxIdentity (); + if (!packageId) packageId = this->getIdentity (); + if (!packageId) return t; + LPWSTR lpswT = NULL; + HRESULT hr = packageId->GetName (&lpswT); + if (!lpswT) return t; + if (FAILED (hr)) { if (lpswT) CoTaskMemFree (lpswT); return t; } + if (lpswT) t += lpswT; + if (lpswT) CoTaskMemFree (lpswT); + return t; +} +std::wstring BundleReader::getIdentityPublisher () +{ + std::wstring t (L""); + CComPtr packageId = this->getAppxIdentity (); + if (!packageId) packageId = this->getIdentity (); + if (!packageId) return t; + LPWSTR lpswT = NULL; + HRESULT hr = packageId->GetPublisher (&lpswT); + if (!lpswT) return t; + if (FAILED (hr)) { if (lpswT) CoTaskMemFree (lpswT); return t; } + if (lpswT) t += lpswT; + if (lpswT) CoTaskMemFree (lpswT); + return t; +} +VERSION BundleReader::getIdentityVersion () +{ + VERSION v (0); + CComPtr packageId = this->getAppxIdentity (); + if (!packageId) packageId = this->getIdentity (); + if (!packageId) return v; + UINT64 u64 = 0; + HRESULT hr = packageId->GetVersion (&u64); + v = VERSION (u64); + return v; +} +size_t BundleReader::getIdentityProcessorArchitecture (std::vector &arrOut) +{ + CComPtr bmanifest = this->getManifest (); + if (!bmanifest) return 0; + CComPtr pienum = NULL; + HRESULT hr = bmanifest->GetPackageInfoItems (&pienum); + if (!pienum || FAILED (hr)) return 0; + BOOL hasCurrent = FALSE; + hr = pienum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr pinfo = NULL; + hr = pienum->GetCurrent (&pinfo); + if (pinfo && SUCCEEDED (hr)) + { + APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE ftype = APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_RESOURCE; + hr = pinfo->GetPackageType (&ftype); + if (SUCCEEDED (hr) && ftype == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION) + { + LPWSTR lpswSubPkgName = NULL; + hr = pinfo->GetFileName (&lpswSubPkgName); + if (lpswSubPkgName && SUCCEEDED (hr)) + { + CComPtr ifile = NULL; + hr = this->m_bundleReader->GetPayloadPackage (lpswSubPkgName, &ifile); + CoTaskMemFree (lpswSubPkgName); + if (ifile && SUCCEEDED (hr)) + { + AppxReader areader (ifile); + std::vector tarr; + areader.getIdentityProcessorArchitecture (tarr); + for (auto it : tarr) push_no_repeat (arrOut, it); + } + } + } + } + hr = pienum->MoveNext (&hasCurrent); + } + return arrOut.size (); +} +size_t BundleReader::getResourceLanguages (std::vector &vec) +{ + CComPtr bmanifest = this->getManifest (); + if (!bmanifest) return 0; + CComPtr pienum = NULL; + HRESULT hr = bmanifest->GetPackageInfoItems (&pienum); + if (!pienum || FAILED (hr)) return 0; + BOOL hasCurrent = FALSE; + hr = pienum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr pinfo = NULL; + hr = pienum->GetCurrent (&pinfo); + if (pinfo && SUCCEEDED (hr)) + { + LPWSTR lpswSubPkgName = NULL; + hr = pinfo->GetFileName (&lpswSubPkgName); + if (lpswSubPkgName && SUCCEEDED (hr)) + { + CComPtr ifile = NULL; + hr = this->m_bundleReader->GetPayloadPackage (lpswSubPkgName, &ifile); + CoTaskMemFree (lpswSubPkgName); + if (ifile && SUCCEEDED (hr)) + { + AppxReader areader (ifile); + std::vector tarr; + areader.getResourceLanguages (tarr); + for (auto it : tarr) push_no_repeat (vec, it); + } + } + } + hr = pienum->MoveNext (&hasCurrent); + } + return vec.size (); +} +IAppxManifestProperties *BundleReader::getProperties () +{ + CComPtr manifest = this->getAppxManifest (); + if (!manifest) return NULL; + IAppxManifestProperties *properties = NULL; + HRESULT hr = manifest->GetProperties (&properties); + if (!properties) return NULL; + if (FAILED (hr)) { if (properties) properties->Release (); return NULL; } + return properties; +} +std::wstring BundleReader::getPropertiesStringValue (LPCWSTR lpswName) +{ + std::wstring temp (L""); + if (!lpswName) return NULL; + IAppxManifestProperties *properties = this->getProperties (); + if (!properties) return temp; + LPWSTR lpswValue = NULL; + HRESULT hr = properties->GetStringValue (lpswName, &lpswValue); + properties->Release (); + if (lpswValue) { temp += lpswValue; CoTaskMemFree (lpswValue); lpswValue = NULL; } + return temp; +} +std::wstring BundleReader::getPropertiesStringValue (const std::wstring objswName) +{ + return this->getPropertiesStringValue (objswName.c_str ()); +} +HRESULT BundleReader::getPropertiesBoolValue (LPCWSTR lpswName, BOOL &bOutput) +{ + HRESULT hr = E_FAIL; + if (!lpswName || !&bOutput) return hr; + IAppxManifestProperties *properties = this->getProperties (); + if (!properties) return hr; + hr = properties->GetBoolValue (lpswName, &bOutput); + properties->Release (); + return hr; +} +HRESULT BundleReader::getPropertiesBoolValue (const std::wstring objswName, BOOL &bOutput) +{ + return this->getPropertiesBoolValue (objswName.c_str (), bOutput); +} +std::wstring BundleReader::getPropertyName () +{ + return this->getPropertiesStringValue (L"DisplayName"); +} +std::wstring BundleReader::getPropertyDescription () +{ + return this->getPropertiesStringValue (L"Description"); +} +std::wstring BundleReader::getPropertyPublisher () +{ + return this->getPropertiesStringValue (L"PublisherDisplayName"); +} +std::wstring BundleReader::getPropertyLogo () +{ + return this->getPropertiesStringValue (L"Logo"); +} +UINT64 BundleReader::getPrerequisite (LPCWSTR lpswName) +{ + IAppxManifestReader *manifest = this->getAppxManifest (); + if (!manifest) return NULL; + UINT64 u64t = 0; + HRESULT hr = manifest->GetPrerequisite (lpswName, &u64t); + if (manifest) manifest->Release (); + if (FAILED (hr)) return NULL; + return u64t; +} +UINT64 BundleReader::getPrerequisite (const std::wstring objswName) +{ + return this->getPrerequisite (objswName.c_str ()); +} +VERSION BundleReader::getPrerequisiteOSMinVersion () +{ + UINT64 temp = this->getPrerequisite (L"OSMinVersion"); + return VERSION (temp); +} +IAppxManifestApplicationsEnumerator *BundleReader::getApplicationsEnumerator () +{ + IAppxManifestReader *manifest = this->getAppxManifest (); + if (!manifest) return NULL; + IAppxManifestApplicationsEnumerator *temp = NULL; + HRESULT hr = manifest->GetApplications (&temp); + manifest->Release (); + if (!temp) return NULL; + if (FAILED (hr)) { if (temp) temp->Release (); return NULL; } + return temp; +} +bool BundleReader::isPackageApplication () +{ + IAppxManifestApplicationsEnumerator *aenum = this->getApplicationsEnumerator (); + if (!aenum) return false; + BOOL hasCurrent = FALSE; + HRESULT hr = aenum->GetHasCurrent (&hasCurrent); + aenum->Release (); + return SUCCEEDED (hr) && hasCurrent; +} +size_t BundleReader::getApplications (std::vector& output) +{ + if (!&output) return 0; + output.clear (); + CComPtr aenum = this->getApplicationsEnumerator (); + if (!aenum) return 0; + BOOL hasCurrent = FALSE; + HRESULT hr = aenum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr app = NULL; + hr = aenum->GetCurrent (&app); + if (app && SUCCEEDED (hr)) + { + appmap map; + LPWSTR lpswTemp = NULL; + hr = app->GetAppUserModelId (&lpswTemp); + if (lpswTemp && SUCCEEDED (hr)) + { + std::wstring objT = lpswTemp; + CoTaskMemFree (lpswTemp); + if (!objT.empty ()) + { + map [StringLabel (L"AppUserModelID")] = objT; + for (auto it : applicationItems) + { + LPWSTR lpswTemp2 = NULL; + hr = app->GetStringValue (it.c_str (), &lpswTemp2); + if (lpswTemp2 && SUCCEEDED (hr)) + { + std::wstring objT2 = lpswTemp2; + CoTaskMemFree (lpswTemp2); + if (!objT2.empty ()) + { + map [StringLabel (it)] = objT2; + } + } + } + push_no_repeat (output, map); + } + } + } + hr = aenum->MoveNext (&hasCurrent); + } + return output.size (); +} +size_t BundleReader::getApplicationUserModelIDs (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + std::vector maps; + this->getApplications (maps); + for (auto it : maps) + { + std::wstring t (L""); + t += it.getAppUserModelID (); + push_no_repeat (output, t); + } + return output.size (); +} +size_t BundleReader::getApplicationIDs (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + std::vector maps; + this->getApplications (maps); + for (auto it : maps) + { + std::wstring t (L""); + t += it [StringLabel (L"Id")]; + push_no_repeat (output, t); + } + return output.size (); +} +size_t BundleReader::getApplicationVisualElementsBackgroundColor (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + std::vector maps; + this->getApplications (maps); + for (auto it : maps) + { + std::wstring t (L""); + t += it [StringLabel (L"BackgroundColor")]; + push_no_repeat (output, t); + } + return output.size (); +} +APPX_CAPABILITIES BundleReader::getCapabilitiesFlag () +{ + CComPtr manifest = this->getAppxManifest (); + if (!manifest) return (APPX_CAPABILITIES)NULL; + APPX_CAPABILITIES temp; + HRESULT hr = manifest->GetCapabilities (&temp); + if (FAILED (hr)) return (APPX_CAPABILITIES)NULL; + return temp; +} +size_t BundleReader::getDeviceCapabilities (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + CComPtr manifest = this->getAppxManifest (); + if (!manifest) return 0; + CComPtr denum = NULL; + HRESULT hr = manifest->GetDeviceCapabilities (&denum); + if (!denum || FAILED (hr)) return 0; + BOOL hasCurrent = FALSE; + hr = denum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + LPWSTR lpswT = NULL; + hr = denum->GetCurrent (&lpswT); + if (lpswT && SUCCEEDED (hr)) + { + std::wstring objswT = lpswT; + CoTaskMemFree (lpswT); + if (!objswT.empty ()) push_no_repeat (output, objswT); + } + hr = denum->MoveNext (&hasCurrent); + } + return output.size (); +} +size_t BundleReader::getCapabilities (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + std::vector dcap; + GetCapabilitiesName (this->getCapabilitiesFlag (), output); + this->getDeviceCapabilities (dcap); + for (auto it : dcap) + { + std::wstring temp (L""); + temp += it; + push_no_repeat (output, temp); + } + return output.size (); +} +IAppxManifestPackageDependenciesEnumerator *BundleReader::getDependenciesEnumerator () +{ + CComPtr manifest = this->getAppxManifest (); + if (!manifest) return NULL; + IAppxManifestPackageDependenciesEnumerator *deps; + HRESULT hr = manifest->GetPackageDependencies (&deps); + if (!deps) return NULL; + if (FAILED (hr)) + { + if (deps) deps->Release (); + return NULL; + } + return deps; +} +size_t BundleReader::getDependencies (std::vector &output) +{ + if (!&output) return 0; + output.clear (); + CComPtr deps = this->getDependenciesEnumerator (); + if (!deps) return 0; + BOOL hasCurrent = FALSE; + HRESULT hr = deps->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr dep = NULL; + hr = deps->GetCurrent (&dep); + if (SUCCEEDED (hr)) + { + DEPINFO dinfo (dep); + push_no_repeat (output, dinfo); + } + hr = deps->MoveNext (&hasCurrent); + } + return output.size (); +} +IStream *BundleReader::extractFileToStream (LPCWSTR lpswFilePath) +{ + CComPtr bmanifest = this->getManifest (); + if (!bmanifest) return NULL; + CComPtr pienum = NULL; + HRESULT hr = bmanifest->GetPackageInfoItems (&pienum); + if (!pienum || FAILED (hr)) return NULL; + BOOL hasCurrent = FALSE; + hr = pienum->GetHasCurrent (&hasCurrent); + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr pinfo = NULL; + hr = pienum->GetCurrent (&pinfo); + if (pinfo && SUCCEEDED (hr)) + { + APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE ftype = APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_RESOURCE; + hr = pinfo->GetPackageType (&ftype); + if (SUCCEEDED (hr) && ftype == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION) + { + LPWSTR lpswSubPkgName = NULL; + hr = pinfo->GetFileName (&lpswSubPkgName); + if (lpswSubPkgName && SUCCEEDED (hr)) + { + CComPtr ifile = NULL; + hr = this->m_bundleReader->GetPayloadPackage (lpswSubPkgName, &ifile); + CoTaskMemFree (lpswSubPkgName); + + if (ifile && SUCCEEDED (hr)) + { + AppxReader areader (ifile); + IStream *isfile = areader.extractFileToStream (lpswFilePath); + if (isfile) return isfile; + } + } + else if (lpswSubPkgName) + { + CoTaskMemFree (lpswSubPkgName); + } + } + } + hr = pienum->MoveNext (&hasCurrent); + } + while (SUCCEEDED (hr) && hasCurrent) + { + CComPtr pinfo = NULL; + hr = pienum->GetCurrent (&pinfo); + if (pinfo && SUCCEEDED (hr)) + { + LPWSTR lpswSubPkgName = NULL; + hr = pinfo->GetFileName (&lpswSubPkgName); + if (lpswSubPkgName && SUCCEEDED (hr)) + { + CComPtr ifile = NULL; + hr = this->m_bundleReader->GetPayloadPackage (lpswSubPkgName, &ifile); + CoTaskMemFree (lpswSubPkgName); + if (ifile && SUCCEEDED (hr)) + { + AppxReader areader (ifile); + IStream *isfile = areader.extractFileToStream (lpswFilePath); + if (isfile) return isfile; + } + } + else if (lpswSubPkgName) + { + CoTaskMemFree (lpswSubPkgName); + } + } + hr = pienum->MoveNext (&hasCurrent); + } + return NULL; +} +IStream *BundleReader::extractFileToStream (std::wstring objswFilePath) +{ + return this->extractFileToStream (objswFilePath.c_str ()); +} +IStream *BundleReader::getPriFileStream () +{ + return this->extractFileToStream (L"resources.pri"); +} + +typedef enum _PKGTYPE { PKG_UNKNOWN = 0, PKG_SINGLE = 1, PKG_BUNDLE = 2 } PKGTYPE, pkgtype; + +typedef class PackageReader +{ + private: + AppxReader single; + BundleReader bundle; + public: + PackageReader (LPCWSTR lpwzFile); + PackageReader (std::wstring objwzFile); + PackageReader (); + bool create (LPCWSTR lpwzFile); + bool create (std::wstring objwzFile); + bool destroy (); + bool isAvailable (); + ~PackageReader (); + pkgtype getType (); + // ʧܷسΪ 0 յı + std::wstring getIdentityName (); + // ʧܷسΪ 0 յı + std::wstring getIdentityPublisher (); + // ʧܷضΪ 0 İ汾 + VERSION getIdentityVersion (); + size_t getIdentityProcessorArchitecture (std::vector &arrOut); + size_t getResourceLanguages (std::vector &vec); + LPCWSTR getFilePath (); + IAppxManifestReader *getAppxManifest (); + IAppxBundleManifestReader *getBundleManifest (); + // ˶ȡĶȡİΪ Bundle ָҪֶͷšֶ֮ͷţŶٶ + IAPPXREADER getAppxPackageReader () + { + switch (this->getType ()) + { + case PKG_SINGLE: return const_cast (single.getPackageReader ()); + case PKG_BUNDLE: return bundle.getAppxPackageReader (); + } + return NULL; + } + // ȡֶָͷţŶٶ + IBUNDLEREADER getBundlePackageReader () + { + if (this->getType () == PKG_BUNDLE) return const_cast (bundle.getPackageReader ()); + else return NULL; + } + std::wstring getPropertyName (); + std::wstring getPropertyDescription (); + std::wstring getPropertyPublisher (); + std::wstring getPropertyLogo (); + // ʧܷضΪ 0 İ汾 + VERSION getPrerequisiteOSMinVersion (); + // жϵǰǷΪӦðԴΪĻжǷӰдӦð + bool isPackageApplication (); + size_t getApplications (std::vector &output); + size_t getApplicationUserModelIDs (std::vector &output); + size_t getApplicationIDs (std::vector &output); + size_t getApplicationVisualElementsBackgroundColor (std::vector &output); + size_t getCapabilities (std::vector &output); + size_t getDependencies (std::vector &output); + IStream *getPriFileStream (); + IStream *extractFileToStream (LPCWSTR lpswFilePath); + IStream *extractFileToStream (std::wstring objswFilePath); +} pkgreader; +PackageReader::PackageReader (LPCWSTR lpwzFile) { create (lpwzFile); } +PackageReader::PackageReader (std::wstring objwzFile) { create (objwzFile); } +PackageReader::PackageReader (): single (), bundle () {} +bool PackageReader::create (LPCWSTR lpwzFile) +{ + this->destroy (); + return bundle.create (lpwzFile) || single.create (lpwzFile); +} +bool PackageReader::create (std::wstring objwzFile) { return this->create (objwzFile.c_str ()); } +bool PackageReader::destroy () +{ + if (!isAvailable ()) return false; + bool res = single.destroy (); + res = bundle.destroy () || res; + return res; +} +bool PackageReader::isAvailable () +{ + return single.isFileReaderAvailable () || bundle.isFileReaderAvailable (); +} +PackageReader::~PackageReader () { destroy (); } +pkgtype PackageReader::getType () +{ + if (single.isFileReaderAvailable ()) return PKG_SINGLE; + else if (bundle.isFileReaderAvailable ()) return PKG_BUNDLE; + else return PKG_UNKNOWN; +} +IAppxManifestReader *PackageReader::getAppxManifest () +{ + switch (this->getType ()) + { + case PKG_SINGLE: return single.getManifest (); + case PKG_BUNDLE: return bundle.getAppxManifest (); + } + return NULL; +} +IAppxBundleManifestReader *PackageReader::getBundleManifest () +{ + if (this->getType () == PKG_BUNDLE) return bundle.getManifest (); + return NULL; +} +// ʧܷسΪ 0 յı +std::wstring PackageReader::getIdentityName () +{ + std::wstring t (L""); + if (single.isFileReaderAvailable ()) return single.getIdentityName (); + if (bundle.isFileReaderAvailable ()) return bundle.getIdentityName (); + return t; +} +// ʧܷسΪ 0 յı +std::wstring PackageReader::getIdentityPublisher () +{ + std::wstring t (L""); + if (single.isFileReaderAvailable ()) return single.getIdentityPublisher (); + if (bundle.isFileReaderAvailable ()) return bundle.getIdentityPublisher (); + return t; +} +// ʧܷضΪ 0 İ汾 +VERSION PackageReader::getIdentityVersion () +{ + VERSION v (0); + if (single.isFileReaderAvailable ()) return single.getIdentityVersion (); + if (bundle.isFileReaderAvailable ()) return bundle.getIdentityVersion (); + return v; +} +size_t PackageReader::getIdentityProcessorArchitecture (std::vector &arrOut) +{ + + if (single.isFileReaderAvailable ()) return single.getIdentityProcessorArchitecture (arrOut); + if (bundle.isFileReaderAvailable ()) return bundle.getIdentityProcessorArchitecture (arrOut); + return 0; +} +size_t PackageReader::getResourceLanguages (std::vector &vec) +{ + if (single.isFileReaderAvailable ()) return single.getResourceLanguages (vec); + if (bundle.isFileReaderAvailable ()) return bundle.getResourceLanguages (vec); + return 0; +} +LPCWSTR PackageReader::getFilePath () +{ + switch (this->getType ()) + { + case PKG_SINGLE: return this->single.getFilePath (); + case PKG_BUNDLE: return this->bundle.getFilePath (); + } + return NULL; +} +std::wstring PackageReader::getPropertyName () +{ + if (single.isFileReaderAvailable ()) return single.getPropertyName (); + if (bundle.isFileReaderAvailable ()) return bundle.getPropertyName (); + return std::wstring (L""); +} +std::wstring PackageReader::getPropertyDescription () +{ + if (single.isFileReaderAvailable ()) return single.getPropertyDescription (); + if (bundle.isFileReaderAvailable ()) return bundle.getPropertyDescription (); + return std::wstring (L""); +} +std::wstring PackageReader::getPropertyPublisher () +{ + if (single.isFileReaderAvailable ()) return single.getPropertyPublisher (); + if (bundle.isFileReaderAvailable ()) return bundle.getPropertyPublisher (); + return std::wstring (L""); +} +std::wstring PackageReader::getPropertyLogo () +{ + if (single.isFileReaderAvailable ()) return single.getPropertyLogo (); + if (bundle.isFileReaderAvailable ()) return bundle.getPropertyLogo (); + return std::wstring (L""); +} +// ʧܷضΪ 0 İ汾 +VERSION PackageReader::getPrerequisiteOSMinVersion () +{ + VERSION v (0); + if (single.isFileReaderAvailable ()) return single.getPrerequisiteOSMinVersion (); + if (bundle.isFileReaderAvailable ()) return bundle.getPrerequisiteOSMinVersion (); + return v; +} +// жϵǰǷΪӦðԴΪĻжǷӰдӦð +bool PackageReader::isPackageApplication () +{ + if (single.isFileReaderAvailable ()) return single.isPackageApplication (); + if (bundle.isFileReaderAvailable ()) return bundle.isPackageApplication (); + return false; +} +size_t PackageReader::getApplications (std::vector &output) +{ + if (single.isFileReaderAvailable ()) return single.getApplications (output); + if (bundle.isFileReaderAvailable ()) return bundle.getApplications (output); + return 0; +} +size_t PackageReader::getApplicationUserModelIDs (std::vector &output) +{ + if (single.isFileReaderAvailable ()) return single.getApplicationUserModelIDs (output); + if (bundle.isFileReaderAvailable ()) return bundle.getApplicationUserModelIDs (output); + return 0; +} +size_t PackageReader::getApplicationIDs (std::vector &output) +{ + if (single.isFileReaderAvailable ()) return single.getApplicationIDs (output); + if (bundle.isFileReaderAvailable ()) return bundle.getApplicationIDs (output); + return 0; +} +size_t PackageReader::getApplicationVisualElementsBackgroundColor (std::vector &output) +{ + if (single.isFileReaderAvailable ()) return single.getApplicationVisualElementsBackgroundColor (output); + if (bundle.isFileReaderAvailable ()) return bundle.getApplicationVisualElementsBackgroundColor (output); + return 0; +} +size_t PackageReader::getCapabilities (std::vector &output) +{ + if (single.isFileReaderAvailable ()) return single.getCapabilities (output); + if (bundle.isFileReaderAvailable ()) return bundle.getCapabilities (output); + return 0; +} +size_t PackageReader::getDependencies (std::vector &output) +{ + if (single.isFileReaderAvailable ()) return single.getDependencies (output); + if (bundle.isFileReaderAvailable ()) return bundle.getDependencies (output); + return 0; +} +IStream *PackageReader::getPriFileStream () +{ + if (single.isFileReaderAvailable ()) return single.getPriFileStream (); + if (bundle.isFileReaderAvailable ()) return bundle.getPriFileStream (); + return NULL; +} +IStream *PackageReader::extractFileToStream (LPCWSTR lpswFilePath) +{ + if (single.isFileReaderAvailable ()) return single.extractFileToStream (lpswFilePath); + if (bundle.isFileReaderAvailable ()) return bundle.extractFileToStream (lpswFilePath); + return NULL; +} +IStream *PackageReader::extractFileToStream (std::wstring objswFilePath) +{ + if (single.isFileReaderAvailable ()) return single.extractFileToStream (objswFilePath); + if (bundle.isFileReaderAvailable ()) return bundle.extractFileToStream (objswFilePath); + return NULL; +} diff --git a/AppInstaller/pkginfo.h b/AppInstaller/pkginfo.h new file mode 100644 index 0000000..158b750 --- /dev/null +++ b/AppInstaller/pkginfo.h @@ -0,0 +1,196 @@ +#pragma once +#include "pkgcode.h" +#include "priread.h" +#include + +// ڴϢ +struct PackageInfomation +{ + struct Identity + { + std::wstring name = L""; + std::wstring publisher = L""; + VERSION version; + std::vector architectures; + } identities; + struct Resources + { + std::vector languages; + } resources; + struct Prerequisites + { + VERSION osMinVersion; + } prerequisites; + struct Property + { + std::wstring name = L""; + std::wstring description = L""; + std::wstring publisher = L""; + std::string logoBase64 = ""; + CComPtr logoStream = NULL; + } properties; + std::vector applications; + std::vector capabilities; + std::vector dependencies; + bool isMsResourceLabel (LPCSTR lpstr) + { + if (!lpstr) return false; + const std::string mslabel ("ms-resource:"); + std::string sub = StringTrim (std::string (lpstr)).substr (0, mslabel.length ()); + return LabelEqual (sub, mslabel); + } + bool isMsResourceLabel (LPCWSTR lpstr) + { + if (!lpstr) return false; + const std::wstring mslabel (L"ms-resource:"); + std::wstring sub = StringTrim (std::wstring (lpstr)).substr (0, mslabel.length ()); + return LabelEqual (sub, mslabel); + } + bool isMsResourceLabel (std::string objStr) { return isMsResourceLabel (objStr.c_str ()); } + bool isMsResourceLabel (std::wstring objStr) { return isMsResourceLabel (objStr.c_str ()); } + PackageInfomation (PackageReader &reader) { this->create (reader); } + PackageInfomation () {} + bool create (PackageReader &reader) + { + PriReader pri; + this->identities.name = reader.getIdentityName (); + this->identities.publisher = reader.getIdentityPublisher (); + this->identities.version = reader.getIdentityVersion (); + reader.getIdentityProcessorArchitecture (this->identities.architectures); + reader.getResourceLanguages (this->resources.languages); + std::sort (this->resources.languages.begin (), this->resources.languages.end ()); + if (pri.create (reader.getPriFileStream ())) + { + std::wstring temp = reader.getPropertyName (); + if (isMsResourceLabel (temp)) + { + std::wstring getres = pri.findStringValue (temp); + if (!getres.empty () && getres.length () > 0) temp = std::wstring (L"") + getres; + } + this->properties.name = temp; + temp = reader.getPropertyDescription (); + if (isMsResourceLabel (temp)) + { + std::wstring getres = pri.findStringValue (temp); + if (!getres.empty () && getres.length () > 0) temp = std::wstring (L"") + getres; + } + this->properties.description = temp; + temp = reader.getPropertyPublisher (); + if (isMsResourceLabel (temp)) + { + std::wstring getres = pri.findStringValue (temp); + if (!getres.empty () && getres.length () > 0) temp = std::wstring (L"") + getres; + } + this->properties.publisher = temp; + } + else + { + this->properties.name = reader.getPropertyName (); + this->properties.description = reader.getPropertyDescription (); + this->properties.publisher = reader.getPropertyPublisher (); + } + this->properties.logoBase64 = GetLogoBase64FromReader (reader, &this->properties.logoStream); + this->prerequisites.osMinVersion = reader.getPrerequisiteOSMinVersion (); + reader.getApplications (this->applications); + reader.getCapabilities (capabilities); + reader.getDependencies (dependencies); + return reader.isAvailable (); + } + void destroy () + { + this->identities.name = L""; + this->identities.publisher = L""; + this->identities.version = VERSION (0); + this->identities.architectures.clear (); + this->properties.name = L""; + this->properties.description = L""; + this->properties.publisher = L""; + this->properties.logoBase64 = ""; + if (this->properties.logoStream) { this->properties.logoStream.Release (); this->properties.logoStream = nullptr; } + this->resources.languages.clear (); + this->prerequisites.osMinVersion = VERSION (0); + this->applications.clear (); + this->capabilities.clear (); + this->dependencies.clear (); + } + // ʧܷسΪ 0 յı + std::wstring getIdentityName () { return this->identities.name; } + // ʧܷسΪ 0 յı + std::wstring getIdentityPublisher () { return this->identities.publisher; } + // ʧܷضΪ 0 İ汾 + VERSION getIdentityVersion () { return this->identities.version; } + size_t getIdentityProcessorArchitecture (std::vector &arrOut) + { + for (auto it : this->identities.architectures) + { + arrOut.push_back (it); + } + return arrOut.size (); + } + size_t getResourceLanguages (std::vector &vec) + { + for (auto it : this->resources.languages) + { + vec.push_back (it); + } + return vec.size (); + } + std::wstring getPropertyName () { return this->properties.name; } + std::wstring getPropertyDescription () { return this->properties.description; } + std::wstring getPropertyPublisher () { return this->properties.publisher; } + std::string getPropertyLogoBase64 () { return this->properties.logoBase64; } + // ֶͷ + IStream *getPropertyLogoIStream () { return this->properties.logoStream; } + // ʧܷضΪ 0 İ汾 + VERSION getPrerequisiteOSMinVersion () { return this->prerequisites.osMinVersion; } + // жϵǰǷΪӦðԴΪĻжǷӰдӦð + bool isPackageApplication () { return this->applications.size () > 0; } + size_t getApplications (std::vector &output) + { + for (auto it : this->applications) + { + output.push_back (it); + } + return output.size (); + } + size_t getApplicationUserModelIDs (std::vector &output) + { + for (auto it : this->applications) + { + output.push_back (it.getAppUserModelID ()); + } + return output.size (); + } + size_t getApplicationIDs (std::vector &output) + { + for (size_t cnt = 0; cnt < this->applications.size (); cnt ++) + { + output.push_back (this->applications [cnt] [std::wstring (L"Id")]); + } + return output.size (); + } + size_t getApplicationVisualElementsBackgroundColor (std::vector &output) + { + for (size_t cnt = 0; cnt < this->applications.size (); cnt ++) + { + output.push_back (this->applications [cnt] [std::wstring (L"BackgroundColor")]); + } + return output.size (); + } + size_t getCapabilities (std::vector &output) + { + for (auto it : this->capabilities) + { + output.push_back (it); + } + return output.size (); + } + size_t getDependencies (std::vector &output) + { + for (auto it : this->dependencies) + { + output.push_back (it); + } + return output.size (); + } +}; \ No newline at end of file diff --git a/AppInstaller/priread.h b/AppInstaller/priread.h new file mode 100644 index 0000000..0041052 --- /dev/null +++ b/AppInstaller/priread.h @@ -0,0 +1,377 @@ +#pragma once +// PRI APIֻʹ makepri +#include +#include +#include +#include "localeex.h" +#include +#include "pkgcode.h" +#include "PriReader2.h" + +std::string GetProgramRootDirectoryA () +{ + char path [MAX_PATH]; + if (GetModuleFileNameA (NULL, path, MAX_PATH)) + { + std::string dir (path); + size_t pos = dir.find_last_of ("\\/"); + if (pos != std::string::npos) + { + dir = dir.substr (0, pos); + } + return dir; + } + return ""; +} +std::wstring GetProgramRootDirectoryW () +{ + wchar_t path [MAX_PATH]; + if (GetModuleFileNameW (NULL, path, MAX_PATH)) + { + std::wstring dir (path); + size_t pos = dir.find_last_of (L"\\/"); + if (pos != std::wstring::npos) + { + dir = dir.substr (0, pos); + } + return dir; + } + return L""; +} +std::string EnsureTrailingSlash (const std::string &path) +{ + if (path.empty ()) return path; // ·ֱӷ + + char lastChar = path.back (); + if (lastChar == '\\' || lastChar == '/') + return path; // зֱָӷ + // ϵͳԭ·ʽʵķָ + char separator = (path.find ('/') != std::string::npos) ? '/' : '\\'; + return path + separator; +} +std::wstring EnsureTrailingSlash (const std::wstring &path) +{ + if (path.empty ()) return path; + + wchar_t lastChar = path.back (); + if (lastChar == L'\\' || lastChar == L'/') + return path; + + wchar_t separator = (path.find (L'/') != std::wstring::npos) ? L'/' : L'\\'; + return path + separator; +} +bool IsDirectoryExists (const std::string path) { return IsDirectoryExistsA (path.c_str ()); } +bool IsDirectoryExists (const std::wstring path) { return IsDirectoryExistsW (path.c_str ()); } +bool IsDirectoryExists (LPCSTR path) { return IsDirectoryExistsA (path); } +bool IsDirectoryExists (LPCWSTR path) { return IsDirectoryExistsW (path); } +std::string NormalizePath (const std::string &path) +{ + if (!path.empty () && path.back () == '\\') + return path.substr (0, path.size () - 1); + return path; +} +std::wstring NormalizePath (const std::wstring &path) +{ + if (!path.empty () && path.back () == L'\\') + return path.substr (0, path.size () - 1); + return path; +} +std::vector EnumSubdirectories (const std::string &directory, bool includeParentPath) +{ + std::vector subdirs; + std::string normPath = NormalizePath (directory); + std::string searchPath = normPath + "\\*"; + WIN32_FIND_DATAA findData; + HANDLE hFind = FindFirstFileA (searchPath.c_str (), &findData); + if (hFind == INVALID_HANDLE_VALUE) return subdirs; + do + { + // "." ".." + if (strcmp (findData.cFileName, ".") == 0 || strcmp (findData.cFileName, "..") == 0) + continue; + // жǷΪĿ¼ + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (includeParentPath) + subdirs.push_back (normPath + "\\" + findData.cFileName); + else + subdirs.push_back (findData.cFileName); + } + } while (FindNextFileA (hFind, &findData)); + FindClose (hFind); + return subdirs; +} +std::vector EnumSubdirectories (const std::wstring &directory, bool includeParentPath) +{ + std::vector subdirs; + std::wstring normPath = NormalizePath (directory); + std::wstring searchPath = normPath + L"\\*"; + WIN32_FIND_DATAW findData; + HANDLE hFind = FindFirstFileW (searchPath.c_str (), &findData); + if (hFind == INVALID_HANDLE_VALUE) return subdirs; + do + { + if (wcscmp (findData.cFileName, L".") == 0 || wcscmp (findData.cFileName, L"..") == 0) + continue; + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (includeParentPath) + subdirs.push_back (normPath + L"\\" + findData.cFileName); + else + subdirs.push_back (findData.cFileName); + } + } while (FindNextFileW (hFind, &findData)); + FindClose (hFind); + return subdirs; +} +bool CheckDependency (const std::string &dllName) +{ + HMODULE hModule = LoadLibraryA (dllName.c_str ()); + if (hModule == NULL) + { + return false; + } + FreeLibrary (hModule); + return true; +} +bool CheckDependency (const std::wstring &dllName) +{ + HMODULE hModule = LoadLibraryW (dllName.c_str ()); + if (hModule == NULL) + { + return false; + } + FreeLibrary (hModule); + return true; +} +bool CanRunExe (const std::string &exePath) +{ + STARTUPINFOA si = {sizeof (si)}; + PROCESS_INFORMATION pi; + BOOL success = CreateProcessA ( + exePath.c_str (), // Ӧ· + NULL, // в + NULL, // ȫ + NULL, // ̰߳ȫ + FALSE, // ̳о + CREATE_NO_WINDOW, // + NULL, // + NULL, // ǰĿ¼ + &si, // Ϣ + &pi // Ϣ + ); + if (!success) + { + DWORD error = GetLastError (); + return false; + } + WaitForSingleObject (pi.hProcess, INFINITE); + DWORD exitCode; + GetExitCodeProcess (pi.hProcess, &exitCode); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return (exitCode == 0); +} +bool CanRunExe (const std::wstring& exePath) +{ + STARTUPINFOW si = {sizeof (si)}; + PROCESS_INFORMATION pi; + BOOL success = CreateProcessW ( + exePath.c_str (), // Ӧ· + NULL, // в + NULL, // ȫ + NULL, // ̰߳ȫ + FALSE, // ̳о + CREATE_NO_WINDOW, // + NULL, // + NULL, // ǰĿ¼ + &si, // Ϣ + &pi // Ϣ + ); + if (!success) + { + DWORD error = GetLastError (); + return false; + } + WaitForSingleObject (pi.hProcess, INFINITE); + DWORD exitCode; + GetExitCodeProcess (pi.hProcess, &exitCode); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return (exitCode == 0); +} +bool IsProgramExecutable (const std::string &exePath) +{ + if (!IsFileExists (exePath)) + { + return false; + } + if (!CanRunExe (exePath)) + { + return false; + } + return true; +} +bool IsProgramExecutable (const std::wstring &exePath) +{ + if (!IsFileExists (exePath)) + { + return false; + } + if (!CanRunExe (exePath)) + { + return false; + } + return true; +} +std::wstring GetUniqueTempFilePathW () +{ + // ȡʱļ· + wchar_t tempPath [MAX_PATH]; + if (GetTempPath (MAX_PATH, tempPath) == 0) + { + return L""; + } + // һΨһʱļ + wchar_t tempFile [MAX_PATH]; + if (GetTempFileName (tempPath, L"TMP", 0, tempFile) == 0) + { + return L""; + } + return tempFile; +} +std::string GetUniqueTempFilePathA () { + // ȡʱļ· + char tempPath [MAX_PATH]; + if (GetTempPathA (MAX_PATH, tempPath) == 0) + { + return ""; + } + // һΨһʱļ + char tempFile [MAX_PATH]; + if (GetTempFileNameA (tempPath, "TMP", 0, tempFile) == 0) + { + return ""; + } + return tempFile; +} +int InStr (const std::string &text, const std::string &keyword, bool ignoreCase = false) +{ + std::string s1, s2; + if (ignoreCase) + { + s1 = StringToUpper (text); + s2 = StringToUpper (keyword); + } + else + { + s1 = text; + s2 = keyword; + } + const char *found = StrStrIA (s1.c_str (), s2.c_str ()); + if (!found) + { + return -1; + } + return found - text.c_str (); +} +int InStr (const std::wstring &text, const std::wstring &keyword, bool ignoreCase = false) +{ + std::wstring s1, s2; + if (ignoreCase) + { + s1 = StringToUpper (text); + s2 = StringToUpper (keyword); + } + else + { + s1 = text; + s2 = keyword; + } + const WCHAR *found = StrStrIW (s1.c_str (), s2.c_str ()); + if (!found) + { + return -1; + } + return found - text.c_str (); +} + +template StringType ReplaceBackslash (const StringType &input) +{ + StringType result = input; // ַ޸ԭ + using CharType = typename StringType::value_type; // ȡַַͣchar wchar_t + std::replace (result.begin (), result.end (), static_cast ('\\'), static_cast ('/')); + return result; +} + +class PriReader +{ + private: + HPRIREADER priReader; + public: + PriReader (LPCWSTR lpPriFilePath) { this->create (lpPriFilePath); } + PriReader (const std::wstring objPriFilePath) { this->create (objPriFilePath); } + PriReader (IStream *comISPriFile) { this->create (comISPriFile); } + ~PriReader () { this->destroy (); } + PriReader (): priReader (NULL) {} + void destroy () + { + if (!priReader) return; + DestroyPriReader (priReader); + priReader = NULL; + } + bool isAvailable () { return priReader != nullptr; } + bool create (const std::wstring priFile) { destroy (); return priReader = CreatePriReader (priFile.c_str ()); } + bool create (LPCWSTR priFile) { destroy (); if (!priFile) return false; return this->create (std::wstring (priFile)); } + bool create (IStream *priFStream) { destroy (); return priReader = CreatePriReaderFromStream (priFStream); } + // ȡָҪ free ֶͷš + LPSTR findStringValue (LPCSTR lpMsName, LPCSTR defaultLocaleCode = NULL) + { + return PriReaderFindStringValueA (priReader, lpMsName, defaultLocaleCode); + } + // ȡָҪ free ֶͷš + LPWSTR findStringValue (LPCWSTR lpMsName, LPCWSTR defaultLocaleCode = NULL) + { + return PriReaderFindStringValueW (priReader, lpMsName, defaultLocaleCode); + } + std::string findStringValue (const std::string &objMsName, const std::string &defaultLocaleCode = "") + { + std::string t (""); + LPSTR lpStr = findStringValue (objMsName.c_str (), ((!defaultLocaleCode.empty () && defaultLocaleCode.length () > 0) ? defaultLocaleCode.c_str () : NULL)); + if (lpStr) t += lpStr; + if (lpStr) free (lpStr); + return t; + } + std::wstring findStringValue (const std::wstring &objMsName, const std::wstring &defaultLocaleCode = L"") + { + std::wstring t (L""); + LPWSTR lpStr = findStringValue (objMsName.c_str (), ((!defaultLocaleCode.empty () && defaultLocaleCode.length () > 0) ? defaultLocaleCode.c_str () : NULL)); + if (lpStr) t += lpStr; + if (lpStr) free (lpStr); + return t; + } + LPSTR findFilePathValue (LPCSTR lpMsName, int defaultScale = 0, ImageContrast defaultContrast = ImageContrast::none) + { + return PriReaderFindFilePathValueA (priReader, lpMsName, defaultScale, defaultContrast); + } + LPWSTR findFilePathValue (LPCWSTR lpMsName, int defaultScale = 0, ImageContrast defaultContrast = ImageContrast::none) + { + return PriReaderFindFilePathValueW (priReader, lpMsName, defaultScale, defaultContrast); + } + std::string findFilePathValue (const std::string &objMsName, int defaultScale = 0, ImageContrast defaultContrast = ImageContrast::none) + { + std::string t (""); + LPSTR lpStr = findFilePathValue (objMsName.c_str (), defaultScale, defaultContrast); + if (lpStr) t += lpStr; + if (lpStr) free (lpStr); + return t; + } + std::wstring findFilePathValue (const std::wstring &objMsName, int defaultScale = 0, ImageContrast defaultContrast = ImageContrast::none) + { + std::wstring t (L""); + LPWSTR lpStr = findFilePathValue (objMsName.c_str (), defaultScale, defaultContrast); + if (lpStr) t += lpStr; + if (lpStr) free (lpStr); + return t; + } +}; \ No newline at end of file diff --git a/AppInstaller/res/Button/Large/blank.png b/AppInstaller/res/Button/Large/blank.png new file mode 100644 index 0000000..4a12390 Binary files /dev/null and b/AppInstaller/res/Button/Large/blank.png differ diff --git a/AppInstaller/res/Button/Large/blank_light.png b/AppInstaller/res/Button/Large/blank_light.png new file mode 100644 index 0000000..a44303d Binary files /dev/null and b/AppInstaller/res/Button/Large/blank_light.png differ diff --git a/AppInstaller/res/Button/Large/blank_press.png b/AppInstaller/res/Button/Large/blank_press.png new file mode 100644 index 0000000..0376f98 Binary files /dev/null and b/AppInstaller/res/Button/Large/blank_press.png differ diff --git a/AppInstaller/res/Button/Large/cancel_window_light.png b/AppInstaller/res/Button/Large/cancel_window_light.png new file mode 100644 index 0000000..45e3fe0 Binary files /dev/null and b/AppInstaller/res/Button/Large/cancel_window_light.png differ diff --git a/AppInstaller/res/Button/Large/cancel_window_normal.png b/AppInstaller/res/Button/Large/cancel_window_normal.png new file mode 100644 index 0000000..dd1442c Binary files /dev/null and b/AppInstaller/res/Button/Large/cancel_window_normal.png differ diff --git a/AppInstaller/res/Button/Large/cancel_window_press.png b/AppInstaller/res/Button/Large/cancel_window_press.png new file mode 100644 index 0000000..171508c Binary files /dev/null and b/AppInstaller/res/Button/Large/cancel_window_press.png differ diff --git a/AppInstaller/res/Button/Large/max_light.png b/AppInstaller/res/Button/Large/max_light.png new file mode 100644 index 0000000..8b6fe0c Binary files /dev/null and b/AppInstaller/res/Button/Large/max_light.png differ diff --git a/AppInstaller/res/Button/Large/max_normal.png b/AppInstaller/res/Button/Large/max_normal.png new file mode 100644 index 0000000..4fcdd76 Binary files /dev/null and b/AppInstaller/res/Button/Large/max_normal.png differ diff --git a/AppInstaller/res/Button/Large/max_press.png b/AppInstaller/res/Button/Large/max_press.png new file mode 100644 index 0000000..53b911a Binary files /dev/null and b/AppInstaller/res/Button/Large/max_press.png differ diff --git a/AppInstaller/res/Button/Large/max_trans_normal.png b/AppInstaller/res/Button/Large/max_trans_normal.png new file mode 100644 index 0000000..09aa968 Binary files /dev/null and b/AppInstaller/res/Button/Large/max_trans_normal.png differ diff --git a/AppInstaller/res/Button/Large/min_light.png b/AppInstaller/res/Button/Large/min_light.png new file mode 100644 index 0000000..8e9e960 Binary files /dev/null and b/AppInstaller/res/Button/Large/min_light.png differ diff --git a/AppInstaller/res/Button/Large/min_normal.png b/AppInstaller/res/Button/Large/min_normal.png new file mode 100644 index 0000000..efe7ffc Binary files /dev/null and b/AppInstaller/res/Button/Large/min_normal.png differ diff --git a/AppInstaller/res/Button/Large/min_press.png b/AppInstaller/res/Button/Large/min_press.png new file mode 100644 index 0000000..c367ae7 Binary files /dev/null and b/AppInstaller/res/Button/Large/min_press.png differ diff --git a/AppInstaller/res/Button/Large/min_trans_normal.png b/AppInstaller/res/Button/Large/min_trans_normal.png new file mode 100644 index 0000000..8e9a54f Binary files /dev/null and b/AppInstaller/res/Button/Large/min_trans_normal.png differ diff --git a/AppInstaller/res/Button/Large/restore_light.png b/AppInstaller/res/Button/Large/restore_light.png new file mode 100644 index 0000000..3552d68 Binary files /dev/null and b/AppInstaller/res/Button/Large/restore_light.png differ diff --git a/AppInstaller/res/Button/Large/restore_normal.png b/AppInstaller/res/Button/Large/restore_normal.png new file mode 100644 index 0000000..8aad4d5 Binary files /dev/null and b/AppInstaller/res/Button/Large/restore_normal.png differ diff --git a/AppInstaller/res/Button/Large/restore_press.png b/AppInstaller/res/Button/Large/restore_press.png new file mode 100644 index 0000000..a848ece Binary files /dev/null and b/AppInstaller/res/Button/Large/restore_press.png differ diff --git a/AppInstaller/res/Button/Large/restore_trans_normal.png b/AppInstaller/res/Button/Large/restore_trans_normal.png new file mode 100644 index 0000000..bc01f58 Binary files /dev/null and b/AppInstaller/res/Button/Large/restore_trans_normal.png differ diff --git a/AppInstaller/res/Button/Normal/blank.png b/AppInstaller/res/Button/Normal/blank.png new file mode 100644 index 0000000..0431c20 Binary files /dev/null and b/AppInstaller/res/Button/Normal/blank.png differ diff --git a/AppInstaller/res/Button/Normal/blank_light.png b/AppInstaller/res/Button/Normal/blank_light.png new file mode 100644 index 0000000..3328fa7 Binary files /dev/null and b/AppInstaller/res/Button/Normal/blank_light.png differ diff --git a/AppInstaller/res/Button/Normal/blank_press.png b/AppInstaller/res/Button/Normal/blank_press.png new file mode 100644 index 0000000..cf8aa85 Binary files /dev/null and b/AppInstaller/res/Button/Normal/blank_press.png differ diff --git a/AppInstaller/res/Button/Normal/cancel_back.png b/AppInstaller/res/Button/Normal/cancel_back.png new file mode 100644 index 0000000..6ed1343 Binary files /dev/null and b/AppInstaller/res/Button/Normal/cancel_back.png differ diff --git a/AppInstaller/res/Button/Normal/cancel_light.png b/AppInstaller/res/Button/Normal/cancel_light.png new file mode 100644 index 0000000..bc89c71 Binary files /dev/null and b/AppInstaller/res/Button/Normal/cancel_light.png differ diff --git a/AppInstaller/res/Button/Normal/cancel_press.png b/AppInstaller/res/Button/Normal/cancel_press.png new file mode 100644 index 0000000..6cc0e3c Binary files /dev/null and b/AppInstaller/res/Button/Normal/cancel_press.png differ diff --git a/AppInstaller/res/Button/Normal/max_back.png b/AppInstaller/res/Button/Normal/max_back.png new file mode 100644 index 0000000..92b54c2 Binary files /dev/null and b/AppInstaller/res/Button/Normal/max_back.png differ diff --git a/AppInstaller/res/Button/Normal/max_light.png b/AppInstaller/res/Button/Normal/max_light.png new file mode 100644 index 0000000..10bb4a6 Binary files /dev/null and b/AppInstaller/res/Button/Normal/max_light.png differ diff --git a/AppInstaller/res/Button/Normal/max_press.png b/AppInstaller/res/Button/Normal/max_press.png new file mode 100644 index 0000000..a83fbfc Binary files /dev/null and b/AppInstaller/res/Button/Normal/max_press.png differ diff --git a/AppInstaller/res/Button/Normal/min_back.png b/AppInstaller/res/Button/Normal/min_back.png new file mode 100644 index 0000000..709a12a Binary files /dev/null and b/AppInstaller/res/Button/Normal/min_back.png differ diff --git a/AppInstaller/res/Button/Normal/min_light.png b/AppInstaller/res/Button/Normal/min_light.png new file mode 100644 index 0000000..17675ea Binary files /dev/null and b/AppInstaller/res/Button/Normal/min_light.png differ diff --git a/AppInstaller/res/Button/Normal/min_press.png b/AppInstaller/res/Button/Normal/min_press.png new file mode 100644 index 0000000..db95770 Binary files /dev/null and b/AppInstaller/res/Button/Normal/min_press.png differ diff --git a/AppInstaller/res/Button/Normal/restore_back.png b/AppInstaller/res/Button/Normal/restore_back.png new file mode 100644 index 0000000..c10da8b Binary files /dev/null and b/AppInstaller/res/Button/Normal/restore_back.png differ diff --git a/AppInstaller/res/Button/Normal/restore_light.png b/AppInstaller/res/Button/Normal/restore_light.png new file mode 100644 index 0000000..3eada01 Binary files /dev/null and b/AppInstaller/res/Button/Normal/restore_light.png differ diff --git a/AppInstaller/res/Button/Normal/restore_press.png b/AppInstaller/res/Button/Normal/restore_press.png new file mode 100644 index 0000000..d64f607 Binary files /dev/null and b/AppInstaller/res/Button/Normal/restore_press.png differ diff --git a/AppInstaller/res/Fonts/IDR_SETUP_FONT.TTF b/AppInstaller/res/Fonts/IDR_SETUP_FONT.TTF new file mode 100644 index 0000000..bc89e9c Binary files /dev/null and b/AppInstaller/res/Fonts/IDR_SETUP_FONT.TTF differ diff --git a/AppInstaller/res/Icons/FileIcon.ico b/AppInstaller/res/Icons/FileIcon.ico new file mode 100644 index 0000000..074eb28 Binary files /dev/null and b/AppInstaller/res/Icons/FileIcon.ico differ diff --git a/AppInstaller/res/Icons/IconColor.ico b/AppInstaller/res/Icons/IconColor.ico new file mode 100644 index 0000000..3db5e1a Binary files /dev/null and b/AppInstaller/res/Icons/IconColor.ico differ diff --git a/AppInstaller/res/Icons/IconTitleBar.ico b/AppInstaller/res/Icons/IconTitleBar.ico new file mode 100644 index 0000000..3b0063a Binary files /dev/null and b/AppInstaller/res/Icons/IconTitleBar.ico differ diff --git a/AppInstaller/res/Icons/IconWhite.ico b/AppInstaller/res/Icons/IconWhite.ico new file mode 100644 index 0000000..12dc50a Binary files /dev/null and b/AppInstaller/res/Icons/IconWhite.ico differ diff --git a/AppInstaller/res/Icons/Main.ico b/AppInstaller/res/Icons/Main.ico new file mode 100644 index 0000000..1ba811e Binary files /dev/null and b/AppInstaller/res/Icons/Main.ico differ diff --git a/AppInstaller/res/Pictures/Trans.png b/AppInstaller/res/Pictures/Trans.png new file mode 100644 index 0000000..076cd28 Binary files /dev/null and b/AppInstaller/res/Pictures/Trans.png differ diff --git a/AppInstaller/res/Pictures/Trans_old.png b/AppInstaller/res/Pictures/Trans_old.png new file mode 100644 index 0000000..6e3f92d Binary files /dev/null and b/AppInstaller/res/Pictures/Trans_old.png differ diff --git a/AppInstaller/res/icon.ico b/AppInstaller/res/icon.ico new file mode 100644 index 0000000..f1e0de9 Binary files /dev/null and b/AppInstaller/res/icon.ico differ diff --git a/AppInstaller/res/manifest.xml b/AppInstaller/res/manifest.xml new file mode 100644 index 0000000..44d54ca --- /dev/null +++ b/AppInstaller/res/manifest.xml @@ -0,0 +1,25 @@ + + + + + + + True/PM + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AppInstaller/res2.h b/AppInstaller/res2.h new file mode 100644 index 0000000..08b8476 --- /dev/null +++ b/AppInstaller/res2.h @@ -0,0 +1,156 @@ +#pragma once +#include "resource.h" +#include "pkgcode.h" +bool IsEqualLabel (std::wstring str1, std::wstring str2) +{ + std::wstring s1 = StringToUpper (StringTrim (str1)), + s2 = StringToUpper (StringTrim (str2)); + return s1 == s2; +} +typedef class _LABEL +{ + private: + std::wstring objwsStr; + public: + template explicit _LABEL (const T& str) + { + std::wstringstream wss; + wss << str; + objwsStr = wss.str (); + } + _LABEL (const _LABEL &label) + { + objwsStr = std::wstring (label.objwsStr); + } + _LABEL (): objwsStr (L"") {} + friend bool operator == (const _LABEL &l1, const _LABEL &l2) + { + return IsEqualLabel (l1.objwsStr, l2.objwsStr); + } + friend bool operator == (LPCWSTR &l1, const _LABEL &l2) + { + return IsEqualLabel (_LABEL (l1).objwsStr, l2.objwsStr); + } + friend bool operator == (const _LABEL &l2, LPCWSTR &l1) + { + return IsEqualLabel (_LABEL (l1).objwsStr, l2.objwsStr); + } + friend bool operator == (std::wstring &l1, const _LABEL &l2) + { + return IsEqualLabel (_LABEL (l1).objwsStr, l2.objwsStr); + } + friend bool operator == (const _LABEL &l2, std::wstring &l1) + { + return IsEqualLabel (_LABEL (l1).objwsStr, l2.objwsStr); + } + _LABEL operator = (const _LABEL &other) + { + if (this != &other) this->objwsStr = std::wstring (other.objwsStr); + return *this; + } + _LABEL operator = (LPCWSTR &lpWStr) + { + this->objwsStr = std::wstring (lpWStr); + return *this; + } + _LABEL operator = (const std::wstring &obj) + { + this->objwsStr = std::wstring (obj); + return *this; + } + std::wstring getStr () const { return objwsStr; } + LPCWSTR getStrC () { return objwsStr.c_str (); } + bool operator < (const _LABEL &other) const + { + std::wstring s1 = StringToUpper (StringTrim (this->objwsStr)), + s2 = StringToUpper (StringTrim (other.objwsStr)); + return s1 < s2; + } +} LABEL; +typedef std::map MAP_LABEL_UINT; +bool isinitcapmap = false; +MAP_LABEL_UINT capmap; +void InitCapabilitiesMap () +{ + if (isinitcapmap) return; + isinitcapmap = true; + capmap [LABEL (L"internetClient")] = internetClient; + capmap [LABEL (L"internetClientServer")] = internetClientServer; + capmap [LABEL (L"privateNetworkClientServer")] = privateNetworkClientServer; + capmap [LABEL (L"documentsLibrary")] = documentsLibrary; + capmap [LABEL (L"picturesLibrary")] = picturesLibrary; + capmap [LABEL (L"videosLibrary")] = videosLibrary; + capmap [LABEL (L"musicLibrary")] = musicLibrary; + capmap [LABEL (L"enterpriseAuthentication")] = enterpriseAuthentication; + capmap [LABEL (L"sharedUserCertificates")] = sharedUserCertificates; + capmap [LABEL (L"removableStorage")] = removableStorage; + capmap [LABEL (L"appointments")] = appointments; + capmap [LABEL (L"contacts")] = contacts; + capmap [LABEL (L"phoneCall")] = phoneCall; + capmap [LABEL (L"backgroundMediaPlayback")] = backgroundMediaPlayback; + capmap [LABEL (L"pointOfService")] = pointOfService; + capmap [LABEL (L"allJoyn")] = allJoyn; + capmap [LABEL (L"phoneCallHistoryPublic")] = phoneCallHistoryPublic; + capmap [LABEL (L"microphone")] = microphone; + capmap [LABEL (L"offlineMapsManagement")] = offlineMapsManagement; + capmap [LABEL (L"objects5D")] = objects5D; + capmap [LABEL (L"objects3D")] = objects3D; + capmap [LABEL (L"graphicsCaptureWithoutBorder")] = graphicsCaptureWithoutBorder; + capmap [LABEL (L"bluetooth")] = bluetooth; + capmap [LABEL (L"lowLevelDevices")] = lowLevelDevices; + capmap [LABEL (L"location")] = location; + capmap [LABEL (L"humaninterfacedevice")] = humaninterfacedevice; + capmap [LABEL (L"recordedCallsFolder")] = recordedCallsFolder; + capmap [LABEL (L"proximity")] = proximity; + capmap [LABEL (L"webcam")] = webcam; + capmap [LABEL (L"graphicsCaptureProgrammatic")] = graphicsCaptureProgrammatic; + capmap [LABEL (L"userNotificationListener")] = userNotificationListener; + capmap [LABEL (L"userDataTasks")] = userDataTasks; + capmap [LABEL (L"userAccountInformation")] = userAccountInformation; + capmap [LABEL (L"usb")] = usb; + capmap [LABEL (L"systemManagement")] = systemManagement; + capmap [LABEL (L"spatialPerception")] = spatialPerception; + capmap [LABEL (L"smsSend")] = smsSend; + capmap [LABEL (L"blockedChatMessages")] = blockedChatMessages; + capmap [LABEL (L"chat")] = chat; + capmap [LABEL (L"codeGeneration")] = codeGeneration; + capmap [LABEL (L"voipCall")] = voipCall; + capmap [LABEL (L"enterpriseDataPolicy")] = enterpriseDataPolicy; + capmap [LABEL (L"inputInjectionBrokered")] = inputInjectionBrokered; + capmap [LABEL (L"remoteSystem")] = remoteSystem; + capmap [LABEL (L"inProcessMediaExtension")] = inProcessMediaExtension; + capmap [LABEL (L"webPlatformMediaExtension")] = webPlatformMediaExtension; + capmap [LABEL (L"previewStore")] = previewStore; + capmap [LABEL (L"confirmAppClose")] = confirmAppClose; + capmap [LABEL (L"runFullTrust")] = runFullTrust; + capmap [LABEL (L"previewUiComposition")] = previewUiComposition; + capmap [LABEL (L"slapiQueryLicenseValue")] = slapiQueryLicenseValue; + capmap [LABEL (L"localSystemServices")] = localSystemServices; + capmap [LABEL (L"packageManagement")] = packageManagement; + capmap [LABEL (L"packageQuery")] = packageQuery; + capmap [LABEL (L"packagePolicySystem")] = packagePolicySystem; + capmap [LABEL (L"storeAppInstall")] = storeAppInstall; + capmap [LABEL (L"appLicensing")] = appLicensing; + capmap [LABEL (L"broadFileSystemAccess")] = broadFileSystemAccess; + capmap [LABEL (L"allowElevation")] = allowElevation; + capmap [LABEL (L"unvirtualizedResources")] = unvirtualizedResources; + capmap [LABEL (L"extendedExecution")] = extendedExecution; + capmap [LABEL (L"appointmentsSystem")] = appointmentsSystem; + capmap [LABEL (L"contactsSystem")] = contactsSystem; + capmap [LABEL (L"phoneCallSystem")] = phoneCallSystem; + capmap [LABEL (L"userDataAccounts")] = userDataAccounts; + capmap [LABEL (L"userDataTasksSystem")] = userDataTasksSystem; +} +// ʧܷ NULL +UINT CapabilitiesNameToID (LPCWSTR lpStr) +{ + if (!lpStr) return NULL; + InitCapabilitiesMap (); + auto it = capmap.find (LABEL (lpStr)); + if (it != capmap.end ()) return it->second; + else return NULL; +} +UINT CapabilitiesNameToID (std::wstring objStr) +{ + return CapabilitiesNameToID (objStr.c_str ()); +} \ No newline at end of file diff --git a/AppInstaller/resource.h b/AppInstaller/resource.h new file mode 100644 index 0000000..d1272f2 --- /dev/null +++ b/AppInstaller/resource.h @@ -0,0 +1,162 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ ɵİļ +// AppInstaller.rc ʹ +// +#pragma once +#define IDR_MANIFEST1 1 +#define IDR_VERSION_ZH_CN 1 +#define IDR_VERSION_EN_US 2 +#define MANIFEST 24 +#define BLANK_NORMAL 99 +#define BLANK_LIGHT 100 +#define BLANK_PRESS 101 +#define MIN_NORMAL 102 +#define MIN_LIGHT 103 +#define MIN_PRESS 104 +#define MAX_NORMAL 105 +#define MAX_LIGHT 106 +#define MAX_PRESS 107 +#define RESTORE_NORMAL 108 +#define RESTORE_LIGHT 109 +#define RESTORE_PRESS 110 +#define CANCEL_NORMAL 111 +#define CANCEL_LIGHT 112 +#define CANCEL_PRESS 113 +#define BLANK_LARGR_NORMAL 114 +#define BLANK_LARGR_LIGHT 115 +#define BLANK_LARGR_PRESS 116 +#define MIN_LARGR_NORMAL 117 +#define MIN_LARGE_LIGHT 118 +#define MIN_LARGR_PRESS 119 +#define MAX_LARGE_NORMAL 120 +#define MAX_LARGE_LIGHT 121 +#define MAX_LARGE_PRESS 122 +#define RESTORE_LARGE_NORMAL 123 +#define RESTORE_LARGE_LIGHT 124 +#define RESTORE_LARGE_PRESS 125 +#define CANCEL_LARGE_NORMAL 126 +#define CANCEL_LARGE_LIGHT 127 +#define CANCEL_LARGE_PRESS 128 +#define IDI_MAINICON 129 +#define ICON_TASKBAR 130 +#define ICON_FILE 131 +#define ICON_WHITE 132 +#define ICON_METRO 133 +#define ICON_COLOR 136 +#define WIN_TITLE 300 +#define PAGE_LOADING 301 +#define PAGE_1_TITLE 302 +#define PAGE_INFO_PUBLISHER 303 +#define PAGE_INFO_VERSION 304 +#define PAGE_FUNCTIONS 305 +#define PAGE_CHECK_RUNWHENREADY 306 +#define PAGE_2_LOADCERT 307 +#define PAGE_2_INSTALL 308 +#define PAGE_3_TITLE 309 +#define PAGE_4_TITLE 310 +#define PAGE_5_TITLE 311 +#define DIALOG_SELLET_APPX 312 +#define DIALOG_SELLET_UNI 313 +#define BUTTON_1_SER1 314 +#define BUTTON_3_SER1 315 +#define BUTTON_4_SER1 316 +#define BUTTON_5_SER1 317 +#define DIALOG_WINTITLE 318 +#define PAGE_1_APPHASINSTALLED 319 +#define PAGE_2_TITLE 320 +#define PAGE_1_APP 321 +#define PAGE_2_LOADING 322 +#define PAGE_2_INSTALLING 323 +#define CLHELP_1 330 +#define CLHELP_2 331 +#define CLHELP_3 332 +#define CLHELP_4 333 +#define CLHELP_5 334 +#define CLHELP_6 335 +#define CLHELP_7 336 +#define INITWIDTH 400 +#define INITHEIGHT 401 +#define LIMITWIDTH 402 +#define LIMITHEIGHT 403 +#define textSupportCPU 450 +#define textSupportSystem 451 +#define textSupportLanguage 452 +#define textDependency 453 +#define textDependencyItem 454 +#define internetClient 500 +#define internetClientServer 501 +#define privateNetworkClientServer 502 +#define documentsLibrary 503 +#define picturesLibrary 504 +#define videosLibrary 505 +#define musicLibrary 506 +#define enterpriseAuthentication 507 +#define sharedUserCertificates 508 +#define removableStorage 509 +#define appointments 510 +#define contacts 511 +#define phoneCall 512 +#define backgroundMediaPlayback 513 +#define pointOfService 514 +#define allJoyn 515 +#define phoneCallHistoryPublic 516 +#define microphone 517 +#define offlineMapsManagement 518 +#define objects5D 519 +#define objects3D 519 +#define graphicsCaptureWithoutBorder 520 +#define bluetooth 521 +#define lowLevelDevices 522 +#define location 523 +#define humaninterfacedevice 524 +#define recordedCallsFolder 525 +#define proximity 526 +#define webcam 527 +#define graphicsCaptureProgrammatic 528 +#define userNotificationListener 529 +#define userDataTasks 530 +#define userAccountInformation 531 +#define usb 532 +#define systemManagement 533 +#define spatialPerception 534 +#define smsSend 535 +#define blockedChatMessages 536 +#define chat 537 +#define codeGeneration 538 +#define voipCall 539 +#define enterpriseDataPolicy 540 +#define inputInjectionBrokered 541 +#define remoteSystem 542 +#define inProcessMediaExtension 544 +#define webPlatformMediaExtension 545 +#define previewStore 546 +#define confirmAppClose 547 +#define runFullTrust 548 +#define previewUiComposition 549 +#define slapiQueryLicenseValue 550 +#define localSystemServices 551 +#define packageManagement 552 +#define packageQuery 553 +#define packagePolicySystem 554 +#define storeAppInstall 555 +#define appLicensing 556 +#define broadFileSystemAccess 557 +#define allowElevation 558 +#define unvirtualizedResources 559 +#define extendedExecution 560 +#define appointmentsSystem 561 +#define contactsSystem 562 +#define phoneCallSystem 563 +#define userDataAccounts 564 +#define userDataTasksSystem 565 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/AppLauncher/AppLauncher.cpp b/AppLauncher/AppLauncher.cpp new file mode 100644 index 0000000..fb48515 --- /dev/null +++ b/AppLauncher/AppLauncher.cpp @@ -0,0 +1,31 @@ +// AppLauncher.cpp : DLL Ӧóĵ +// + +#include "stdafx.h" +#include "AppLauncher.h" + +HRESULT LaunchApp (LPCWSTR lpswStr, PDWORD pdwProcessId) +{ + if (!lpswStr) return E_INVALIDARG; + if (FAILED (CoInitializeEx (NULL, COINIT_APARTMENTTHREADED))) return E_INVALIDARG; + std::wstring strAppUserModelId (L""); + if (lpswStr) strAppUserModelId += lpswStr; + CComPtr spAppActivationManager; + HRESULT hrResult = E_INVALIDARG; + if (!strAppUserModelId.empty ()) + { + // Instantiate IApplicationActivationManager + hrResult = CoCreateInstance (CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, IID_IApplicationActivationManager, (LPVOID*)&spAppActivationManager); + if (SUCCEEDED (hrResult)) + { + // This call ensures that the app is launched as the foreground window + hrResult = CoAllowSetForegroundWindow (spAppActivationManager, NULL); + // Launch the app + if (SUCCEEDED (hrResult)) + { + hrResult = spAppActivationManager->ActivateApplication (strAppUserModelId.c_str (), NULL, AO_NONE, pdwProcessId); + } + } + } + return hrResult; +} \ No newline at end of file diff --git a/AppLauncher/AppLauncher.h b/AppLauncher/AppLauncher.h new file mode 100644 index 0000000..70c06e4 --- /dev/null +++ b/AppLauncher/AppLauncher.h @@ -0,0 +1,13 @@ +// ifdef Ǵʹ DLL 򵥵 +// ı׼ DLL еļ϶ APPLAUNCHER_EXPORTS +// űġʹô DLL +// κĿϲӦ˷šԴļаļκĿὫ +// APPLAUNCHER_API ΪǴ DLL ģ DLL ô˺궨 +// ΪDZġ +#ifdef APPLAUNCHER_EXPORTS +#define APPLAUNCHER_API __declspec(dllexport) +#else +#define APPLAUNCHER_API __declspec(dllimport) +#endif + +EXTERN_C APPLAUNCHER_API HRESULT LaunchApp (LPCWSTR strAppUserModelId, PDWORD pdwProcessId); diff --git a/AppLauncher/AppLauncher.vcxproj b/AppLauncher/AppLauncher.vcxproj new file mode 100644 index 0000000..c8dafb4 --- /dev/null +++ b/AppLauncher/AppLauncher.vcxproj @@ -0,0 +1,250 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Release + ARM + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {285130BC-CBF1-4C7A-A28D-6F5EE6C68384} + Win32Proj + AppLauncher + 8.1 + + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + false + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;APPLAUNCHER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;APPLAUNCHER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Use + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;APPLAUNCHER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;APPLAUNCHER_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + + + Windows + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;APPLAUNCHER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;APPLAUNCHER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + false + false + + + + + false + + + false + false + + + + + false + + + + + Create + Create + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/AppLauncher/AppLauncher.vcxproj.filters b/AppLauncher/AppLauncher.vcxproj.filters new file mode 100644 index 0000000..156a8e8 --- /dev/null +++ b/AppLauncher/AppLauncher.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + \ No newline at end of file diff --git a/AppLauncher/ReadMe.txt b/AppLauncher/ReadMe.txt new file mode 100644 index 0000000..ffec762 --- /dev/null +++ b/AppLauncher/ReadMe.txt @@ -0,0 +1,30 @@ +======================================================================== + 动态链接库:AppLauncher 项目概述 +======================================================================== + +应用程序向导已为您创建了此 AppLauncher DLL。 + +本文件概要介绍组成 AppLauncher 应用程序的每个文件的内容。 + + +AppLauncher.vcxproj + 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 + +AppLauncher.vcxproj.filters + 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 + +AppLauncher.cpp + 这是主 DLL 源文件。 + +///////////////////////////////////////////////////////////////////////////// +其他标准文件: + +StdAfx.h, StdAfx.cpp + 这些文件用于生成名为 AppLauncher.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 + +///////////////////////////////////////////////////////////////////////////// +其他注释: + +应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 + +///////////////////////////////////////////////////////////////////////////// diff --git a/AppLauncher/dllmain.cpp b/AppLauncher/dllmain.cpp new file mode 100644 index 0000000..260abc6 --- /dev/null +++ b/AppLauncher/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : DLL Ӧóڵ㡣 +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/AppLauncher/stdafx.cpp b/AppLauncher/stdafx.cpp new file mode 100644 index 0000000..30610d8 --- /dev/null +++ b/AppLauncher/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : ֻ׼ļԴļ +// AppLauncher.pch ΪԤͷ +// stdafx.obj ԤϢ + +#include "stdafx.h" + +// TODO: STDAFX.H κĸͷļ +//ڴļ diff --git a/AppLauncher/stdafx.h b/AppLauncher/stdafx.h new file mode 100644 index 0000000..f06cb3a --- /dev/null +++ b/AppLauncher/stdafx.h @@ -0,0 +1,25 @@ +// stdafx.h : ׼ϵͳļİļ +// Ǿʹõĵ +// ضĿİļ +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Windows ͷųʹõ +// Windows ͷļ: +#include + + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // ijЩ CString 캯ʽ + +#include +#include + +// TODO: ڴ˴óҪͷļ +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/AppLauncher/targetver.h b/AppLauncher/targetver.h new file mode 100644 index 0000000..416cebf --- /dev/null +++ b/AppLauncher/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h õ߰汾 Windows ƽ̨ + +// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h +// _WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h + +#include diff --git a/Base64Img/Base64Img.cpp b/Base64Img/Base64Img.cpp new file mode 100644 index 0000000..b368c36 --- /dev/null +++ b/Base64Img/Base64Img.cpp @@ -0,0 +1,34 @@ +// Base64Img.cpp : DLL Ӧóĵ +// + +#include "stdafx.h" +#include "Base64Img.h" + +LPSTR StreamToBase64 (HISTREAM ifile) +{ + if (!ifile) return NULL; + IStream *pStream = (IStream *)ifile; + LARGE_INTEGER liZero = {}; + pStream->Seek (liZero, STREAM_SEEK_SET, nullptr); + STATSTG statstg; + pStream->Stat (&statstg, STATFLAG_NONAME); + ULARGE_INTEGER uliSize = statstg.cbSize; + std::vector buffer (uliSize.QuadPart); + ULONG bytesRead; + pStream->Read (buffer.data (), static_cast(buffer.size ()), &bytesRead); + DWORD base64Size = 0; + if (!CryptBinaryToStringA (buffer.data (), bytesRead, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &base64Size)) + { + return NULL; + } + std::vector base64Buffer (base64Size); + if (!CryptBinaryToStringA (buffer.data (), bytesRead, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, base64Buffer.data (), &base64Size)) + { + return NULL; + } + std::string res = std::string (base64Buffer.begin (), base64Buffer.end ()); + LPSTR lpszStr = (LPSTR)calloc (res.capacity (), sizeof (char)); + if (!lpszStr) return NULL; + lstrcpyA (lpszStr, res.c_str ()); + return lpszStr; +} \ No newline at end of file diff --git a/Base64Img/Base64Img.h b/Base64Img/Base64Img.h new file mode 100644 index 0000000..fb7c3e5 --- /dev/null +++ b/Base64Img/Base64Img.h @@ -0,0 +1,16 @@ +// ifdef Ǵʹ DLL 򵥵 +// ı׼ DLL еļ϶ BASE64IMG_EXPORTS +// űġʹô DLL +// κĿϲӦ˷šԴļаļκĿὫ +// BASE64IMG_API ΪǴ DLL ģ DLL ô˺궨 +// ΪDZġ +#ifdef BASE64IMG_EXPORTS +#define BASE64IMG_API __declspec(dllexport) +#else +#define BASE64IMG_API __declspec(dllimport) +#endif + +typedef HANDLE HISTREAM; +typedef char *LPSTR; + +extern "C" BASE64IMG_API LPSTR StreamToBase64 (HISTREAM ifile); diff --git a/Base64Img/Base64Img.vcxproj b/Base64Img/Base64Img.vcxproj new file mode 100644 index 0000000..eda671e --- /dev/null +++ b/Base64Img/Base64Img.vcxproj @@ -0,0 +1,254 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Release + ARM + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {911EDC63-DB20-4D61-9420-583A1C35427F} + Win32Proj + Base64Img + 8.1 + + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + false + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;BASE64IMG_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + crypt32.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;BASE64IMG_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + crypt32.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;BASE64IMG_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;BASE64IMG_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + + + Windows + true + true + true + crypt32.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;BASE64IMG_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + crypt32.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;BASE64IMG_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + false + false + + + + + false + + + false + false + + + + + false + + + + + Create + Create + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/Base64Img/Base64Img.vcxproj.filters b/Base64Img/Base64Img.vcxproj.filters new file mode 100644 index 0000000..47ea228 --- /dev/null +++ b/Base64Img/Base64Img.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + \ No newline at end of file diff --git a/Base64Img/ReadMe.txt b/Base64Img/ReadMe.txt new file mode 100644 index 0000000..cc19490 --- /dev/null +++ b/Base64Img/ReadMe.txt @@ -0,0 +1,30 @@ +======================================================================== + 动态链接库:Base64Img 项目概述 +======================================================================== + +应用程序向导已为您创建了此 Base64Img DLL。 + +本文件概要介绍组成 Base64Img 应用程序的每个文件的内容。 + + +Base64Img.vcxproj + 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 + +Base64Img.vcxproj.filters + 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 + +Base64Img.cpp + 这是主 DLL 源文件。 + +///////////////////////////////////////////////////////////////////////////// +其他标准文件: + +StdAfx.h, StdAfx.cpp + 这些文件用于生成名为 Base64Img.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 + +///////////////////////////////////////////////////////////////////////////// +其他注释: + +应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 + +///////////////////////////////////////////////////////////////////////////// diff --git a/Base64Img/dllmain.cpp b/Base64Img/dllmain.cpp new file mode 100644 index 0000000..260abc6 --- /dev/null +++ b/Base64Img/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : DLL Ӧóڵ㡣 +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/Base64Img/stdafx.cpp b/Base64Img/stdafx.cpp new file mode 100644 index 0000000..bc09187 --- /dev/null +++ b/Base64Img/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : ֻ׼ļԴļ +// Base64Img.pch ΪԤͷ +// stdafx.obj ԤϢ + +#include "stdafx.h" + +// TODO: STDAFX.H κĸͷļ +//ڴļ diff --git a/Base64Img/stdafx.h b/Base64Img/stdafx.h new file mode 100644 index 0000000..32c80bd --- /dev/null +++ b/Base64Img/stdafx.h @@ -0,0 +1,28 @@ +// stdafx.h : ׼ϵͳļİļ +// Ǿʹõĵ +// ضĿİļ +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Windows ͷųʹõ +// Windows ͷļ: +#include + + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // ijЩ CString 캯ʽ + +#include +#include + +// TODO: ڴ˴óҪͷļ +#include +#include +#include +#include +#include +#include +#include +using namespace std; \ No newline at end of file diff --git a/Base64Img/targetver.h b/Base64Img/targetver.h new file mode 100644 index 0000000..416cebf --- /dev/null +++ b/Base64Img/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h õ߰汾 Windows ƽ̨ + +// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h +// _WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h + +#include diff --git a/CertificateManager/CertificateManager.cpp b/CertificateManager/CertificateManager.cpp new file mode 100644 index 0000000..6cdfe01 --- /dev/null +++ b/CertificateManager/CertificateManager.cpp @@ -0,0 +1,629 @@ +// CertificateManager.cpp : DLL Ӧóĵ +// + +#include "stdafx.h" +#include "CertificateManager.h" +#define _ELDER +#ifdef _ELDER + +bool LoadCertFromCertFile (LPCWSTR lpCertFile) +{ + LPCWSTR storeNameROOT = L"Root"; + LPCWSTR storeNamePublisher = L"TrustedPublisher"; // TrustedPublisher + // ROOT 洢 + HCERTSTORE hCertStore = CertOpenStore ( + CERT_STORE_PROV_SYSTEM, + 0, + NULL, + CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, + storeNameROOT + ); + if (!hCertStore) + { + OutputDebugStringW (L"Failed to open certificate store! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + return false; + } + HCERTSTORE hFileCertStore = NULL; + PCCERT_CONTEXT pCertContext = NULL; + // ʹ CryptQueryObject Զ֤ʽ + if (!CryptQueryObject ( + CERT_QUERY_OBJECT_FILE, // ֤ļ + lpCertFile, + CERT_QUERY_CONTENT_FLAG_CERT | // X.509 ֤ + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,// PKCS7 ʽ + CERT_QUERY_FORMAT_FLAG_ALL, // иʽ + 0, + NULL, NULL, NULL, + &hFileCertStore, // ֤洢 + NULL, // CRL PKCS7 ǩϢ + NULL + )) + { + OutputDebugStringW (L"Failed to detect certificate format! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertCloseStore (hCertStore, 0); + return false; + } + // ȡ֤ + pCertContext = CertEnumCertificatesInStore (hFileCertStore, NULL); + if (!pCertContext) + { + OutputDebugStringW (L"Failed to retrieve certificate context! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertCloseStore (hFileCertStore, 0); + CertCloseStore (hCertStore, 0); + return false; + } + // ֤ӵ ROOT 洢 + if (!CertAddCertificateContextToStore (hCertStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) + { + OutputDebugStringW (L"Failed to add certificate to ROOT store! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hFileCertStore, 0); + CertCloseStore (hCertStore, 0); + return false; + } + // 뵽 TrustedPublisher 洢 + HCERTSTORE hPublisherStore = CertOpenStore ( + CERT_STORE_PROV_SYSTEM, + 0, + NULL, + CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, + storeNamePublisher + ); + if (!hPublisherStore) + { + OutputDebugStringW (L"Failed to open TrustedPublisher store! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hFileCertStore, 0); + CertCloseStore (hCertStore, 0); + return false; + } + if (!CertAddCertificateContextToStore (hPublisherStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) + { + OutputDebugStringW (L"Failed to add certificate to TrustedPublisher store! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hFileCertStore, 0); + CertCloseStore (hCertStore, 0); + CertCloseStore (hPublisherStore, 0); + return false; + } + CertFreeCertificateContext (pCertContext); + CertCloseStore (hFileCertStore, 0); + CertCloseStore (hCertStore, 0); + CertCloseStore (hPublisherStore, 0); + return true; +} +bool LoadCertFromSignedFile (LPCWSTR lpSignedFile) +{ + LPCWSTR storeNameROOT = L"Root"; + LPCWSTR storeNamePublisher = L"TrustedPublisher"; // TrustedPublisher + HCERTSTORE hStore = NULL; + PCCERT_CONTEXT pCertContext = NULL; + // ǩļȡ֤洢 + if (!CryptQueryObject ( + CERT_QUERY_OBJECT_FILE, lpSignedFile, + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, + CERT_QUERY_FORMAT_FLAG_BINARY, 0, + NULL, NULL, NULL, &hStore, NULL, NULL + )) + { + OutputDebugStringW (L"Failed to query signed file! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + return false; + } + pCertContext = CertEnumCertificatesInStore (hStore, NULL); + if (!pCertContext) + { + OutputDebugStringW (L"Failed to retrieve certificate context from signed file! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertCloseStore (hStore, 0); + return false; + } + // Ŀ洢 + HCERTSTORE hTargetStore = CertOpenStore ( + CERT_STORE_PROV_SYSTEM, + 0, + NULL, + CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, + storeNameROOT + ); + if (!hTargetStore) + { + OutputDebugStringW (L"Failed to open target store (ROOT)! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, 0); + return false; + } + // ֤鵽 ROOT 洢 + if (!CertAddCertificateContextToStore (hTargetStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) + { + OutputDebugStringW (L"Failed to add certificate to ROOT store from signed file! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, 0); + CertCloseStore (hTargetStore, 0); + return false; + } + // 뵽 TrustedPublisher 洢 + HCERTSTORE hPublisherStore = CertOpenStore ( + CERT_STORE_PROV_SYSTEM, + 0, + NULL, + CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, + storeNamePublisher + ); + if (!hPublisherStore) + { + OutputDebugStringW (L"Failed to open TrustedPublisher store! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, 0); + CertCloseStore (hTargetStore, 0); + return false; + } + if (!CertAddCertificateContextToStore (hPublisherStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) + { + OutputDebugStringW (L"Failed to add certificate to TrustedPublisher store from signed file! Error: "); + OutputDebugStringW (std::to_wstring (GetLastError ()).c_str ()); + OutputDebugStringW (L"\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, 0); + CertCloseStore (hTargetStore, 0); + CertCloseStore (hPublisherStore, 0); + return false; + } + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, 0); + CertCloseStore (hTargetStore, 0); + CertCloseStore (hPublisherStore, 0); + return true; +} +/* +bool IsCertAlreadyInStore (HCERTSTORE hStore, PCCERT_CONTEXT pCertContext) +{ + PCCERT_CONTEXT pExistingCert = NULL; + pExistingCert = CertFindCertificateInStore (hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext, NULL); + if (pExistingCert) + { + CertFreeCertificateContext (pExistingCert); + return true; + } + return false; +} +bool LoadCertFromCertFile (LPCWSTR lpCertFile) +{ + OutputDebugString (L"LoadCertFromCertFile: Starting to load certificate from file.\n"); + HCERTSTORE hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, L"ROOT"); + if (!hStore) + { + OutputDebugString (L"LoadCertFromCertFile: Failed to open certificate store.\n"); + return false; + } + HANDLE hFile = CreateFile (lpCertFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + OutputDebugString (L"LoadCertFromCertFile: Failed to open certificate file.\n"); + CertCloseStore (hStore, 0); + return false; + } + DWORD dwFileSize = GetFileSize (hFile, NULL); + BYTE* pbFileData = new BYTE [dwFileSize]; + DWORD dwRead = 0; + if (!ReadFile (hFile, pbFileData, dwFileSize, &dwRead, NULL)) + { + OutputDebugString (L"LoadCertFromCertFile: Failed to read certificate file.\n"); + CloseHandle (hFile); + delete [] pbFileData; + CertCloseStore (hStore, 0); + return false; + } + CloseHandle (hFile); + PCCERT_CONTEXT pCertContext = CertCreateCertificateContext (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pbFileData, dwFileSize); + delete [] pbFileData; + if (!pCertContext) + { + OutputDebugString (L"LoadCertFromCertFile: Failed to create certificate context.\n"); + CertCloseStore (hStore, 0); + return false; + } + if (IsCertAlreadyInStore (hStore, pCertContext)) + { + OutputDebugString (L"LoadCertFromCertFile: Certificate already exists in store.\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, 0); + return true; + } + if (!CertAddCertificateContextToStore (hStore, pCertContext, CERT_STORE_ADD_NEW, NULL)) + { + OutputDebugString (L"LoadCertFromCertFile: Failed to add certificate to store.\n"); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, 0); + return false; + } + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, 0); + OutputDebugString (L"LoadCertFromCertFile: Successfully loaded certificate from file.\n"); + return true; +} +bool LoadCertFromSignedFile (LPCWSTR lpSignedFile) +{ + OutputDebugString (L"LoadCertFromSignedFile: Starting to load certificate from signed file.\n"); + HCERTSTORE hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, NULL, + CERT_SYSTEM_STORE_CURRENT_USER | CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_MAXIMUM_ALLOWED_FLAG, + L"ROOT"); + if (!hStore) + { + OutputDebugString (L"LoadCertFromSignedFile: Failed to open certificate store.\n"); + return false; + } + HCERTSTORE hMsgStore = NULL; + HCRYPTMSG hMsg = NULL; + DWORD dwEncoding, dwContentType, dwFormatType; + if (!CryptQueryObject (CERT_QUERY_OBJECT_FILE, lpSignedFile, + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, + CERT_QUERY_FORMAT_FLAG_BINARY, 0, + &dwEncoding, &dwContentType, &dwFormatType, + &hMsgStore, &hMsg, NULL)) + { + DWORD dwError = GetLastError (); + WCHAR errorMsg [256]; + wsprintf (errorMsg, L"LoadCertFromSignedFile: CryptQueryObject failed. Error: %lu\n", dwError); + OutputDebugString (errorMsg); + CertCloseStore (hStore, 0); + return false; + } + PCCERT_CONTEXT pCertContext = NULL; + while ((pCertContext = CertFindCertificateInStore (hMsgStore, + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + 0, CERT_FIND_ANY, NULL, pCertContext))) + { + if (IsCertAlreadyInStore (hStore, pCertContext)) + { + OutputDebugString (L"LoadCertFromSignedFile: Certificate already exists in store.\n"); + continue; + } + // 滻֤ + if (!CertAddCertificateContextToStore (hStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) + { + DWORD dwError = GetLastError (); + WCHAR errorMsg [256]; + wsprintf (errorMsg, L"LoadCertFromSignedFile: Failed to add certificate to store. Error: %lu\n", dwError); + OutputDebugString (errorMsg); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hMsgStore, 0); + CertCloseStore (hStore, 0); + return false; + } + } + CertCloseStore (hMsgStore, 0); + CertCloseStore (hStore, 0); + OutputDebugString (L"LoadCertFromSignedFile: Successfully loaded certificate from signed file.\n"); + return true; +} +*/ +#else +std::wstring certmgrPath = L""; +extern "C" bool IsFileExistsW (LPCWSTR filename) +{ + DWORD dwAttrib = GetFileAttributesW (filename); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +} +extern "C" bool IsFileExistsA (LPCSTR filename) +{ + DWORD dwAttrib = GetFileAttributesA (filename); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +} +bool IsFileExists (LPWSTR filePath) { return IsFileExistsW (filePath); } +bool IsFileExists (LPCSTR filePath) { return IsFileExistsA (filePath); } +bool IsFileExists (std::string filePath) { return IsFileExistsA (filePath.c_str ()); } +bool IsFileExists (std::wstring filePath) { return IsFileExistsW (filePath.c_str ()); } +std::string GetProgramRootDirectoryA () +{ + char path [MAX_PATH]; + if (GetModuleFileNameA (NULL, path, MAX_PATH)) + { + std::string dir (path); + size_t pos = dir.find_last_of ("\\/"); + if (pos != std::string::npos) + { + dir = dir.substr (0, pos); + } + return dir; + } + return ""; +} +std::wstring GetProgramRootDirectoryW () +{ + wchar_t path [MAX_PATH]; + if (GetModuleFileNameW (NULL, path, MAX_PATH)) + { + std::wstring dir (path); + size_t pos = dir.find_last_of (L"\\/"); + if (pos != std::wstring::npos) + { + dir = dir.substr (0, pos); + } + return dir; + } + return L""; +} +std::string EnsureTrailingSlash (const std::string &path) +{ + if (path.empty ()) return path; // ·ֱӷ + + char lastChar = path.back (); + if (lastChar == '\\' || lastChar == '/') + return path; // зֱָӷ + // ϵͳԭ·ʽʵķָ + char separator = (path.find ('/') != std::string::npos) ? '/' : '\\'; + return path + separator; +} +std::wstring EnsureTrailingSlash (const std::wstring &path) +{ + if (path.empty ()) return path; + + wchar_t lastChar = path.back (); + if (lastChar == L'\\' || lastChar == L'/') + return path; + + wchar_t separator = (path.find (L'/') != std::wstring::npos) ? L'/' : L'\\'; + return path + separator; +} +bool IsDirectoryExistsA (LPCSTR path) +{ + DWORD attributes = GetFileAttributesA (path); + return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY)); +} +bool IsDirectoryExistsW (LPCWSTR path) +{ + DWORD attributes = GetFileAttributesW (path); + return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY)); +} +bool IsDirectoryExists (const std::string path) { return IsDirectoryExistsA (path.c_str ()); } +bool IsDirectoryExists (const std::wstring path) { return IsDirectoryExistsW (path.c_str ()); } +bool IsDirectoryExists (LPCSTR path) { return IsDirectoryExistsA (path); } +bool IsDirectoryExists (LPCWSTR path) { return IsDirectoryExistsW (path); } +bool InitCertMgrProgramPath () +{ + if (IsFileExists (certmgrPath)) return true; // ظʼ + std::wstring rootpath = EnsureTrailingSlash (EnsureTrailingSlash (GetProgramRootDirectoryW ()) + L"Tools"); + if (!IsDirectoryExists (rootpath)) rootpath = L"Tools"; + if (!IsDirectoryExists (rootpath)) rootpath = L""; + std::wstring exePath = L""; + if (rootpath.length () > 0) exePath = EnsureTrailingSlash (rootpath) + L"Certmgr.exe"; + else exePath = L"Certmgr"; + certmgrPath = exePath; + return (IsFileExists (certmgrPath)); +} +bool ExecProgramW (LPCWSTR lpApplicationName, LPCWSTR lpCommandLine, bool bWait, DWORD nShowCmd, const BYTE *lpStdInput, std::wstring &stdOutput, std::wstring &stdError) +{ + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof (SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + HANDLE hStdOutRead, hStdOutWrite; + HANDLE hStdErrRead, hStdErrWrite; + HANDLE hStdInRead = NULL, hStdInWrite = NULL; + // ׼ܵ + if (!CreatePipe (&hStdOutRead, &hStdOutWrite, &sa, 0)) + { + OutputDebugString (L"ExecProgramW: Failed to create stdout pipe\n"); + return false; + } + SetHandleInformation (hStdOutRead, HANDLE_FLAG_INHERIT, 0); + // ׼ܵ + if (!CreatePipe (&hStdErrRead, &hStdErrWrite, &sa, 0)) + { + OutputDebugString (L"ExecProgramW: Failed to create stderr pipe\n"); + CloseHandle (hStdOutRead); + CloseHandle (hStdOutWrite); + return false; + } + SetHandleInformation (hStdErrRead, HANDLE_FLAG_INHERIT, 0); + // ׼ܵݣ + if (lpStdInput) + { + if (!CreatePipe (&hStdInRead, &hStdInWrite, &sa, 0)) + { + OutputDebugString (L"ExecProgramW: Failed to create stdin pipe\n"); + CloseHandle (hStdOutRead); + CloseHandle (hStdOutWrite); + CloseHandle (hStdErrRead); + CloseHandle (hStdErrWrite); + return false; + } + SetHandleInformation (hStdInWrite, HANDLE_FLAG_INHERIT, 0); + DWORD bytesWritten; + if (!WriteFile (hStdInWrite, lpStdInput, lstrlenA ((LPCSTR)lpStdInput), &bytesWritten, NULL)) + { + OutputDebugString (L"ExecProgramW: Failed to write to stdin pipe\n"); + CloseHandle (hStdInRead); + CloseHandle (hStdInWrite); + CloseHandle (hStdOutRead); + CloseHandle (hStdOutWrite); + CloseHandle (hStdErrRead); + CloseHandle (hStdErrWrite); + return false; + } + CloseHandle (hStdInWrite); // رд + } + STARTUPINFO si = {0}; + PROCESS_INFORMATION pi = {0}; + si.cb = sizeof (STARTUPINFO); + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + si.wShowWindow = static_cast(nShowCmd); + si.hStdOutput = hStdOutWrite; + si.hStdError = hStdErrWrite; + si.hStdInput = hStdInRead ? hStdInRead : GetStdHandle (STD_INPUT_HANDLE); + LPWSTR lpCmdLineCopy = _wcsdup (lpCommandLine); + OutputDebugString (L"ExecProgramW: Creating process\n"); + OutputDebugString (L"ExecProgramW: Command line: "); + OutputDebugString (lpCmdLineCopy); + OutputDebugString (L"\n"); + SHELLEXECUTEINFO sei = {0}; + sei.cbSize = sizeof (SHELLEXECUTEINFO); + sei.fMask = SEE_MASK_NOCLOSEPROCESS; + sei.hwnd = NULL; + sei.lpVerb = L"runas"; // Ȩ + sei.lpFile = lpApplicationName; + sei.lpParameters = lpCmdLineCopy; + sei.lpDirectory = NULL; + sei.nShow = nShowCmd; + sei.hInstApp = NULL; + if (!ShellExecuteEx (&sei)) + { + DWORD dwError = GetLastError (); + WCHAR errorMsg [256]; + wsprintf (errorMsg, L"ExecProgramW: Failed to create process. Error: %lu\n", dwError); + OutputDebugString (errorMsg); + free (lpCmdLineCopy); + CloseHandle (hStdOutRead); + CloseHandle (hStdOutWrite); + CloseHandle (hStdErrRead); + CloseHandle (hStdErrWrite); + if (hStdInRead) CloseHandle (hStdInRead); + return false; + } + free (lpCmdLineCopy); + CloseHandle (hStdOutWrite); + CloseHandle (hStdErrWrite); + if (hStdInRead) CloseHandle (hStdInRead); + // ȡ׼ + DWORD bytesRead; + char buffer [4096]; + OutputDebugString (L"ExecProgramW: Reading stdout\n"); + while (ReadFile (hStdOutRead, buffer, sizeof (buffer) - 1, &bytesRead, NULL) && bytesRead > 0) + { + buffer [bytesRead] = 0; + int wlen = MultiByteToWideChar (CP_UTF8, 0, buffer, -1, NULL, 0); + std::vector wbuffer (wlen); + MultiByteToWideChar (CP_UTF8, 0, buffer, -1, wbuffer.data (), wlen); + stdOutput += wbuffer.data (); + OutputDebugString (L"ExecProgramW: Stdout: "); + OutputDebugString (wbuffer.data ()); + OutputDebugString (L"\n"); + } + CloseHandle (hStdOutRead); + // ȡ׼ + OutputDebugString (L"ExecProgramW: Reading stderr\n"); + while (ReadFile (hStdErrRead, buffer, sizeof (buffer) - 1, &bytesRead, NULL) && bytesRead > 0) + { + buffer [bytesRead] = 0; + int wlen = MultiByteToWideChar (CP_UTF8, 0, buffer, -1, NULL, 0); + std::vector wbuffer (wlen); + MultiByteToWideChar (CP_UTF8, 0, buffer, -1, wbuffer.data (), wlen); + stdError += wbuffer.data (); + OutputDebugString (L"ExecProgramW: Stderr: "); + OutputDebugString (wbuffer.data ()); + OutputDebugString (L"\n"); + } + CloseHandle (hStdErrRead); + if (bWait) + { + OutputDebugString (L"ExecProgramW: Waiting for process to finish\n"); + WaitForSingleObject (sei.hProcess, INFINITE); + } + CloseHandle (sei.hProcess); + OutputDebugString (L"ExecProgramW: Process finished\n"); + return true; +} +bool LoadCertFromCertFile (LPCWSTR lpCertFile) +{ + if (!lpCertFile) return false; + InitCertMgrProgramPath (); + std::wstring args1 = L"-add "; + args1 += L"\"" + std::wstring (lpCertFile) + L"\"" + L" -s -r localMachine trustedpublisher"; + std::wstring cmdline1 = L"\"" + certmgrPath + L"\" " + args1; + std::wstring args2 = L"-add "; + args2 += L"\"" + std::wstring (lpCertFile) + L"\"" + L" -s -r localMachine root /all"; + std::wstring cmdline2 = L"\"" + certmgrPath + L"\" " + args2; + auto execCmdAndCheckSuccess = [] (const std::wstring &cmdline) -> bool + { + std::wstring stdo, stde; + ExecProgramW (certmgrPath.c_str (), cmdline.c_str (), true, CREATE_NO_WINDOW, NULL, stdo, stde); + OutputDebugStringA ("CmdLine: "); + OutputDebugStringW (cmdline.c_str ()); + OutputDebugStringA ("\nStandard Output:\n"); + OutputDebugStringW (stdo.c_str ()); + OutputDebugStringA ("\nStandard Error:\n"); + OutputDebugStringW (stde.c_str ()); + bool success = stdo.find (L"Succeeded") != std::wstring::npos; + return success; + }; + bool res = execCmdAndCheckSuccess (cmdline1); + return execCmdAndCheckSuccess (cmdline2) && res; +} + +bool LoadCertFromSignedFile (LPCWSTR lpSignedFile) +{ + if (!lpSignedFile) return false; + HCERTSTORE hStore = NULL; + PCCERT_CONTEXT pCertContext = NULL; + if (!CryptQueryObject ( + CERT_QUERY_OBJECT_FILE, lpSignedFile, + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, + CERT_QUERY_FORMAT_FLAG_BINARY, 0, + NULL, NULL, NULL, &hStore, NULL, NULL)) + { + return false; + } + pCertContext = CertEnumCertificatesInStore (hStore, NULL); + if (!pCertContext) + { + CertCloseStore (hStore, CERT_CLOSE_STORE_FORCE_FLAG); + return false; + } + wchar_t tempPath [MAX_PATH]; + if (GetTempPath (MAX_PATH, tempPath) == 0) + { + return false; + } + WCHAR tempCertFilePath [MAX_PATH]; + if (GetTempFileNameW (tempPath, L"cert", 0, tempCertFilePath) == 0) + { + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, CERT_CLOSE_STORE_FORCE_FLAG); + return false; + } + std::wstring tempFileOStr = tempCertFilePath; tempFileOStr += L".cer"; + HANDLE hTempFile = CreateFileW (tempFileOStr.c_str (), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); + if (hTempFile == INVALID_HANDLE_VALUE) + { + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, CERT_CLOSE_STORE_FORCE_FLAG); + return false; // Failed to create temp file + } + DWORD writtenBytes = 0; + if (!WriteFile (hTempFile, pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, &writtenBytes, NULL)) + { + CloseHandle (hTempFile); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, CERT_CLOSE_STORE_FORCE_FLAG); + DeleteFileW (tempFileOStr.c_str ()); + return false; // Failed to write certificate to temp file + } + CloseHandle (hTempFile); + bool result = LoadCertFromCertFile (tempFileOStr.c_str ()); + DeleteFileW (tempFileOStr.c_str ()); + CertFreeCertificateContext (pCertContext); + CertCloseStore (hStore, CERT_CLOSE_STORE_FORCE_FLAG); + return result; +} +#endif diff --git a/CertificateManager/CertificateManager.h b/CertificateManager/CertificateManager.h new file mode 100644 index 0000000..715361f --- /dev/null +++ b/CertificateManager/CertificateManager.h @@ -0,0 +1,18 @@ +// ifdef Ǵʹ DLL 򵥵 +// ı׼ DLL еļ϶ CERTIFICATEMANAGER_EXPORTS +// űġʹô DLL +// κĿϲӦ˷šԴļаļκĿὫ +// CERTIFICATEMANAGER_API ΪǴ DLL ģ DLL ô˺궨 +// ΪDZġ +#ifdef CERTIFICATEMANAGER_EXPORTS +#define CERTIFICATEMANAGER_API __declspec(dllexport) +#else +#define CERTIFICATEMANAGER_API __declspec(dllimport) +#endif + +#define func_certmgr CERTIFICATEMANAGER_API +#define func_c_certmgr extern "C" CERTIFICATEMANAGER_API + +func_c_certmgr bool LoadCertFromCertFile (LPCWSTR lpCertFile); + +func_c_certmgr bool LoadCertFromSignedFile (LPCWSTR lpSignedFile); diff --git a/CertificateManager/CertificateManager.vcxproj b/CertificateManager/CertificateManager.vcxproj new file mode 100644 index 0000000..53ba4c1 --- /dev/null +++ b/CertificateManager/CertificateManager.vcxproj @@ -0,0 +1,253 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Release + ARM + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {22702832-C3FD-48E5-BC7D-3879CA50A2ED} + Win32Proj + CertificateManager + 8.1 + + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + false + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;CERTIFICATEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + crypt32.lib;wintrust.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;CERTIFICATEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + crypt32.lib;wintrust.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;CERTIFICATEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;CERTIFICATEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + + + Windows + true + true + true + crypt32.lib;wintrust.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;CERTIFICATEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;CERTIFICATEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + false + false + + + + + false + + + false + false + + + + + false + + + + + Create + Create + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/CertificateManager/CertificateManager.vcxproj.filters b/CertificateManager/CertificateManager.vcxproj.filters new file mode 100644 index 0000000..52e7ba1 --- /dev/null +++ b/CertificateManager/CertificateManager.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + \ No newline at end of file diff --git a/CertificateManager/ReadMe.txt b/CertificateManager/ReadMe.txt new file mode 100644 index 0000000..dec912d --- /dev/null +++ b/CertificateManager/ReadMe.txt @@ -0,0 +1,30 @@ +======================================================================== + 动态链接库:CertificateManager 项目概述 +======================================================================== + +应用程序向导已为您创建了此 CertificateManager DLL。 + +本文件概要介绍组成 CertificateManager 应用程序的每个文件的内容。 + + +CertificateManager.vcxproj + 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 + +CertificateManager.vcxproj.filters + 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 + +CertificateManager.cpp + 这是主 DLL 源文件。 + +///////////////////////////////////////////////////////////////////////////// +其他标准文件: + +StdAfx.h, StdAfx.cpp + 这些文件用于生成名为 CertificateManager.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 + +///////////////////////////////////////////////////////////////////////////// +其他注释: + +应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 + +///////////////////////////////////////////////////////////////////////////// diff --git a/CertificateManager/dllmain.cpp b/CertificateManager/dllmain.cpp new file mode 100644 index 0000000..260abc6 --- /dev/null +++ b/CertificateManager/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : DLL Ӧóڵ㡣 +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/CertificateManager/stdafx.cpp b/CertificateManager/stdafx.cpp new file mode 100644 index 0000000..bb8fa7c --- /dev/null +++ b/CertificateManager/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : ֻ׼ļԴļ +// CertificateManager.pch ΪԤͷ +// stdafx.obj ԤϢ + +#include "stdafx.h" + +// TODO: STDAFX.H κĸͷļ +//ڴļ diff --git a/CertificateManager/stdafx.h b/CertificateManager/stdafx.h new file mode 100644 index 0000000..5854de1 --- /dev/null +++ b/CertificateManager/stdafx.h @@ -0,0 +1,21 @@ +// stdafx.h : ׼ϵͳļİļ +// Ǿʹõĵ +// ضĿİļ +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Windows ͷųʹõ +// Windows ͷļ: +#include + + + +// TODO: ڴ˴óҪͷļ +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/CertificateManager/targetver.h b/CertificateManager/targetver.h new file mode 100644 index 0000000..416cebf --- /dev/null +++ b/CertificateManager/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h õ߰汾 Windows ƽ̨ + +// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h +// _WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h + +#include diff --git a/PackageAdd/PackageAdd.csproj b/PackageAdd/PackageAdd.csproj new file mode 100644 index 0000000..3b9b76f --- /dev/null +++ b/PackageAdd/PackageAdd.csproj @@ -0,0 +1,58 @@ + + + + + Debug + AnyCPU + {D3DC0F1B-6BEC-4417-AB5F-59686F2F5ED3} + Library + Properties + PackageAdd + PackageAdd + v4.5 + 8.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PackageAdd/PackageInstaller.cs b/PackageAdd/PackageInstaller.cs new file mode 100644 index 0000000..e0807ad --- /dev/null +++ b/PackageAdd/PackageInstaller.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Foundation; +using Windows.Management.Deployment; +using System.Runtime.InteropServices; +using System.Threading; + +namespace PackageAdd +{ + public enum AsyncStatus + { + Started, + Completed, + Canceled, + Error + } + public delegate void PACKAGE_ADD_CALLBACK (int progress); + public static class PackageInstaller + { + public static AsyncStatus AddPackageFromFile([MarshalAs(UnmanagedType.LPWStr)] string swFilePath, IntPtr callbackPtr) + { + if (string.IsNullOrEmpty(swFilePath)) + { + return AsyncStatus.Error; + } + try + { + Uri packageUri = new Uri(swFilePath); + PackageManager packageManager = new PackageManager(); + IAsyncOperationWithProgress deploymentOperation = packageManager.AddPackageAsync(packageUri, null, DeploymentOptions.None); + // 获取 C++ 传入的回调函数 + PACKAGE_ADD_CALLBACK callback = (PACKAGE_ADD_CALLBACK)Marshal.GetDelegateForFunctionPointer(callbackPtr, typeof(PACKAGE_ADD_CALLBACK)); + ManualResetEvent opCompletedEvent = new ManualResetEvent(false); + deploymentOperation.Progress = (depProgress, progress) => + { + callback?.Invoke((int)progress.percentage); + }; + deploymentOperation.Completed = (depProgress, status) => + { + opCompletedEvent.Set(); + }; + //Console.WriteLine($"Installing package {swFilePath}"); + opCompletedEvent.WaitOne(); + if (deploymentOperation.Status == Windows.Foundation.AsyncStatus.Error) + { + return AsyncStatus.Error; + } + else if (deploymentOperation.Status == Windows.Foundation.AsyncStatus.Canceled) + { + return AsyncStatus.Canceled; + } + else if (deploymentOperation.Status == Windows.Foundation.AsyncStatus.Completed) + { + return AsyncStatus.Completed; + } + else + { + return AsyncStatus.Error; + } + } + catch (Exception) + { + return AsyncStatus.Error; + } + } + } +} diff --git a/PackageAdd/Properties/AssemblyInfo.cs b/PackageAdd/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b8715a7 --- /dev/null +++ b/PackageAdd/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("PackageAdd")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PackageAdd")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +//将 ComVisible 设置为 false 将使此程序集中的类型 +//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("d3dc0f1b-6bec-4417-ab5f-59686f2f5ed3")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/PackageManager/PackageManager.cpp b/PackageManager/PackageManager.cpp new file mode 100644 index 0000000..2801f9c --- /dev/null +++ b/PackageManager/PackageManager.cpp @@ -0,0 +1,82 @@ +// PackageManager.cpp : DLL Ӧóĵ +// + +#include "stdafx.h" +#include "PackageManager.h" + + +std::wstring lastErrorCode (L""); +std::wstring lastErrorDetailText (L""); + +[MTAThread] +EXTERN_C PACKAGEMANAGER_API InstallStatus AddPackageFromPath (LPCWSTR lpswPath, PACKAGE_ADD_PROGRESS callbProgress) +{ + lastErrorCode = L""; + lastErrorDetailText = L""; + HANDLE completedEvent = nullptr; + try + { + completedEvent = CreateEventEx (nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); + if (!completedEvent) return InstallStatus::Error; + String ^inputPackageUri = ref new String (lpswPath); + auto packageUri = ref new Uri (inputPackageUri); + auto packageManager = ref new PackageManager (); + auto deploymentOperation = packageManager->AddPackageAsync (packageUri, nullptr, DeploymentOptions::None); + deploymentOperation->Progress = + ref new AsyncOperationProgressHandler ( + [callbProgress] (IAsyncOperationWithProgress^ operation, DeploymentProgress progress) + { + if (callbProgress) + callbProgress (progress.percentage); + }); + deploymentOperation->Completed = + ref new AsyncOperationWithProgressCompletedHandler ( + [&completedEvent] (IAsyncOperationWithProgress^ operation, AsyncStatus) + { + SetEvent (completedEvent); + }); + WaitForSingleObject (completedEvent, INFINITE); + if (!completedEvent) + { + CloseHandle (completedEvent); completedEvent = nullptr; + } + if (deploymentOperation->Status == AsyncStatus::Error) + { + auto deploymentResult = deploymentOperation->GetResults (); + lastErrorCode += deploymentOperation->ErrorCode.Value; + lastErrorDetailText += deploymentResult->ErrorText->Data (); + return InstallStatus::Error; + } + else if (deploymentOperation->Status == AsyncStatus::Canceled) + { + lastErrorDetailText += L"Installation Canceled"; + return InstallStatus::Canceled; + } + else if (deploymentOperation->Status == AsyncStatus::Completed) + { + return InstallStatus::Success; + } + } + catch (Exception ^ex) + { + lastErrorDetailText += ex->ToString ()->Data (); + return InstallStatus::Error; + } + if (!completedEvent) + { + CloseHandle (completedEvent); completedEvent = nullptr; + } + return InstallStatus::Canceled; +} + +EXTERN_C PACKAGEMANAGER_API LPCWSTR GetLastErrorCode () +{ + if (lastErrorCode.length () == 0) return NULL; + else return lastErrorCode.c_str (); +} + +EXTERN_C PACKAGEMANAGER_API LPCWSTR GetLastErrorDetailText () +{ + if (lastErrorDetailText.length () == 0) return NULL; + else return lastErrorDetailText.c_str (); +} \ No newline at end of file diff --git a/PackageManager/PackageManager.h b/PackageManager/PackageManager.h new file mode 100644 index 0000000..fde9b2d --- /dev/null +++ b/PackageManager/PackageManager.h @@ -0,0 +1,38 @@ +// ifdef Ǵʹ DLL 򵥵 +// ı׼ DLL еļ϶ PACKAGEMANAGER_EXPORTS +// űġʹô DLL +// κĿϲӦ˷šԴļаļκĿὫ +// PACKAGEMANAGER_API ΪǴ DLL ģ DLL ô˺궨 +// ΪDZġ +#ifdef PACKAGEMANAGER_EXPORTS +#define PACKAGEMANAGER_API __declspec(dllexport) +#else +#define PACKAGEMANAGER_API __declspec(dllimport) +#endif + +// Ǵ PackageManager.dll +class PACKAGEMANAGER_API CPackageManager { +public: + CPackageManager(void); + // TODO: ڴķ +}; + +extern PACKAGEMANAGER_API int nPackageManager; + +PACKAGEMANAGER_API int fnPackageManager(void); + +typedef void (*_PACKAGE_ADD_PROGRESS)(unsigned progress); +typedef _PACKAGE_ADD_PROGRESS PACKAGE_ADD_PROGRESS; + +enum class InstallStatus +{ + Success, + Error, + Canceled +}; + +EXTERN_C PACKAGEMANAGER_API InstallStatus AddPackageFromPath (LPCWSTR lpswPath, PACKAGE_ADD_PROGRESS callbProgress); + +EXTERN_C PACKAGEMANAGER_API LPCWSTR GetLastErrorCode (); + +EXTERN_C PACKAGEMANAGER_API LPCWSTR GetLastErrorDetailText (); \ No newline at end of file diff --git a/PackageManager/PackageManager.vcxproj b/PackageManager/PackageManager.vcxproj new file mode 100644 index 0000000..c6bf6b4 --- /dev/null +++ b/PackageManager/PackageManager.vcxproj @@ -0,0 +1,182 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {912FA351-8B8C-4B54-A7FE-7B3ECF9EBC05} + Win32Proj + PackageManager + 8.1 + + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;PACKAGEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + true + ProgramDatabase + false + + + Windows + true + + + + + Use + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;PACKAGEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;PACKAGEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + true + + + Windows + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;PACKAGEMANAGER_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + false + + + false + + + false + + + false + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/PackageManager/PackageManager.vcxproj.filters b/PackageManager/PackageManager.vcxproj.filters new file mode 100644 index 0000000..c93e938 --- /dev/null +++ b/PackageManager/PackageManager.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + \ No newline at end of file diff --git a/PackageManager/ReadMe.txt b/PackageManager/ReadMe.txt new file mode 100644 index 0000000..e7c9063 --- /dev/null +++ b/PackageManager/ReadMe.txt @@ -0,0 +1,30 @@ +======================================================================== + 动态链接库:PackageManager 项目概述 +======================================================================== + +应用程序向导已为您创建了此 PackageManager DLL。 + +本文件概要介绍组成 PackageManager 应用程序的每个文件的内容。 + + +PackageManager.vcxproj + 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 + +PackageManager.vcxproj.filters + 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 + +PackageManager.cpp + 这是主 DLL 源文件。 + +///////////////////////////////////////////////////////////////////////////// +其他标准文件: + +StdAfx.h, StdAfx.cpp + 这些文件用于生成名为 PackageManager.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 + +///////////////////////////////////////////////////////////////////////////// +其他注释: + +应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 + +///////////////////////////////////////////////////////////////////////////// diff --git a/PackageManager/dllmain.cpp b/PackageManager/dllmain.cpp new file mode 100644 index 0000000..260abc6 --- /dev/null +++ b/PackageManager/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : DLL Ӧóڵ㡣 +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/PackageManager/stdafx.cpp b/PackageManager/stdafx.cpp new file mode 100644 index 0000000..c5ef2e7 --- /dev/null +++ b/PackageManager/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : ֻ׼ļԴļ +// PackageManager.pch ΪԤͷ +// stdafx.obj ԤϢ + +#include "stdafx.h" + +// TODO: STDAFX.H κĸͷļ +//ڴļ diff --git a/PackageManager/stdafx.h b/PackageManager/stdafx.h new file mode 100644 index 0000000..d032da5 --- /dev/null +++ b/PackageManager/stdafx.h @@ -0,0 +1,25 @@ +// stdafx.h : ׼ϵͳļİļ +// Ǿʹõĵ +// ضĿİļ +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Windows ͷųʹõ +// Windows ͷļ: +#include + + + +// TODO: ڴ˴óҪͷļ +#include +#include +#include + +#using + +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Management::Deployment; \ No newline at end of file diff --git a/PackageManager/targetver.h b/PackageManager/targetver.h new file mode 100644 index 0000000..416cebf --- /dev/null +++ b/PackageManager/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h õ߰汾 Windows ƽ̨ + +// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h +// _WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h + +#include diff --git a/PackageManagerAdd/AddPackageSample.cpp b/PackageManagerAdd/AddPackageSample.cpp new file mode 100644 index 0000000..0019257 --- /dev/null +++ b/PackageManagerAdd/AddPackageSample.cpp @@ -0,0 +1,34 @@ +//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +//// PARTICULAR PURPOSE. +//// +//// Copyright (c) Microsoft Corporation. All rights reserved + +#include "stdafx.h" +#include "PackageManager.h" +#include +using namespace std; +void callback (unsigned progress) +{ + std::cout << '\r' << progress << "%" << std::ends; +} + +[MTAThread] +int __cdecl main(Platform::Array^ args) +{ + wcout << L"Copyright (c) Microsoft Corporation. All rights reserved." << endl; + wcout << L"Add Package" << endl << endl; + + if (args->Length < 2) + { + wcout << L"Usage: addpkg.exe packageUri" << endl; + return 1; + } + HANDLE completedEvent = nullptr; + int returnValue = 0; + String^ inputPackageUri = args[1]; + cout << endl; + AddPackageFromPath (inputPackageUri->Data (), &callback); + return 0; +} diff --git a/PackageManagerAdd/AddPackageSample.sln b/PackageManagerAdd/AddPackageSample.sln new file mode 100644 index 0000000..5afbb33 --- /dev/null +++ b/PackageManagerAdd/AddPackageSample.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 12 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AddPackageSample", "AddPackageSample.vcxproj", "{59131AB7-2A7D-9A09-8223-174C3F5E0F57}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Win32.ActiveCfg = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Win32.Build.0 = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Win32.ActiveCfg = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PackageManagerAdd/AddPackageSample.vcxproj b/PackageManagerAdd/AddPackageSample.vcxproj new file mode 100644 index 0000000..c10f9e9 --- /dev/null +++ b/PackageManagerAdd/AddPackageSample.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Release + ARM + + + Release + Win32 + + + + $(VCTargetsPath11) + 12.0 + + + Win32Proj + {59131AB7-2A7D-9A09-8223-174C3F5E0F57} + PackageManager + + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + false + v120 + Unicode + + + DynamicLibrary + false + v120 + Unicode + + + + + + + + + + + + + + + + + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + + WIN32;_DEBUG;PKGMGR_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + true + false + /ZW:nostdlib /FUplatform.winmd /FUwindows.winmd %(AdditionalOptions) + Create + + + MachineX86 + true + NotSet + + + + + WIN32;_DEBUG;PKGMGR_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + true + false + /ZW:nostdlib /FUplatform.winmd /FUwindows.winmd %(AdditionalOptions) + Create + + + true + NotSet + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + true + /ZW:nostdlib /FUplatform.winmd /FUWindows.winmd %(AdditionalOptions) + + + MachineX86 + true + Console + true + true + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + true + /ZW:nostdlib /FUplatform.winmd /FUWindows.winmd %(AdditionalOptions) + + + true + Console + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PackageManagerAdd/PackageManager.h b/PackageManagerAdd/PackageManager.h new file mode 100644 index 0000000..a690639 --- /dev/null +++ b/PackageManagerAdd/PackageManager.h @@ -0,0 +1,26 @@ +#pragma once +#ifdef PKGMGR_EXPORTS +#define PKGMGR_API __declspec(dllexport) +#else +#define PKGMGR_API __declspec(dllimport) +#endif + +typedef void (*_PACKAGE_ADD_PROGRESS)(unsigned progress); +typedef _PACKAGE_ADD_PROGRESS PACKAGE_ADD_PROGRESS; + +enum class InstallStatus +{ + Success, + Error, + Canceled +}; + +extern "C" PKGMGR_API InstallStatus AddPackageFromPath (LPCWSTR lpswPath, PACKAGE_ADD_PROGRESS callbProgress); + +extern "C" PKGMGR_API LPCWSTR GetLastErrorCode (); + +extern "C" PKGMGR_API LPCWSTR GetLastErrorDetailText (); + +extern "C" PKGMGR_API size_t GetLastErrorCodeLength (); + +extern "C" PKGMGR_API size_t GetLastErrorDetailTextLength (); \ No newline at end of file diff --git a/PackageManagerAdd/README.txt b/PackageManagerAdd/README.txt new file mode 100644 index 0000000..09ff1df --- /dev/null +++ b/PackageManagerAdd/README.txt @@ -0,0 +1,39 @@ +Add Package Sample +==================== +This sample demonstrates how to use IPackageManager to install a package. + +Prerequisites +============= +This sample requires Windows 8.1+. +This sample requires Visual Studio 12 Ultimate Developer Preview. +This sample requires the Windows Runtime Software Development Kit. + +Sample Language Implementations +=============================== +C++ + +Files: +====== +AddPackageSample.cpp + +To build the sample using the command prompt: +============================================= + 1. Open the Command Prompt window and navigate to the directory. + 2. Type msbuild AddPackageSample.sln. + + +To build the sample using Visual Studio 12 Ultimate Developer Preview (preferred method): +================================================ + 1. Open File Explorer and navigate to the directory. + 2. Double-click the icon for the .sln (solution) file to open the file in + Visual Studio. + 3. In the Build menu, select Build Solution. The application will be + built in the default \Debug or \Release directory. + + +To Run the sample: +================== + 1. Open a command prompt. + 2. Navigate to the directory containing AddPackageSample.exe + 2. Type AddPackageSample.exe "" at the command line. + For example, AddPackageSample.exe "file://C|/users/testuser/desktop/testpackage.appx" diff --git a/PackageManagerAdd/pkgaddcode.cpp b/PackageManagerAdd/pkgaddcode.cpp new file mode 100644 index 0000000..940c367 --- /dev/null +++ b/PackageManagerAdd/pkgaddcode.cpp @@ -0,0 +1,86 @@ +#include "stdafx.h" +#include "PackageManager.h" + +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Management::Deployment; + +std::wstring lastErrorCode (L""); +std::wstring lastErrorDetailText (L""); + +[MTAThread] +InstallStatus AddPackageFromPath (LPCWSTR lpswPath, PACKAGE_ADD_PROGRESS callbProgress) +{ + lastErrorCode = L""; + lastErrorDetailText = L""; + HANDLE completedEvent = nullptr; + try + { + completedEvent = CreateEventEx (nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); + if (!completedEvent) return InstallStatus::Error; + String ^inputPackageUri = ref new String (lpswPath); + auto packageUri = ref new Uri (inputPackageUri); + auto packageManager = ref new PackageManager (); + auto deploymentOperation = packageManager->AddPackageAsync (packageUri, nullptr, DeploymentOptions::None); + deploymentOperation->Progress = + ref new AsyncOperationProgressHandler ( + [callbProgress] (IAsyncOperationWithProgress^ operation, DeploymentProgress progress) + { + if (callbProgress) + callbProgress (progress.percentage); + }); + deploymentOperation->Completed = + ref new AsyncOperationWithProgressCompletedHandler ( + [&completedEvent] (IAsyncOperationWithProgress^ operation, AsyncStatus) + { + SetEvent (completedEvent); + }); + WaitForSingleObject (completedEvent, INFINITE); + if (!completedEvent) + { + CloseHandle (completedEvent); completedEvent = nullptr; + } + if (deploymentOperation->Status == AsyncStatus::Error) + { + auto deploymentResult = deploymentOperation->GetResults (); + lastErrorCode += deploymentOperation->ErrorCode.Value; + lastErrorDetailText += deploymentResult->ErrorText->Data (); + return InstallStatus::Error; + } + else if (deploymentOperation->Status == AsyncStatus::Canceled) + { + lastErrorDetailText += L"Installation Canceled"; + return InstallStatus::Canceled; + } + else if (deploymentOperation->Status == AsyncStatus::Completed) + { + return InstallStatus::Success; + } + } + catch (Exception ^ex) + { + lastErrorDetailText += ex->ToString ()->Data (); + return InstallStatus::Error; + } + if (!completedEvent) + { + CloseHandle (completedEvent); completedEvent = nullptr; + } + return InstallStatus::Canceled; +} + +LPCWSTR GetLastErrorCode () +{ + if (lastErrorCode.length () == 0) return NULL; + else return lastErrorCode.c_str (); +} + +LPCWSTR GetLastErrorDetailText () +{ + if (lastErrorDetailText.length () == 0) return NULL; + else return lastErrorDetailText.c_str (); +} + +size_t GetLastErrorCodeLength () { return lastErrorCode.length (); } + +size_t GetLastErrorDetailTextLength () { return lastErrorDetailText.length (); } \ No newline at end of file diff --git a/PackageManagerAdd/stdafx.h b/PackageManagerAdd/stdafx.h new file mode 100644 index 0000000..474caa9 --- /dev/null +++ b/PackageManagerAdd/stdafx.h @@ -0,0 +1,12 @@ +#pragma once +#include +#include +#include +#include + +#using + +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Management::Deployment; +using namespace std; \ No newline at end of file diff --git a/PriReader/AddPackageSample.cpp b/PriReader/AddPackageSample.cpp new file mode 100644 index 0000000..0019257 --- /dev/null +++ b/PriReader/AddPackageSample.cpp @@ -0,0 +1,34 @@ +//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +//// PARTICULAR PURPOSE. +//// +//// Copyright (c) Microsoft Corporation. All rights reserved + +#include "stdafx.h" +#include "PackageManager.h" +#include +using namespace std; +void callback (unsigned progress) +{ + std::cout << '\r' << progress << "%" << std::ends; +} + +[MTAThread] +int __cdecl main(Platform::Array^ args) +{ + wcout << L"Copyright (c) Microsoft Corporation. All rights reserved." << endl; + wcout << L"Add Package" << endl << endl; + + if (args->Length < 2) + { + wcout << L"Usage: addpkg.exe packageUri" << endl; + return 1; + } + HANDLE completedEvent = nullptr; + int returnValue = 0; + String^ inputPackageUri = args[1]; + cout << endl; + AddPackageFromPath (inputPackageUri->Data (), &callback); + return 0; +} diff --git a/PriReader/AddPackageSample.vcxproj b/PriReader/AddPackageSample.vcxproj new file mode 100644 index 0000000..806307b --- /dev/null +++ b/PriReader/AddPackageSample.vcxproj @@ -0,0 +1,103 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + $(VCTargetsPath11) + 12.0 + + + Win32Proj + {59131AB7-2A7D-9A09-8223-174C3F5E0F57} + PriReader + + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + false + v120 + Unicode + + + + + + + + + + + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + + WIN32;_DEBUG;PRIREADER_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + true + false + /ZW:nostdlib /FUplatform.winmd /FUwindows.winmd %(AdditionalOptions) + Create + + + MachineX86 + true + NotSet + shlwapi.lib;runtimeobject.lib;%(AdditionalDependencies) + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + true + /ZW:nostdlib /FUplatform.winmd /FUWindows.winmd %(AdditionalOptions) + + + MachineX86 + true + Console + true + true + shlwapi.lib;runtimeobject.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PriReader/PriReader.cpp b/PriReader/PriReader.cpp new file mode 100644 index 0000000..8be9ff9 --- /dev/null +++ b/PriReader/PriReader.cpp @@ -0,0 +1,84 @@ +#include "stdafx.h" +#include "PriReader.h" + +static HRESULT InitializeResourceManager (ComPtr& resourceManager) +{ + ComPtr resourceManagerStatics; + HRESULT hr = RoInitialize (RO_INIT_MULTITHREADED); + if (FAILED (hr)) + { + return hr; + } + hr = RoGetActivationFactory (HStringReference (RuntimeClass_Windows_ApplicationModel_Resources_Core_ResourceManager).Get (), IID_PPV_ARGS (&resourceManagerStatics)); + if (FAILED (hr)) + { + return hr; + } + // Windows 8 ʹ `GetCurrent` ȡȫ ResourceManager + hr = resourceManagerStatics->GetCurrent (&resourceManager); + return hr; +} + +static LPWSTR GetResourceValue (ComPtr resourceManager, LPCWSTR srcName) +{ + ComPtr resourceMap; + HRESULT hr = resourceManager->get_MainResourceMap (&resourceMap); + if (FAILED (hr)) + { + return nullptr; + } + + HSTRING hResourceName; + hr = WindowsCreateString (srcName, static_cast(wcslen (srcName)), &hResourceName); + if (FAILED (hr)) + { + return nullptr; + } + + ComPtr resourceCandidate; + hr = resourceMap->GetValue (hResourceName, &resourceCandidate); + WindowsDeleteString (hResourceName); + if (FAILED (hr)) + { + return nullptr; + } + HSTRING hResourceValue; + hr = resourceCandidate->get_ValueAsString (&hResourceValue); + if (FAILED (hr)) + { + return nullptr; + } + const wchar_t* resourceValue = WindowsGetStringRawBuffer (hResourceValue, nullptr); + LPWSTR result = (LPWSTR)calloc (wcslen (resourceValue) + 1, sizeof (wchar_t)); + if (result) + { + wcscpy_s (result, wcslen (resourceValue) + 1, resourceValue); + } + + WindowsDeleteString (hResourceValue); + return result; +} + +EXTERN_C LPWSTR GetStringValueFromPriSource (IStream* priFileStream, LPCWSTR srcName) +{ + // Windows 8 ֱ֧Ӽ PRI ļʡ stream + ComPtr resourceManager; + HRESULT hr = InitializeResourceManager (resourceManager); + if (FAILED (hr)) + { + return nullptr; + } + return GetResourceValue (resourceManager, srcName); +} + +EXTERN_C LPWSTR GetResourceValueFromPriSource (IStream* priFileStream, LPCWSTR srcName) +{ + // Windows 8 ֧Ĭ ResourceManager + ComPtr resourceManager; + HRESULT hr = InitializeResourceManager (resourceManager); + if (FAILED (hr)) + { + return nullptr; + } + return GetResourceValue (resourceManager, srcName); +} \ No newline at end of file diff --git a/PriReader/PriReader.h b/PriReader/PriReader.h new file mode 100644 index 0000000..3e55864 --- /dev/null +++ b/PriReader/PriReader.h @@ -0,0 +1,11 @@ +#pragma once +#ifdef PRIREADER_EXPORTS +#define PRIREADER_API __declspec(dllexport) +#else +#define PRIREADER_API __declspec(dllimport) +#endif + +#include + +EXTERN_C LPWSTR GetStringValueFromPriSource (IStream *priFileStream, LPCWSTR srcName); +EXTERN_C LPWSTR GetResourceValueFromPriSource (IStream *priFileStream, LPCWSTR srcName); \ No newline at end of file diff --git a/PriReader/PriReader.sln b/PriReader/PriReader.sln new file mode 100644 index 0000000..5afbb33 --- /dev/null +++ b/PriReader/PriReader.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 12 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AddPackageSample", "AddPackageSample.vcxproj", "{59131AB7-2A7D-9A09-8223-174C3F5E0F57}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Win32.ActiveCfg = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Win32.Build.0 = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Win32.ActiveCfg = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PriReader/README.txt b/PriReader/README.txt new file mode 100644 index 0000000..09ff1df --- /dev/null +++ b/PriReader/README.txt @@ -0,0 +1,39 @@ +Add Package Sample +==================== +This sample demonstrates how to use IPackageManager to install a package. + +Prerequisites +============= +This sample requires Windows 8.1+. +This sample requires Visual Studio 12 Ultimate Developer Preview. +This sample requires the Windows Runtime Software Development Kit. + +Sample Language Implementations +=============================== +C++ + +Files: +====== +AddPackageSample.cpp + +To build the sample using the command prompt: +============================================= + 1. Open the Command Prompt window and navigate to the directory. + 2. Type msbuild AddPackageSample.sln. + + +To build the sample using Visual Studio 12 Ultimate Developer Preview (preferred method): +================================================ + 1. Open File Explorer and navigate to the directory. + 2. Double-click the icon for the .sln (solution) file to open the file in + Visual Studio. + 3. In the Build menu, select Build Solution. The application will be + built in the default \Debug or \Release directory. + + +To Run the sample: +================== + 1. Open a command prompt. + 2. Navigate to the directory containing AddPackageSample.exe + 2. Type AddPackageSample.exe "" at the command line. + For example, AddPackageSample.exe "file://C|/users/testuser/desktop/testpackage.appx" diff --git a/PriReader/stdafx.h b/PriReader/stdafx.h new file mode 100644 index 0000000..ce54ca0 --- /dev/null +++ b/PriReader/stdafx.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace Windows::ApplicationModel::Resources::Core; + diff --git a/PriReader2/PriReader2.cpp b/PriReader2/PriReader2.cpp new file mode 100644 index 0000000..1c036f3 --- /dev/null +++ b/PriReader2/PriReader2.cpp @@ -0,0 +1,1879 @@ +// PriReader2.cpp : DLL Ӧóĵ +// + +#include "stdafx.h" +#include "localeex.h" +#include "PriReader2.h" + +int GetDPI () +{ + HDC hDC = GetDC (NULL); + int DPI_A = (int)(((double)GetDeviceCaps (hDC, 118) / (double)GetDeviceCaps (hDC, 8)) * 100); + int DPI_B = (int)(((double)GetDeviceCaps (hDC, 88) / 96) * 100); + ReleaseDC (NULL, hDC); + if (DPI_A == 100) return DPI_B; + else if (DPI_B == 100) return DPI_A; + else if (DPI_A == DPI_B) return DPI_A; + else return 0; +} +std::string GetProgramRootDirectoryA () +{ + char path [MAX_PATH]; + if (GetModuleFileNameA (NULL, path, MAX_PATH)) + { + std::string dir (path); + size_t pos = dir.find_last_of ("\\/"); + if (pos != std::string::npos) + { + dir = dir.substr (0, pos); + } + return dir; + } + return ""; +} +std::wstring GetProgramRootDirectoryW () +{ + wchar_t path [MAX_PATH]; + if (GetModuleFileNameW (NULL, path, MAX_PATH)) + { + std::wstring dir (path); + size_t pos = dir.find_last_of (L"\\/"); + if (pos != std::wstring::npos) + { + dir = dir.substr (0, pos); + } + return dir; + } + return L""; +} +std::string EnsureTrailingSlash (const std::string &path) +{ + if (path.empty ()) return path; // ·ֱӷ + + char lastChar = path.back (); + if (lastChar == '\\' || lastChar == '/') + return path; // зֱָӷ + // ϵͳԭ·ʽʵķָ + char separator = (path.find ('/') != std::string::npos) ? '/' : '\\'; + return path + separator; +} +std::wstring EnsureTrailingSlash (const std::wstring &path) +{ + if (path.empty ()) return path; + + wchar_t lastChar = path.back (); + if (lastChar == L'\\' || lastChar == L'/') + return path; + + wchar_t separator = (path.find (L'/') != std::wstring::npos) ? L'/' : L'\\'; + return path + separator; +} +extern "C" bool IsFileExistsW (LPCWSTR filename) +{ + DWORD dwAttrib = GetFileAttributesW (filename); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +} +extern "C" bool IsFileExistsA (LPCSTR filename) +{ + DWORD dwAttrib = GetFileAttributesA (filename); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +} +bool IsFileExists (LPWSTR filePath) { return IsFileExistsW (filePath); } +bool IsFileExists (LPCSTR filePath) { return IsFileExistsA (filePath); } +bool IsFileExists (std::string filePath) { return IsFileExistsA (filePath.c_str ()); } +bool IsFileExists (std::wstring filePath) { return IsFileExistsW (filePath.c_str ()); } +bool IsDirectoryExistsA (LPCSTR path) +{ + DWORD attributes = GetFileAttributesA (path); + return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY)); +} +bool IsDirectoryExistsW (LPCWSTR path) +{ + DWORD attributes = GetFileAttributesW (path); + return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY)); +} +bool IsDirectoryExists (const std::string path) { return IsDirectoryExistsA (path.c_str ()); } +bool IsDirectoryExists (const std::wstring path) { return IsDirectoryExistsW (path.c_str ()); } +bool IsDirectoryExists (LPCSTR path) { return IsDirectoryExistsA (path); } +bool IsDirectoryExists (LPCWSTR path) { return IsDirectoryExistsW (path); } +std::string NormalizePath (const std::string &path) +{ + if (!path.empty () && path.back () == '\\') + return path.substr (0, path.size () - 1); + return path; +} +std::wstring NormalizePath (const std::wstring &path) +{ + if (!path.empty () && path.back () == L'\\') + return path.substr (0, path.size () - 1); + return path; +} +std::vector EnumSubdirectories (const std::string &directory, bool includeParentPath) +{ + std::vector subdirs; + std::string normPath = NormalizePath (directory); + std::string searchPath = normPath + "\\*"; + WIN32_FIND_DATAA findData; + HANDLE hFind = FindFirstFileA (searchPath.c_str (), &findData); + if (hFind == INVALID_HANDLE_VALUE) return subdirs; + do + { + // "." ".." + if (strcmp (findData.cFileName, ".") == 0 || strcmp (findData.cFileName, "..") == 0) + continue; + // жǷΪĿ¼ + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (includeParentPath) + subdirs.push_back (normPath + "\\" + findData.cFileName); + else + subdirs.push_back (findData.cFileName); + } + } while (FindNextFileA (hFind, &findData)); + FindClose (hFind); + return subdirs; +} +std::vector EnumSubdirectories (const std::wstring &directory, bool includeParentPath) +{ + std::vector subdirs; + std::wstring normPath = NormalizePath (directory); + std::wstring searchPath = normPath + L"\\*"; + WIN32_FIND_DATAW findData; + HANDLE hFind = FindFirstFileW (searchPath.c_str (), &findData); + if (hFind == INVALID_HANDLE_VALUE) return subdirs; + do + { + if (wcscmp (findData.cFileName, L".") == 0 || wcscmp (findData.cFileName, L"..") == 0) + continue; + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (includeParentPath) + subdirs.push_back (normPath + L"\\" + findData.cFileName); + else + subdirs.push_back (findData.cFileName); + } + } while (FindNextFileW (hFind, &findData)); + FindClose (hFind); + return subdirs; +} +bool CheckDependency (const std::string &dllName) +{ + HMODULE hModule = LoadLibraryA (dllName.c_str ()); + if (hModule == NULL) + { + return false; + } + FreeLibrary (hModule); + return true; +} +bool CheckDependency (const std::wstring &dllName) +{ + HMODULE hModule = LoadLibraryW (dllName.c_str ()); + if (hModule == NULL) + { + return false; + } + FreeLibrary (hModule); + return true; +} +bool CanRunExe (const std::string &exePath) +{ + STARTUPINFOA si = {sizeof (si)}; + PROCESS_INFORMATION pi; + BOOL success = CreateProcessA ( + exePath.c_str (), // Ӧ· + NULL, // в + NULL, // ȫ + NULL, // ̰߳ȫ + FALSE, // ̳о + CREATE_NO_WINDOW, // + NULL, // + NULL, // ǰĿ¼ + &si, // Ϣ + &pi // Ϣ + ); + if (!success) + { + DWORD error = GetLastError (); + return false; + } + WaitForSingleObject (pi.hProcess, INFINITE); + DWORD exitCode; + GetExitCodeProcess (pi.hProcess, &exitCode); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return (exitCode == 0); +} +bool CanRunExe (const std::wstring& exePath) +{ + STARTUPINFOW si = {sizeof (si)}; + PROCESS_INFORMATION pi; + BOOL success = CreateProcessW ( + exePath.c_str (), // Ӧ· + NULL, // в + NULL, // ȫ + NULL, // ̰߳ȫ + FALSE, // ̳о + CREATE_NO_WINDOW, // + NULL, // + NULL, // ǰĿ¼ + &si, // Ϣ + &pi // Ϣ + ); + if (!success) + { + DWORD error = GetLastError (); + return false; + } + WaitForSingleObject (pi.hProcess, INFINITE); + DWORD exitCode; + GetExitCodeProcess (pi.hProcess, &exitCode); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return (exitCode == 0); +} +bool IsProgramExecutable (const std::string &exePath) +{ + if (!IsFileExists (exePath)) + { + return false; + } + if (!CanRunExe (exePath)) + { + return false; + } + return true; +} +bool IsProgramExecutable (const std::wstring &exePath) +{ + if (!IsFileExists (exePath)) + { + return false; + } + if (!CanRunExe (exePath)) + { + return false; + } + return true; +} +std::wstring GetUniqueTempFilePathW () +{ + // ȡʱļ· + wchar_t tempPath [MAX_PATH]; + if (GetTempPath (MAX_PATH, tempPath) == 0) + { + return L""; + } + // һΨһʱļ + wchar_t tempFile [MAX_PATH]; + if (GetTempFileName (tempPath, L"TMP", 0, tempFile) == 0) + { + return L""; + } + return tempFile; +} +std::string GetUniqueTempFilePathA () { + // ȡʱļ· + char tempPath [MAX_PATH]; + if (GetTempPathA (MAX_PATH, tempPath) == 0) + { + return ""; + } + // һΨһʱļ + char tempFile [MAX_PATH]; + if (GetTempFileNameA (tempPath, "TMP", 0, tempFile) == 0) + { + return ""; + } + return tempFile; +} +std::wstring StringTrim (const std::wstring &str) +{ + if (str.empty ()) return L""; + LPCWSTR start = str.c_str (); + LPCWSTR end = start + str.size () - 1; +#define isblankstrlabelw(wch) (wch == L' ' || wch == L'\t' || wch == L'\n') + while (*start != L'\0' && isblankstrlabelw (*start)) ++start; + while (end >= start && isblankstrlabelw (*end)) --end; + if (start > end) return L""; + return std::wstring (start, end + 1); +} +std::string StringTrim (const std::string &str) +{ + if (str.empty ()) return ""; + LPCSTR start = str.c_str (); + LPCSTR end = start + str.size () - 1; +#define isblankstrlabela(wch) (wch == ' ' || wch == '\t' || wch == '\n') + while (*start != L'\0' && isblankstrlabela (*start)) ++start; + while (end >= start && isblankstrlabela (*end)) --end; + if (start > end) return ""; + return std::string (start, end + 1); +} +namespace l0km +{ + template < typename E, + typename TR = std::char_traits, + typename AL = std::allocator < E >> + inline std::basic_string toupper (const std::basic_string &src) + { + std::basic_string dst = src; + static const std::locale loc; + const std::ctype &ctype = std::use_facet> (loc); + for (typename std::basic_string::size_type i = 0; i < src.size (); ++i) + { + dst [i] = ctype.toupper (src [i]); + } + return dst; + } + + template < typename E, + typename TR = std::char_traits, + typename AL = std::allocator < E >> + inline std::basic_string tolower (const std::basic_string &src) + { + std::basic_string dst = src; + static const std::locale loc; + const std::ctype &ctype = std::use_facet> (loc); + for (typename std::basic_string::size_type i = 0; i < src.size (); ++i) + { + dst [i] = ctype.tolower (src [i]); + } + return dst; + } +} // namespace l0km +#define StringToUpper l0km::toupper +#define StringToLower l0km::tolower +int LabelCompare (const std::wstring &l1, const std::wstring &l2) +{ + std::wstring s1 = StringToUpper (StringTrim (l1)), + s2 = StringToUpper (StringTrim (l2)); + return lstrcmpW (s1.c_str (), s2.c_str ()); +} +int LabelCompare (LPCWSTR l1, LPCWSTR l2) +{ + return LabelCompare (std::wstring (l1), std::wstring (l2)); +} +int LabelCompare (const std::string &l1, const std::string &l2) +{ + std::string s1 = StringToUpper (StringTrim (l1)), + s2 = StringToUpper (StringTrim (l2)); + return lstrcmpA (s1.c_str (), s2.c_str ()); +} +int LabelCompare (LPCSTR l1, LPCSTR l2) +{ + return LabelCompare (std::string (l1), std::string (l2)); +} +bool LabelEqual (const std::wstring &l1, const std::wstring &l2) +{ + return !LabelCompare (l1, l2); +} +bool LabelEqual (LPCWSTR l1, LPCWSTR l2) +{ + return !LabelCompare (l1, l2); +} +bool LabelEqual (const std::string &l1, const std::string &l2) +{ + return !LabelCompare (l1, l2); +} +bool LabelEqual (LPCSTR l1, LPCSTR l2) +{ + return !LabelCompare (l1, l2); +} +int InStr (const std::string &text, const std::string &keyword, bool ignoreCase = false) +{ + std::string s1, s2; + if (ignoreCase) + { + s1 = StringToUpper (text); + s2 = StringToUpper (keyword); + } + else + { + s1 = text; + s2 = keyword; + } + const char *found = StrStrIA (s1.c_str (), s2.c_str ()); + if (!found) + { + return -1; + } + return found - text.c_str (); +} +int InStr (const std::wstring &text, const std::wstring &keyword, bool ignoreCase = false) +{ + std::wstring s1, s2; + if (ignoreCase) + { + s1 = StringToUpper (text); + s2 = StringToUpper (keyword); + } + else + { + s1 = text; + s2 = keyword; + } + const WCHAR *found = StrStrIW (s1.c_str (), s2.c_str ()); + if (!found) + { + return -1; + } + return found - text.c_str (); +} + +enum class ProcessorArchitecture +{ + x86 = 1, + x64 = 2, + arm = 3, + arm64 = 4 +}; + +typedef struct VERSION +{ + UINT16 build, maintenance, minor, major; + VERSION (UINT16 major, UINT16 minor, UINT16 maintenance, UINT16 build); + VERSION (UINT64 ver); + VERSION (); + virtual ~VERSION (); + std::wstring toStringW (); + std::string toString (); + bool isEmpty (); + UINT64 getUInt64 (); + INT64 compare (VERSION &another); + bool equals (VERSION &another); + bool operator == (VERSION &another) { return this->equals (another); } + bool operator > (VERSION &another) { return this->getUInt64 () > another.getUInt64 (); } + bool operator < (VERSION &another) { return this->getUInt64 () < another.getUInt64 (); } + bool operator >= (VERSION &another) { return !(*this < another); } + bool operator <= (VERSION &another) { return !(*this > another); } + bool operator != (VERSION &another) { return !this->equals (another); } + static VERSION stringTo (const std::string &str); + static VERSION stringTo (const std::wstring &str); + static VERSION stringTo (LPCSTR str); + static VERSION stringTo (LPCWSTR str); + VERSION setFromString (const std::string &str) + { + VERSION v = stringTo (str); + this->major = v.major; + this->minor = v.minor; + this->maintenance = v.maintenance; + this->build = v.build; + return *this; + } + VERSION setFromString (const std::wstring &str) + { + VERSION v = stringTo (str); + this->major = v.major; + this->minor = v.minor; + this->maintenance = v.maintenance; + this->build = v.build; + return *this; + } + private: + static std::vector splitVersionString (const std::string &str); + static std::vector splitVersionString (const std::wstring &str); +} _VERSION, VERSION, Version, version; +VERSION::VERSION (UINT16 major, UINT16 minor, UINT16 maintenance, UINT16 build): + major (major), minor (minor), maintenance (maintenance), build (build) {} +VERSION::VERSION (UINT64 verdata) : major ((verdata >> 0x30) & 0xFFFF), minor ((verdata >> 0x20) & 0xFFFF), +maintenance ((verdata >> 0x10) & 0xFFFF), build ((verdata) & 0xFFFF) {} +VERSION::VERSION () : major (0), minor (0), maintenance (0), build (0) {} +VERSION::~VERSION () +{ + this->major = 0; + this->minor = 0; + this->maintenance = 0; + this->build = 0; +} +std::wstring VERSION::toStringW () +{ + std::wstringstream ss; + ss << this->major << L'.' << this->minor << L'.' << this->maintenance << L'.' << this->build << std::ends; + std::wstring st (L""); + st += ss.str (); + return st; +} +std::string VERSION::toString () +{ + std::stringstream ss; + ss << this->major << '.' << this->minor << '.' << this->maintenance << '.' << this->build << std::ends; + std::string st (""); + st += ss.str (); + return st; +} +bool VERSION::isEmpty () +{ + return this->getUInt64 () == 0; +} +UINT64 VERSION::getUInt64 () +{ + UINT64 u64 = (((UINT64)major) << 0x30) | (((UINT64)minor) << 0x20) | (((UINT64)maintenance) << 0x10) | ((UINT64)build); + return u64; +} +INT64 VERSION::compare (VERSION &another) +{ + UINT64 u1 = this->getUInt64 (), u2 = another.getUInt64 (); + return u1 - u2; +} +bool VERSION::equals (VERSION &another) +{ + return !this->compare (another); +} +std::vector VERSION::splitVersionString (const std::string &str) +{ + std::vector result; + std::stringstream ss (str); + std::string segment; + while (std::getline (ss, segment, '.')) // Ȱ '.' + { + size_t pos = 0; + while ((pos = segment.find (',')) != std::string::npos) // ٰ ',' + { + result.push_back (segment.substr (0, pos)); + segment.erase (0, pos + 1); + } + result.push_back (segment); + } + return result; +} +std::vector VERSION::splitVersionString (const std::wstring &str) +{ + std::vector result; + std::wstringstream ss (str); + std::wstring segment; + while (std::getline (ss, segment, L'.')) // Ȱ '.' + { + size_t pos = 0; + while ((pos = segment.find (L',')) != std::wstring::npos) // ٰ ',' + { + result.push_back (segment.substr (0, pos)); + segment.erase (0, pos + 1); + } + result.push_back (segment); + } + return result; +} +VERSION VERSION::stringTo (const std::string &str) +{ + std::vector parts = splitVersionString (str); + UINT16 major = (parts.size () > 0) ? static_cast(std::stoi (parts [0])) : 0; + UINT16 minor = (parts.size () > 1) ? static_cast(std::stoi (parts [1])) : 0; + UINT16 maintenance = (parts.size () > 2) ? static_cast(std::stoi (parts [2])) : 0; + UINT16 build = (parts.size () > 3) ? static_cast(std::stoi (parts [3])) : 0; + return VERSION (major, minor, maintenance, build); +} +VERSION VERSION::stringTo (const std::wstring &str) +{ + std::vector parts = splitVersionString (str); + UINT16 major = (parts.size () > 0) ? static_cast(std::stoi (parts [0])) : 0; + UINT16 minor = (parts.size () > 1) ? static_cast(std::stoi (parts [1])) : 0; + UINT16 maintenance = (parts.size () > 2) ? static_cast(std::stoi (parts [2])) : 0; + UINT16 build = (parts.size () > 3) ? static_cast(std::stoi (parts [3])) : 0; + return VERSION (major, minor, maintenance, build); +} +VERSION VERSION::stringTo (LPCSTR str) +{ + return stringTo (std::string (str)); +} +VERSION VERSION::stringTo (LPCWSTR str) +{ + return stringTo (std::wstring (str)); +} + +struct ProgramExeInfo +{ + std::wstring filePath; + ProcessorArchitecture process; + VERSION version; + ProgramExeInfo (std::wstring filePath, ProcessorArchitecture process, VERSION version): filePath (filePath), process (process), version (version) {} + ProgramExeInfo (): filePath (L""), process (ProcessorArchitecture::x86), version (0) {} + bool operator == (ProgramExeInfo &another) + { + return LabelEqual (this->filePath, another.filePath) && this->process == another.process && this->version == another.version; + } + bool operator < (ProgramExeInfo &another) + { + if (this->version > another.version) return true; + if (this->version < another.version) return false; + return static_cast(this->process) < static_cast(another.process); + } +}; + +ProcessorArchitecture GetProcessorArchitecture () +{ + SYSTEM_INFO sysInfo; + GetSystemInfo (&sysInfo); + switch (sysInfo.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_INTEL: + return ProcessorArchitecture::x86; // 32-bit Intel + case PROCESSOR_ARCHITECTURE_AMD64: + return ProcessorArchitecture::x64; // 64-bit Intel/AMD + case PROCESSOR_ARCHITECTURE_ARM: + return ProcessorArchitecture::arm; // ARM + case 12: + return ProcessorArchitecture::arm64; // ARM64 + default: + throw std::runtime_error ("Unknown processor architecture."); + } + return ProcessorArchitecture::x86; +} + +template StringType ReplaceBackslash (const StringType &input) +{ + StringType result = input; // ַ޸ԭ + using CharType = typename StringType::value_type; // ȡַַͣchar wchar_t + std::replace (result.begin (), result.end (), static_cast ('\\'), static_cast ('/')); + return result; +} + +HRESULT ExtractFileFromStream (_In_ IStream* ifile, _In_ LPCWSTR outputFilePath) +{ + if (ifile == nullptr || outputFilePath == nullptr) + { + return E_INVALIDARG; + } + HRESULT hr = S_OK; + IStream* outputStream = nullptr; + ULARGE_INTEGER fileSizeLargeInteger = {0}; + STATSTG statstg = {0}; + // ȡĴС + hr = ifile->Stat (&statstg, STATFLAG_NONAME); + if (SUCCEEDED (hr)) + { + fileSizeLargeInteger.QuadPart = statstg.cbSize.QuadPart; + } + // ļ IStream + if (SUCCEEDED (hr)) + { + hr = SHCreateStreamOnFileEx ( + outputFilePath, + STGM_CREATE | STGM_READWRITE | STGM_SHARE_DENY_NONE, + 0, + TRUE, + NULL, + &outputStream); + } + // ݵ + if (SUCCEEDED (hr)) + { + hr = ifile->CopyTo (outputStream, fileSizeLargeInteger, nullptr, nullptr); + } + // ȷȫд + if (SUCCEEDED (hr) && outputStream) + { + hr = outputStream->Commit (STGC_DEFAULT); // ˢ» + } + // ͷԴ + if (outputStream) + { + outputStream->Release (); + } + return hr; +} + +class PriReader +{ + private: + static std::wstring makepri; + std::wstring prifile = L""; + std::wstring txmlpath = L""; + pugi::xml_document *xmlreader; + static bool initMakePri () + { + if (IsFileExists (makepri)) return true; // ظʼ + std::wstring rootpath = EnsureTrailingSlash (EnsureTrailingSlash (GetProgramRootDirectoryW ()) + L"Tools\\MakePRI"); + if (!IsDirectoryExists (rootpath)) rootpath = L"Tools\\MakePRI"; + if (!IsDirectoryExists (rootpath)) return false; + std::vector vers = EnumSubdirectories (rootpath, false); + if (!vers.size ()) return false; + std::vector einf; + for (auto it : vers) + { + // x86 + { + ProgramExeInfo pe; + pe.filePath = EnsureTrailingSlash (EnsureTrailingSlash (rootpath) + it) + L"x86\\makepri.exe"; + pe.process = ProcessorArchitecture::x86; + pe.version = VERSION::stringTo (it); + if (IsFileExists (pe.filePath)) + { + if (!pe.version.isEmpty ()) + { + einf.push_back (pe); + } + } + } + // x64 + { + ProgramExeInfo pe; + pe.filePath = EnsureTrailingSlash (EnsureTrailingSlash (rootpath) + it) + L"x64\\makepri.exe"; + pe.process = ProcessorArchitecture::x64; + pe.version = VERSION::stringTo (it); + if (IsFileExists (pe.filePath)) + { + if (!pe.version.isEmpty ()) + { + einf.push_back (pe); + } + } + } + // arm + { + ProgramExeInfo pe; + pe.filePath = EnsureTrailingSlash (EnsureTrailingSlash (rootpath) + it) + L"arm\\makepri.exe"; + pe.process = ProcessorArchitecture::arm; + pe.version = VERSION::stringTo (it); + if (IsFileExists (pe.filePath)) + { + if (!pe.version.isEmpty ()) + { + einf.push_back (pe); + } + } + } + // arm64 + { + ProgramExeInfo pe; + pe.filePath = EnsureTrailingSlash (EnsureTrailingSlash (rootpath) + it) + L"arm64\\makepri.exe"; + pe.process = ProcessorArchitecture::arm64; + pe.version = VERSION::stringTo (it); + if (IsFileExists (pe.filePath)) + { + if (!pe.version.isEmpty ()) + { + einf.push_back (pe); + } + } + } + } + size_t n = einf.size (); + for (size_t i = 0; i < n - 1; i ++) + { + for (size_t j = 0; j < n - 1 - i; j ++) + { + if (einf [j].version < einf [j + 1].version) + { + std::swap (einf [j], einf [j + 1]); + } + } + } + ProcessorArchitecture syspa = GetProcessorArchitecture (); + for (auto it : einf) + { + switch (syspa) + { + case ProcessorArchitecture::x64: + if (it.process == ProcessorArchitecture::x64) + { + if (IsProgramExecutable (it.filePath)) + { + PriReader::makepri = it.filePath; + return true; + } + } + case ProcessorArchitecture::x86: + if (it.process == ProcessorArchitecture::x86) + { + if (IsProgramExecutable (it.filePath)) + { + PriReader::makepri = it.filePath; + return true; + } + } break; + case ProcessorArchitecture::arm64: + if (it.process == ProcessorArchitecture::arm64) + { + if (IsProgramExecutable (it.filePath)) + { + PriReader::makepri = it.filePath; + return true; + } + } + case ProcessorArchitecture::arm: + if (it.process == ProcessorArchitecture::arm) + { + if (IsProgramExecutable (it.filePath)) + { + PriReader::makepri = it.filePath; + return true; + } + } break; + } + } + return false; + } + bool isLanguageMatch (const std::string l1, const std::string l2) + { + bool isLanguageMatch = LabelEqual (l1, l2); + if (!isLanguageMatch) + { + bool isLanguageMatch = ( + LocaleCodeToLcidA (l1.c_str ()) + == + LocaleCodeToLcidA (l2.c_str ()) + ); + } + if (!isLanguageMatch) + { + bool isLanguageMatch = LabelEqual ( + GetLocaleRestrictedCodeA (l1), + GetLocaleRestrictedCodeA (l2) + ); + } + return isLanguageMatch; + } + bool isLanguageMatch (LPCSTR l1, LPCSTR l2) + { + return isLanguageMatch (std::string (l1), std::string (l2)); + } + bool isLanguageMatch (const std::wstring l1, const std::wstring l2) + { + bool isLanguageMatch = LabelEqual (l1, l2); + if (!isLanguageMatch) + { + bool isLanguageMatch = ( + LocaleCodeToLcidW (l1.c_str ()) + == + LocaleCodeToLcidW (l2.c_str ()) + ); + } + if (!isLanguageMatch) + { + bool isLanguageMatch = LabelEqual ( + GetLocaleRestrictedCodeW (l1), + GetLocaleRestrictedCodeW (l2) + ); + } + return isLanguageMatch; + } + bool isLanguageMatch (LPCWSTR l1, LPCWSTR l2) + { + return isLanguageMatch (std::wstring (l1), std::wstring (l2)); + } + LPSTR recFindStringValue (pugi::xml_node &subResMap, LPCSTR lpMsName, LPCSTR defaultLocaleCode) + { + for (pugi::xml_node namedRes = subResMap.child ("NamedResource"); namedRes; namedRes = namedRes.next_sibling ("NamedResource")) + { + bool isMatch = false; + pugi::xml_attribute nameAttr = namedRes.attribute ("name"); + std::string resname = nameAttr.as_string (); + isMatch = LabelEqual (resname, lpMsName); + static const std::regex pattern ("^ms-resource:", std::regex_constants::icase); + if (!isMatch) + { + std::string lpname2 = std::regex_replace (std::string (lpMsName), pattern, ""); + isMatch = LabelEqual (resname, lpname2); + } + if (!isMatch) + { + pugi::xml_attribute uriAttr = namedRes.attribute ("uri"); + std::string resuri = uriAttr.as_string (); + isMatch = (InStr (resuri, resname) >= 0); + } + if (isMatch) + { + std::map langmap; + for (pugi::xml_node candidate = namedRes.child ("Candidate"); candidate; candidate = candidate.next_sibling ("Candidate")) + { + pugi::xml_attribute typeAttr = candidate.attribute ("type"); + if (!LabelEqual (typeAttr.as_string (), "String")) continue; + std::string valueGet = candidate.child ("Value").text ().get (); + for (pugi::xml_node qualifierSet = candidate.child ("QualifierSet"); qualifierSet; qualifierSet = qualifierSet.next_sibling ("QualifierSet")) + { + for (pugi::xml_node qualifier = qualifierSet.child ("Qualifier"); qualifier; qualifier = qualifier.next_sibling ("Qualifier")) + { + if (!LabelEqual (qualifier.attribute ("name").as_string (), "Language")) continue; + std::string value = qualifier.attribute ("value").as_string (); + langmap [std::string (value)] = valueGet; + } + } + } + for (auto it : langmap) + { + bool isMatch = LabelEqual (it.first, defaultLocaleCode); + if (!isMatch) isMatch = ( + LocaleCodeToLcidA (it.first.c_str ()) + == + LocaleCodeToLcidA (defaultLocaleCode) + ); + if (isMatch) + { + LPSTR lpbuf = (LPSTR)malloc (it.second.capacity () * sizeof (char)); + ZeroMemory (lpbuf, it.second.capacity ()); + lstrcpyA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + bool isMatch = isLanguageMatch (it.first, defaultLocaleCode); + if (isMatch) + { + LPSTR lpbuf = (LPSTR)malloc (it.second.capacity () * sizeof (char)); + ZeroMemory (lpbuf, it.second.capacity ()); + lstrcpyA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + bool isMatch = LabelEqual (it.first, LcidToLocaleCodeA (GetSystemDefaultLCID ())); + if (!isMatch) isMatch = ( + LocaleCodeToLcidA (it.first.c_str ()) + == + LocaleCodeToLcidA (LcidToLocaleCodeA (GetSystemDefaultLCID ()).c_str ()) + ); + if (isMatch) + { + LPSTR lpbuf = (LPSTR)malloc (it.second.capacity () * sizeof (char)); + ZeroMemory (lpbuf, it.second.capacity ()); + lstrcpyA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + bool isMatch = isLanguageMatch (it.first, LcidToLocaleCodeA (GetSystemDefaultLCID ())); + if (isMatch) + { + LPSTR lpbuf = (LPSTR)malloc (it.second.capacity () * sizeof (char)); + ZeroMemory (lpbuf, it.second.capacity ()); + lstrcpyA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + bool isMatch = isLanguageMatch (it.first, "en-us"); + if (isMatch) + { + LPSTR lpbuf = (LPSTR)malloc (it.second.capacity () * sizeof (char)); + ZeroMemory (lpbuf, it.second.capacity ()); + lstrcpyA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + bool isMatch = isLanguageMatch (it.first, "en"); + if (isMatch) + { + LPSTR lpbuf = (LPSTR)malloc (it.second.capacity () * sizeof (char)); + ZeroMemory (lpbuf, it.second.capacity ()); + lstrcpyA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + LPSTR lpbuf = (LPSTR)malloc (it.second.capacity () * sizeof (char)); + ZeroMemory (lpbuf, it.second.capacity ()); + lstrcpyA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (pugi::xml_node subtree = subResMap.child ("ResourceMapSubtree"); subtree; subtree = subtree.next_sibling ("ResourceMapSubtree")) + { + LPSTR result = recFindStringValue (subtree, lpMsName, defaultLocaleCode); + if (result) return result; // ҵͷ + } + return NULL; + } + LPWSTR recFindStringValue (pugi::xml_node &subResMap, LPCWSTR lpMsName, LPCWSTR defaultLocaleCode) + { + for (pugi::xml_node namedRes = subResMap.child ("NamedResource"); namedRes; namedRes = namedRes.next_sibling ("NamedResource")) + { + bool isMatch = false; + pugi::xml_attribute nameAttr = namedRes.attribute ("name"); + std::wstring resname = pugi::as_wide (nameAttr.as_string ()); + isMatch = LabelEqual (resname, lpMsName); + static const std::wregex pattern (L"^ms-resource:", std::regex_constants::icase); + if (!isMatch) + { + std::wstring lpname2 = std::regex_replace (std::wstring (lpMsName), pattern, L""); + isMatch = LabelEqual (resname, lpname2); + } + if (!isMatch) + { + pugi::xml_attribute uriAttr = namedRes.attribute ("uri"); + std::wstring resuri = pugi::as_wide (uriAttr.as_string ()); + isMatch = (InStr (resuri, lpMsName, true) >= 0); + } + if (!isMatch) + { + std::wstring lpname2 = std::regex_replace (std::wstring (lpMsName), pattern, L""); + pugi::xml_attribute uriAttr = namedRes.attribute ("uri"); + std::wstring resuri = pugi::as_wide (uriAttr.as_string ()); + isMatch = (InStr (resuri, lpname2, true) >= 0); + } + if (isMatch) + { + std::map langmap; + for (pugi::xml_node candidate = namedRes.child ("Candidate"); candidate; candidate = candidate.next_sibling ("Candidate")) + { + pugi::xml_attribute typeAttr = candidate.attribute ("type"); + if (!LabelEqual (typeAttr.as_string (), "String")) continue; + for (pugi::xml_node qualifierSet = candidate.child ("QualifierSet"); qualifierSet; qualifierSet = qualifierSet.next_sibling ("QualifierSet")) + { + std::wstring valueGet = pugi::as_wide (candidate.child ("Value").text ().get ()); + for (pugi::xml_node qualifier = qualifierSet.child ("Qualifier"); qualifier; qualifier = qualifier.next_sibling ("Qualifier")) + { + if (!LabelEqual (qualifier.attribute ("name").as_string (), "Language")) continue; + std::wstring value = pugi::as_wide (qualifier.attribute ("value").as_string ()); + langmap [std::wstring (value)] = valueGet; + } + } + } + for (auto it : langmap) + { + bool isMatch = LabelEqual (it.first, defaultLocaleCode); + if (!isMatch) { + isMatch = (LocaleCodeToLcidW (it.first.c_str ()) == LocaleCodeToLcidW (defaultLocaleCode)); + } + if (isMatch) { + LPWSTR lpbuf = (LPWSTR)malloc ((it.second.length () + 1) * sizeof (wchar_t)); + ZeroMemory (lpbuf, (it.second.length () + 1) * sizeof (wchar_t)); + lstrcpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + if (isLanguageMatch (it.first, defaultLocaleCode)) + { + LPWSTR lpbuf = (LPWSTR)malloc ((it.second.length () + 1) * sizeof (wchar_t)); + ZeroMemory (lpbuf, (it.second.length () + 1) * sizeof (wchar_t)); + lstrcpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + bool isMatch = LabelEqual (it.first, LcidToLocaleCodeW (GetSystemDefaultLCID ())); + if (!isMatch) + { + isMatch = (LocaleCodeToLcidW (it.first.c_str ()) == LocaleCodeToLcidW (LcidToLocaleCodeW (GetSystemDefaultLCID ()).c_str ())); + } + if (isMatch) + { + LPWSTR lpbuf = (LPWSTR)malloc ((it.second.length () + 1) * sizeof (wchar_t)); + ZeroMemory (lpbuf, (it.second.length () + 1) * sizeof (wchar_t)); + lstrcpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + if (isLanguageMatch (it.first, LcidToLocaleCodeW (GetSystemDefaultLCID ()))) + { + LPWSTR lpbuf = (LPWSTR)malloc ((it.second.length () + 1) * sizeof (wchar_t)); + ZeroMemory (lpbuf, (it.second.length () + 1) * sizeof (wchar_t)); + lstrcpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + if (isLanguageMatch (it.first, L"en-us")) + { + LPWSTR lpbuf = (LPWSTR)malloc ((it.second.length () + 1) * sizeof (wchar_t)); + ZeroMemory (lpbuf, (it.second.length () + 1) * sizeof (wchar_t)); + lstrcpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + if (isLanguageMatch (it.first, L"en")) + { + LPWSTR lpbuf = (LPWSTR)malloc ((it.second.length () + 1) * sizeof (wchar_t)); + ZeroMemory (lpbuf, (it.second.length () + 1) * sizeof (wchar_t)); + lstrcpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : langmap) + { + LPWSTR lpbuf = (LPWSTR)malloc ((it.second.length () + 1) * sizeof (wchar_t)); + ZeroMemory (lpbuf, (it.second.length () + 1) * sizeof (wchar_t)); + lstrcpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + // ݹ + for (pugi::xml_node subtree = subResMap.child ("ResourceMapSubtree"); subtree; subtree = subtree.next_sibling ("ResourceMapSubtree")) + { + LPWSTR result = recFindStringValue (subtree, lpMsName, defaultLocaleCode); + if (result) return result; + } + return NULL; + } + struct ImageFileInfo + { + int scale; + ImageContrast contrast; + size_t hash; + ImageFileInfo (int scale = 100, ImageContrast contrast = ImageContrast::none, size_t hash = 0): + scale (scale), contrast (contrast), hash (hash) {} + bool operator < (const ImageFileInfo &right) const + { + if (scale != right.scale) + return scale < right.scale; + if (contrast != right.contrast) + return contrast < right.contrast; + return hash < right.hash; // ȷֶζ + } + bool operator == (const ImageFileInfo &right) const + { + return this->scale == right.scale && this->contrast == right.contrast && this->hash == right.hash; + } + bool operator != (const ImageFileInfo &right) const { return !(*this == right); } + }; + LPSTR recFindFilePathValue (pugi::xml_node &subResMap, LPCSTR lpMsName, int defaultScale = GetDPI (), ImageContrast defaultContrast = ImageContrast::none) + { + for (pugi::xml_node namedRes = subResMap.child ("NamedResource"); namedRes; namedRes = namedRes.next_sibling ("NamedResource")) + { + bool isMatch = false; + pugi::xml_attribute nameAttr = namedRes.attribute ("name"); + std::string resname = nameAttr.as_string (); + isMatch = LabelEqual (resname, lpMsName); + static const std::regex pattern ("^ms-resource:", std::regex_constants::icase); + if (!isMatch) + { + std::string lpname2 = std::regex_replace (std::string (lpMsName), pattern, ""); + isMatch = LabelEqual (resname, lpname2); + } + if (!isMatch) + { + LPCSTR filename = PathFindFileNameA (lpMsName); + isMatch = LabelEqual (resname, filename); + } + if (!isMatch) + { + pugi::xml_attribute uriAttr = namedRes.attribute ("uri"); + std::string resuri = uriAttr.as_string (); + std::string ptouri = ReplaceBackslash (std::string (lpMsName)); + isMatch = (InStr (resuri, ptouri) >= 0); + } + if (isMatch) + { + std::map imgmap; + for (pugi::xml_node candidate = namedRes.child ("Candidate"); candidate; candidate = candidate.next_sibling ("Candidate")) + { + std::string valueGet = candidate.child ("Value").text ().get (); + for (pugi::xml_node qualifierSet = candidate.child ("QualifierSet"); qualifierSet; qualifierSet = qualifierSet.next_sibling ("QualifierSet")) + { + ImageFileInfo tinfo; + for (pugi::xml_node qualifier = candidate.child ("Qualifier"); qualifier; qualifier = qualifier.next_sibling ("Qualifier")) + { + std::string itemname = qualifier.attribute ("name").as_string (); + if (LabelEqual (itemname, "Contrast")) + { + std::string conText = qualifier.attribute ("value").as_string (); + if (LabelEqual (conText, "BLACK")) tinfo.contrast = ImageContrast::black; + else if (LabelEqual (conText, "WHITE")) tinfo.contrast = ImageContrast::white; + } + else if (LabelEqual (itemname, "Scale")) + { + tinfo.scale = qualifier.attribute ("value").as_int (); + } + } + imgmap [tinfo] = valueGet; + } + } + for (auto it : imgmap) + { + if (defaultContrast == it.first.contrast) + { + if (it.first.scale == defaultScale) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (defaultContrast == it.first.contrast) + { + if (it.first.scale >= defaultScale) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (defaultContrast == it.first.contrast) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::none) + { + if (it.first.scale == defaultScale) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::none) + { + if (it.first.scale >= defaultScale) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::none) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::white) + { + if (it.first.scale == defaultScale) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::white) + { + if (it.first.scale >= defaultScale) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::white) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::black) + { + if (it.first.scale == defaultScale) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::black) + { + if (it.first.scale >= defaultScale) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::black) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : imgmap) + { + LPSTR lpbuf = (LPSTR)calloc (it.second.capacity () + 1, sizeof (char)); + lstrcmpA (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (pugi::xml_node subtree = subResMap.child ("ResourceMapSubtree"); subtree; subtree = subtree.next_sibling ("ResourceMapSubtree")) + { + LPSTR result = recFindFilePathValue (subtree, lpMsName, defaultScale, defaultContrast); + if (result) return result; // ҵͷ + } + return NULL; + } + LPWSTR recFindFilePathValue (pugi::xml_node &subResMap, LPCWSTR lpMsName, int defaultScale = GetDPI (), ImageContrast defaultContrast = ImageContrast::none) + { + for (pugi::xml_node namedRes = subResMap.child ("NamedResource"); namedRes; namedRes = namedRes.next_sibling ("NamedResource")) + { + bool isMatch = false; + pugi::xml_attribute nameAttr = namedRes.attribute ("name"); + std::wstring resname = pugi::as_wide (nameAttr.as_string ()); + isMatch = LabelEqual (resname, lpMsName); + static const std::wregex pattern (L"^ms-resource:", std::regex_constants::icase); + if (!isMatch) + { + std::wstring lpname2 = std::regex_replace (std::wstring (lpMsName), pattern, L""); + isMatch = LabelEqual (resname, lpname2); + } + if (!isMatch) + { + LPCWSTR filename = PathFindFileNameW (lpMsName); + isMatch = LabelEqual (resname, filename); + } + if (!isMatch) + { + pugi::xml_attribute uriAttr = namedRes.attribute ("uri"); + std::wstring resuri = pugi::as_wide (uriAttr.as_string ()); + std::wstring ptouri = ReplaceBackslash (std::wstring (lpMsName)); + isMatch = (InStr (resuri, ptouri) >= 0); + } + if (isMatch) + { + std::map imgmap; + for (pugi::xml_node candidate = namedRes.child ("Candidate"); candidate; candidate = candidate.next_sibling ("Candidate")) + { + std::wstring valueGet (L""); + valueGet += pugi::as_wide (candidate.child ("Value").text ().get ()); + bool isNoAdd = false; + for (pugi::xml_node qualifierSet = candidate.child ("QualifierSet"); qualifierSet; qualifierSet = qualifierSet.next_sibling ("QualifierSet")) + { + ImageFileInfo tinfo; + for (pugi::xml_node qualifier = qualifierSet.child ("Qualifier"); qualifier; qualifier = qualifier.next_sibling ("Qualifier")) + { + std::string itemname = qualifier.attribute ("name").as_string (); + if (LabelEqual (itemname, "Contrast")) + { + std::string conText = qualifier.attribute ("value").as_string (); + if (LabelEqual (conText, "BLACK")) tinfo.contrast = ImageContrast::black; + else if (LabelEqual (conText, "WHITE")) tinfo.contrast = ImageContrast::white; + else if (LabelEqual (conText, "HIGH")) tinfo.contrast = ImageContrast::white; + } + else if (LabelEqual (itemname, "Scale")) + { + tinfo.scale = qualifier.attribute ("value").as_int (); + } + else if (LabelEqual (itemname, "TargetSize")) + { + tinfo.scale = (int)((double)qualifier.attribute ("value").as_int () * 2); + isNoAdd = true; + } + else if (LabelEqual (itemname, "AlternateForm")) + { + std::string alfText = qualifier.attribute ("value").as_string (); + std::hash hasher; + tinfo.hash = hasher (alfText); + } + } + if (!isNoAdd) if (valueGet.length () > 0) imgmap [tinfo] = valueGet; + } + } + for (auto it : imgmap) + { + if (defaultContrast == it.first.contrast) + { + if (it.first.scale == defaultScale) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (defaultContrast == it.first.contrast) + { + if (it.first.scale >= defaultScale) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (defaultContrast == it.first.contrast) + { + if (it.first.scale >= 100) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (defaultContrast == it.first.contrast) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::none) + { + if (it.first.scale == defaultScale) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::none) + { + if (it.first.scale >= defaultScale) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::none) + { + if (it.first.scale >= 100) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::none) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::white) + { + if (it.first.scale == defaultScale) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::white) + { + if (it.first.scale >= defaultScale) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::white) + { + if (it.first.scale >= 100) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::white) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::black) + { + if (it.first.scale == defaultScale) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::black) + { + if (it.first.scale >= defaultScale) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::black) + { + if (it.first.scale >= 100) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (auto it : imgmap) + { + if (it.first.contrast == ImageContrast::black) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + for (auto it : imgmap) + { + LPWSTR lpbuf = (LPWSTR)calloc (it.second.capacity () + 1, sizeof (WCHAR)); + StrCpyW (lpbuf, it.second.c_str ()); + return lpbuf; + } + } + } + for (pugi::xml_node subtree = subResMap.child ("ResourceMapSubtree"); subtree; subtree = subtree.next_sibling ("ResourceMapSubtree")) + { + LPWSTR result = recFindFilePathValue (subtree, lpMsName, defaultScale, defaultContrast); + if (result) return result; // ҵͷ + } + return NULL; + } + public: + PriReader (LPCWSTR lpPriFilePath) { this->create (lpPriFilePath); } + PriReader (const std::wstring objPriFilePath) { this->create (objPriFilePath); } + PriReader (IStream *comISPriFile) { this->create (comISPriFile); } + ~PriReader () { this->destroy (); } + PriReader (): prifile (L""), txmlpath (L"") { xmlreader = nullptr; } + void destroy () + { + if (xmlreader) delete xmlreader; + xmlreader = nullptr; + if (IsFileExists (txmlpath)) DeleteFileW (txmlpath.c_str ()); + txmlpath = L""; + prifile = L""; + } + bool isAvailable () { return xmlreader != nullptr; } + bool create (const std::wstring priFile) + { + destroy (); + if (!PriReader::initMakePri ()) return false; + std::wstring outputXmlFile; + do + { + outputXmlFile = GetUniqueTempFilePathW () + L".xml"; + } while (IsFileExists (outputXmlFile)); + std::wstring quotedMakepri = L"\"" + makepri + L"\""; + std::wstring quotedPriFile = L"\"" + priFile + L"\""; + std::wstring quotedOutputXmlFile = L"\"" + outputXmlFile + L"\""; + // + std::wstring command = quotedMakepri + L" dump /if " + quotedPriFile + L" /of " + quotedOutputXmlFile + L" /dt detailed"; + // ܵڻȡ stdout + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof (SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; // ӽ̼̳о + sa.lpSecurityDescriptor = nullptr; + HANDLE hReadPipe, hWritePipe; + if (!CreatePipe (&hReadPipe, &hWritePipe, &sa, 0)) + { + return false; // ܵʧ + } + STARTUPINFO si = {sizeof (si)}; + PROCESS_INFORMATION pi = {0}; + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdOutput = hWritePipe; // ض׼ + si.hStdError = hWritePipe; // ض + si.hStdInput = NULL; + // ִ + if (CreateProcessW (nullptr, const_cast(command.c_str ()), nullptr, nullptr, TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi)) + { + CloseHandle (hWritePipe); // رдˣֹ ReadFile + std::wstring output; + CHAR buffer [4098]; // ȡ + DWORD bytesRead; + while (ReadFile (hReadPipe, buffer, sizeof (buffer) - 1, &bytesRead, nullptr) && bytesRead > 0) + { + buffer [bytesRead] = '\0'; // ȷַֹ + output += (WCHAR *)buffer; + ZeroMemory (buffer, 4098); + } + // ϢANSI 棩 + // ȴ̽ + WaitForSingleObject (pi.hProcess, INFINITE); + while (ReadFile (hReadPipe, buffer, sizeof (buffer) - 1, &bytesRead, nullptr) && bytesRead > 0) + { + buffer [bytesRead] = '\0'; // ȷַֹ + output += (WCHAR *)buffer; + ZeroMemory (buffer, 4098); + } + CloseHandle (hReadPipe); + std::wstring debugoutput (L""); + debugoutput += L"Command Line:\n" + command + L"\n"; + debugoutput += L"Process Output:\n" + output + L"\n"; + OutputDebugStringW (debugoutput.c_str ()); + // ļǷ + if (IsFileExists (outputXmlFile)) + { + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + } + else + { + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + return false; // ʧ + } + } + else + { + CloseHandle (hReadPipe); + CloseHandle (hWritePipe); + return false; // ̴ʧ + } + txmlpath = outputXmlFile; + xmlreader = new pugi::xml_document (); + if (!xmlreader->load_file (outputXmlFile.c_str ())) + { + this->destroy (); + return false; + } + return true; + } + bool create (LPCWSTR priFile) { destroy (); if (!priFile) return false; return this->create (std::wstring (priFile)); } + bool create (IStream *priFStream) + { + destroy (); + if (!PriReader::initMakePri ()) return false; + if (!priFStream) return false; + std::wstring tempPriFile; + do + { + tempPriFile = GetUniqueTempFilePathW () + L".pri"; + } while (IsFileExists (tempPriFile)); + HRESULT hr = ExtractFileFromStream (priFStream, tempPriFile.c_str ()); + if (FAILED (hr)) + { + if (IsFileExists (tempPriFile)) DeleteFileW (tempPriFile.c_str ()); + return false; + } + bool res = this->create (tempPriFile); + DeleteFileW (tempPriFile.c_str ()); + return res; + } + // ȡָҪ free ֶͷš + LPSTR findStringValue (LPCSTR lpMsName, LPCSTR defaultLocaleCode = LcidToLocaleCodeA (GetUserDefaultLCID ()).c_str ()) + { + pugi::xml_node root = xmlreader->child ("PriInfo"); + if (!root) return NULL; + pugi::xml_node resmap = root.child ("ResourceMap"); + if (!resmap) return NULL; + resmap.child ("ResourceMapSubtree"); + for (pugi::xml_node subtree = resmap.child ("ResourceMapSubtree"); subtree; subtree = subtree.next_sibling ("ResourceMapSubtree")) + { + std::string resMapName = subtree.attribute ("name").as_string (); + if (!LabelEqual (resMapName, "resources")) continue; + LPSTR result = recFindStringValue (subtree, lpMsName, defaultLocaleCode); + if (result) return result; + } + return NULL; + } + // ȡָҪ free ֶͷš + LPWSTR findStringValue (LPCWSTR lpMsName, LPCWSTR defaultLocaleCode = LcidToLocaleCodeW (GetUserDefaultLCID ()).c_str ()) + { + pugi::xml_node root = xmlreader->child ("PriInfo"); + if (!root) return NULL; + pugi::xml_node resmap = root.child ("ResourceMap"); + if (!resmap) return NULL; + for (pugi::xml_node subtree = resmap.child ("ResourceMapSubtree"); subtree; subtree = subtree.next_sibling ("ResourceMapSubtree")) + { + std::string resMapName = subtree.attribute ("name").as_string (); + if (LabelEqual (resMapName, "Files")) continue; + // if (!LabelEqual (resMapName, "resources")) continue; + LPWSTR result = recFindStringValue (subtree, lpMsName, defaultLocaleCode); + if (result && lstrlenW (result) > 0) return result; + } + return NULL; + } + std::string findStringValue (const std::string &objMsName, const std::string &defaultLocaleCode = LcidToLocaleCodeA (GetUserDefaultLCID ())) + { + std::string t (""); + LPSTR lpStr = findStringValue (objMsName.c_str (), defaultLocaleCode.c_str ()); + if (lpStr) t += lpStr; + if (lpStr) free (lpStr); + return t; + } + std::wstring findStringValue (const std::wstring &objMsName, const std::wstring &defaultLocaleCode = LcidToLocaleCodeW (GetUserDefaultLCID ())) + { + std::wstring t (L""); + LPWSTR lpStr = findStringValue (objMsName.c_str (), defaultLocaleCode.c_str ()); + if (lpStr) t += lpStr; + if (lpStr) free (lpStr); + return t; + } + LPSTR findFilePathValue (LPCSTR lpMsName, int defaultScale = GetDPI (), ImageContrast defaultContrast = ImageContrast::none) + { + pugi::xml_node root = xmlreader->child ("PriInfo"); + if (!root) return NULL; + pugi::xml_node resmap = root.child ("ResourceMap"); + if (!resmap) return NULL; + resmap.child ("ResourceMapSubtree"); + for (pugi::xml_node subtree = resmap.child ("ResourceMapSubtree"); subtree; subtree = subtree.next_sibling ("ResourceMapSubtree")) + { + std::string resMapName = subtree.attribute ("name").as_string (); + if (!LabelEqual (resMapName, "Files")) continue; + LPSTR result = recFindFilePathValue (subtree, lpMsName, defaultScale, defaultContrast); + if (result) return result; + } + return NULL; + } + LPWSTR findFilePathValue (LPCWSTR lpMsName, int defaultScale = GetDPI (), ImageContrast defaultContrast = ImageContrast::none) + { + pugi::xml_node root = xmlreader->child ("PriInfo"); + if (!root) return NULL; + pugi::xml_node resmap = root.child ("ResourceMap"); + if (!resmap) return NULL; + resmap.child ("ResourceMapSubtree"); + for (pugi::xml_node subtree = resmap.child ("ResourceMapSubtree"); subtree; subtree = subtree.next_sibling ("ResourceMapSubtree")) + { + std::string resMapName = subtree.attribute ("name").as_string (); + if (!LabelEqual (resMapName, "Files")) continue; + LPWSTR result = recFindFilePathValue (subtree, lpMsName, defaultScale, defaultContrast); + if (result) return result; + } + return NULL; + } + std::string findFilePathValue (const std::string &objMsName, int defaultScale = GetDPI (), ImageContrast defaultContrast = ImageContrast::none) + { + std::string t (""); + LPSTR lpStr = findFilePathValue (objMsName.c_str (), defaultScale, defaultContrast); + if (lpStr) t += lpStr; + if (lpStr) free (lpStr); + return t; + } + std::wstring findFilePathValue (const std::wstring &objMsName, int defaultScale = GetDPI (), ImageContrast defaultContrast = ImageContrast::none) + { + std::wstring t (L""); + LPWSTR lpStr = findFilePathValue (objMsName.c_str (), defaultScale, defaultContrast); + if (lpStr) t += lpStr; + if (lpStr) free (lpStr); + return t; + } +}; +std::wstring PriReader::makepri = L""; + +HPRIREADER CreatePriReader (LPCWSTR priFilePath) +{ + if (!priFilePath) return NULL; + PriReader *ptr = new PriReader (); + bool res = ptr->create (priFilePath); + if (!res) + { + delete ptr; + return NULL; + } + return ptr; +} +HPRIREADER CreatePriReaderFromStream (HISTREAM isPriFile) +{ + if (!isPriFile) return NULL; + PriReader *ptr = new PriReader (); + bool res = ptr->create ((IStream *)isPriFile); + if (!res) + { + delete ptr; + return NULL; + } + return ptr; +} +void DestroyPriReader (HPRIREADER hpr) +{ + if (!hpr) return; + PriReader *ptr = (PriReader *)hpr; + delete hpr; + return; +} +// صַֻܿ϶ǿַȷı뷽ʽΪ ANSI ҲпΪ UTF-8 +// ȡֶַͷţ free () +LPSTR PriReaderFindStringValueA (HPRIREADER hPriReader, LPCSTR lpMsName, LPCSTR lpDefaultLocaleCode) +{ + if (!hPriReader || !lpMsName) return NULL; + PriReader *ptr = (PriReader *)hPriReader; + if (lpDefaultLocaleCode) return ptr->findStringValue (lpMsName, lpDefaultLocaleCode); + else return ptr->findStringValue (lpMsName); +} +LPWSTR PriReaderFindStringValueW (HPRIREADER hPriReader, LPCWSTR lpMsName, LPCWSTR lpDefaultLocaleCode) +{ + if (!hPriReader || !lpMsName) return NULL; + PriReader *ptr = (PriReader *)hPriReader; + if (lpDefaultLocaleCode) return ptr->findStringValue (lpMsName, lpDefaultLocaleCode); + else return ptr->findStringValue (lpMsName); +} +LPSTR PriReaderFindFilePathValueA (HPRIREADER hPriReader, LPCSTR lpMsName, int defaultScale, ImageContrast defaultContrast) +{ + if (!hPriReader || !lpMsName) return NULL; + PriReader *ptr = (PriReader *)hPriReader; + if (defaultScale <= 0) defaultScale = GetDPI (); + if ((int)defaultContrast) defaultContrast = ImageContrast::none; + return ptr->findFilePathValue (lpMsName, defaultScale, defaultContrast); +} +LPWSTR PriReaderFindFilePathValueW (HPRIREADER hPriReader, LPCWSTR lpMsName, int defaultScale, ImageContrast defaultContrast) +{ + if (!hPriReader || !lpMsName) return NULL; + PriReader *ptr = (PriReader *)hPriReader; + if (defaultScale <= 0) defaultScale = GetDPI (); + if ((int)defaultContrast) defaultContrast = ImageContrast::none; + return ptr->findFilePathValue (lpMsName, defaultScale, defaultContrast); +} diff --git a/PriReader2/PriReader2.h b/PriReader2/PriReader2.h new file mode 100644 index 0000000..263a6b4 --- /dev/null +++ b/PriReader2/PriReader2.h @@ -0,0 +1,69 @@ +// ifdef Ǵʹ DLL 򵥵 +// ı׼ DLL еļ϶ PRIREADER2_EXPORTS +// űġʹô DLL +// κĿϲӦ˷šԴļаļκĿὫ +// PRIREADER2_API ΪǴ DLL ģ DLL ô˺궨 +// ΪDZġ +#ifdef PRIREADER2_EXPORTS +#define PRIREADER2_API __declspec(dllexport) +#else +#define PRIREADER2_API __declspec(dllimport) +#endif + +#define class_prireader2 class PRIREADER2_API +#define struct_prireader2 struct PRIREADER2_API +#define enum_prireader2 enum PRIREADER2_API +#define enum_class_prireader2 enum class PRIREADER2_API +#define func_prireader2 PRIREADER2_API +#define func_c_prireader2 extern "C" func_prireader2 + +func_c_prireader2 int GetDPI (); +func_c_prireader2 bool IsDirectoryExistsA (LPCSTR path); +func_c_prireader2 bool IsDirectoryExistsW (LPCWSTR path); + +// ͼʹáʾڸ߶ԱȶӦ +enum_class_prireader2 ImageContrast +{ + none = 0, // ָʾ߶Աȶ + white = 1, // ڸ߶ԱȶȺɫͼƬdzɫ + black = 2, // ڸ߶ԱȶȰɫͼƬɫ + high = 3 // ߶Աȶȣ̫ +}; + +typedef HANDLE HPRIREADER; +typedef HANDLE HISTREAM; // IStream * + +func_c_prireader2 HPRIREADER CreatePriReader (LPCWSTR priFilePath); +func_c_prireader2 HPRIREADER CreatePriReaderFromStream (HISTREAM isPriFile); +func_c_prireader2 void DestroyPriReader (HPRIREADER hpr); +// صַֻܿ϶ǿַȷı뷽ʽΪ ANSI ҲпΪ UTF-8 +// ȡֶַͷţ free () +func_c_prireader2 LPSTR PriReaderFindStringValueA ( + HPRIREADER hPriReader, + LPCSTR lpMsName, + LPCSTR lpDefaultLocaleCode // NULLʹĬԴ +); +// صַֻܿ϶ǿַȷı뷽ʽΪ ANSI ҲпΪ UTF-8 +// ȡֶַͷţ free () +func_c_prireader2 LPWSTR PriReaderFindStringValueW ( + HPRIREADER hPriReader, + LPCWSTR lpMsName, + LPCWSTR lpDefaultLocaleCode // NULLʹĬԴ +); +// صַֻܿ϶ǿַȷı뷽ʽΪ ANSI ҲпΪ UTF-8 +// ȡֶַͷţ free () +func_c_prireader2 LPSTR PriReaderFindFilePathValueA ( + HPRIREADER hPriReader, + LPCSTR lpMsName, + int defaultScale, // NULLʹĬ DPI DPIͨʾΪ 100 + ImageContrast defaultContrast +); +// صַֻܿ϶ǿַȷı뷽ʽΪ ANSI ҲпΪ UTF-8 +// ȡֶַͷţ free () +func_c_prireader2 LPWSTR PriReaderFindFilePathValueW ( + HPRIREADER hPriReader, + LPCWSTR lpMsName, + int defaultScale, // NULLʹĬ DPI DPIͨʾΪ 100 + ImageContrast defaultContrast +); + diff --git a/PriReader2/PriReader2.vcxproj b/PriReader2/PriReader2.vcxproj new file mode 100644 index 0000000..cedcd0a --- /dev/null +++ b/PriReader2/PriReader2.vcxproj @@ -0,0 +1,265 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Release + ARM + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {B897969C-6EA9-4DFC-B7E0-94F1C6D94856} + Win32Proj + PriReader2 + 8.1 + + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + false + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIREADER2_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + Shlwapi.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIREADER2_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + Shlwapi.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;PRIREADER2_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIREADER2_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + + + Windows + true + true + true + Shlwapi.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIREADER2_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + Shlwapi.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;PRIREADER2_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + false + false + + + + + false + + + false + false + + + + + false + + + + + + Create + Create + Create + Create + Create + Create + + + + + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + \ No newline at end of file diff --git a/PriReader2/PriReader2.vcxproj.filters b/PriReader2/PriReader2.vcxproj.filters new file mode 100644 index 0000000..20159b0 --- /dev/null +++ b/PriReader2/PriReader2.vcxproj.filters @@ -0,0 +1,48 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + + \ No newline at end of file diff --git a/PriReader2/ReadMe.txt b/PriReader2/ReadMe.txt new file mode 100644 index 0000000..86c89d4 --- /dev/null +++ b/PriReader2/ReadMe.txt @@ -0,0 +1,30 @@ +======================================================================== + 动态链接库:PriReader2 项目概述 +======================================================================== + +应用程序向导已为您创建了此 PriReader2 DLL。 + +本文件概要介绍组成 PriReader2 应用程序的每个文件的内容。 + + +PriReader2.vcxproj + 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 + +PriReader2.vcxproj.filters + 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 + +PriReader2.cpp + 这是主 DLL 源文件。 + +///////////////////////////////////////////////////////////////////////////// +其他标准文件: + +StdAfx.h, StdAfx.cpp + 这些文件用于生成名为 PriReader2.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 + +///////////////////////////////////////////////////////////////////////////// +其他注释: + +应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 + +///////////////////////////////////////////////////////////////////////////// diff --git a/PriReader2/dllmain.cpp b/PriReader2/dllmain.cpp new file mode 100644 index 0000000..260abc6 --- /dev/null +++ b/PriReader2/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : DLL Ӧóڵ㡣 +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/PriReader2/localeex.h b/PriReader2/localeex.h new file mode 100644 index 0000000..458d6a3 --- /dev/null +++ b/PriReader2/localeex.h @@ -0,0 +1,108 @@ +#pragma once +#include "stdafx.h" + +std::wstring StringToWString (const std::string &str, UINT codePage = CP_ACP) +{ + if (str.empty ()) return std::wstring (); + int len = MultiByteToWideChar (codePage, 0, str.c_str (), -1, nullptr, 0); + if (len == 0) return std::wstring (); + std::wstring wstr (len - 1, L'\0'); + MultiByteToWideChar (codePage, 0, str.c_str (), -1, &wstr [0], len); + return wstr; +} + +std::string GetLocaleInfoA (LCID code, LCTYPE type) +{ + char buf [LOCALE_NAME_MAX_LENGTH] = {0}; + GetLocaleInfoA (code, type, buf, LOCALE_NAME_MAX_LENGTH); + return buf; +} +std::wstring GetLocaleInfoW (LCID code, LCTYPE type) +{ + WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0}; + GetLocaleInfoW (code, type, buf, LOCALE_NAME_MAX_LENGTH); + return buf; +} +int GetLocaleInfoEx (std::wstring lpLocaleName, LCTYPE type, std::wstring &output) +{ + WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0}; + int res = GetLocaleInfoEx (lpLocaleName.c_str (), type, buf, LOCALE_NAME_MAX_LENGTH); + if (&output) output = std::wstring (buf); + return res; +} +BOOL SetLocaleInfoA (LCID code, LCTYPE type, const std::string lcData) +{ + return SetLocaleInfoA (code, type, lcData.c_str ()); +} +BOOL SetLocaleInfoW (LCID code, LCTYPE type, const std::wstring lcData) +{ + return SetLocaleInfoW (code, type, lcData.c_str ()); +} +std::string GetLocaleRestrictedCodeFromLcidA (LCID lcid) +{ + return GetLocaleInfoA (lcid, 89); +} +std::wstring GetLocaleRestrictedCodeFromLcidW (LCID lcid) +{ + return GetLocaleInfoW (lcid, 89); +} +std::string GetLocaleElaboratedCodeFromLcidA (LCID lcid) +{ + return GetLocaleInfoA (lcid, 90); +} +std::wstring GetLocaleElaboratedCodeFromLcidW (LCID lcid) +{ + return GetLocaleInfoW (lcid, 90); +} +LCID LocaleCodeToLcidW (LPCWSTR localeCode) +{ + BYTE buf [LOCALE_NAME_MAX_LENGTH * sizeof (WCHAR)] = {0}; + int res = GetLocaleInfoEx (localeCode, LOCALE_RETURN_NUMBER | LOCALE_ILANGUAGE, (LPWSTR)buf, LOCALE_NAME_MAX_LENGTH); + LCID lcid = *((LCID *)buf); + return lcid; +} +LCID LocaleCodeToLcidA (LPCSTR localeCode) +{ + std::wstring lcWide = StringToWString (std::string (localeCode)); + return LocaleCodeToLcidW (lcWide.c_str ()); +} +std::string GetLocaleRestrictedCodeA (LPCSTR lc) +{ + return GetLocaleInfoA (LocaleCodeToLcidA (lc), 89); +} +std::string GetLocaleRestrictedCodeA (const std::string lc) +{ + return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 89); +} +std::wstring GetLocaleRestrictedCodeW (LPCWSTR lc) +{ + return GetLocaleInfoW (LocaleCodeToLcidW (lc), 89); +} +std::wstring GetLocaleRestrictedCodeW (const std::wstring lc) +{ + return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 89); +} +std::string GetLocaleElaboratedCodeA (LPCSTR lc) +{ + return GetLocaleInfoA (LocaleCodeToLcidA (lc), 90); +} +std::string GetLocaleElaboratedCodeA (const std::string lc) +{ + return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 90); +} +std::wstring GetLocaleElaboratedCodeW (LPCWSTR lc) +{ + return GetLocaleInfoW (LocaleCodeToLcidW (lc), 90); +} +std::wstring GetLocaleElaboratedCodeW (const std::wstring lc) +{ + return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 90); +} +std::string LcidToLocaleCodeA (LCID lcid, char divide = '-') +{ + return GetLocaleRestrictedCodeFromLcidA (lcid) + divide + GetLocaleElaboratedCodeFromLcidA (lcid); +} +std::wstring LcidToLocaleCodeW (LCID lcid, WCHAR divide = L'-') +{ + return GetLocaleRestrictedCodeFromLcidW (lcid) + divide + GetLocaleElaboratedCodeFromLcidW (lcid); +} diff --git a/PriReader2/packages.config b/PriReader2/packages.config new file mode 100644 index 0000000..c2da1c1 --- /dev/null +++ b/PriReader2/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/PriReader2/stdafx.cpp b/PriReader2/stdafx.cpp new file mode 100644 index 0000000..f6667da --- /dev/null +++ b/PriReader2/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : ֻ׼ļԴļ +// PriReader2.pch ΪԤͷ +// stdafx.obj ԤϢ + +#include "stdafx.h" + +// TODO: STDAFX.H κĸͷļ +//ڴļ diff --git a/PriReader2/stdafx.h b/PriReader2/stdafx.h new file mode 100644 index 0000000..b70eab5 --- /dev/null +++ b/PriReader2/stdafx.h @@ -0,0 +1,30 @@ +// stdafx.h : ׼ϵͳļİļ +// Ǿʹõĵ +// ضĿİļ +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Windows ͷųʹõ +// Windows ͷļ: +#include + + + +// TODO: ڴ˴óҪͷļ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; \ No newline at end of file diff --git a/PriReader2/targetver.h b/PriReader2/targetver.h new file mode 100644 index 0000000..416cebf --- /dev/null +++ b/PriReader2/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h õ߰汾 Windows ƽ̨ + +// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h +// _WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h + +#include diff --git a/README.md b/README.md new file mode 100644 index 0000000..26d5ab2 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# AppInstallerForWin8 +A Windows Store App Installer for Windows 8. diff --git a/ShoutcutCreater/AddPackageSample.cpp b/ShoutcutCreater/AddPackageSample.cpp new file mode 100644 index 0000000..0019257 --- /dev/null +++ b/ShoutcutCreater/AddPackageSample.cpp @@ -0,0 +1,34 @@ +//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +//// PARTICULAR PURPOSE. +//// +//// Copyright (c) Microsoft Corporation. All rights reserved + +#include "stdafx.h" +#include "PackageManager.h" +#include +using namespace std; +void callback (unsigned progress) +{ + std::cout << '\r' << progress << "%" << std::ends; +} + +[MTAThread] +int __cdecl main(Platform::Array^ args) +{ + wcout << L"Copyright (c) Microsoft Corporation. All rights reserved." << endl; + wcout << L"Add Package" << endl << endl; + + if (args->Length < 2) + { + wcout << L"Usage: addpkg.exe packageUri" << endl; + return 1; + } + HANDLE completedEvent = nullptr; + int returnValue = 0; + String^ inputPackageUri = args[1]; + cout << endl; + AddPackageFromPath (inputPackageUri->Data (), &callback); + return 0; +} diff --git a/ShoutcutCreater/README.txt b/ShoutcutCreater/README.txt new file mode 100644 index 0000000..09ff1df --- /dev/null +++ b/ShoutcutCreater/README.txt @@ -0,0 +1,39 @@ +Add Package Sample +==================== +This sample demonstrates how to use IPackageManager to install a package. + +Prerequisites +============= +This sample requires Windows 8.1+. +This sample requires Visual Studio 12 Ultimate Developer Preview. +This sample requires the Windows Runtime Software Development Kit. + +Sample Language Implementations +=============================== +C++ + +Files: +====== +AddPackageSample.cpp + +To build the sample using the command prompt: +============================================= + 1. Open the Command Prompt window and navigate to the directory. + 2. Type msbuild AddPackageSample.sln. + + +To build the sample using Visual Studio 12 Ultimate Developer Preview (preferred method): +================================================ + 1. Open File Explorer and navigate to the directory. + 2. Double-click the icon for the .sln (solution) file to open the file in + Visual Studio. + 3. In the Build menu, select Build Solution. The application will be + built in the default \Debug or \Release directory. + + +To Run the sample: +================== + 1. Open a command prompt. + 2. Navigate to the directory containing AddPackageSample.exe + 2. Type AddPackageSample.exe "" at the command line. + For example, AddPackageSample.exe "file://C|/users/testuser/desktop/testpackage.appx" diff --git a/ShoutcutCreater/ShortcutCreater.cpp b/ShoutcutCreater/ShortcutCreater.cpp new file mode 100644 index 0000000..b016ff0 --- /dev/null +++ b/ShoutcutCreater/ShortcutCreater.cpp @@ -0,0 +1,46 @@ +#include "stdafx.h" +#include "Shortcut\tCreater.h" + +HRESULT CreateShortcut (LPCWSTR shortcutPath, LPCWSTR targetPath, LPCWSTR appUserModelID) +{ + HRESULT hr; + IShellLink* psl = nullptr; + IPersistFile* ppf = nullptr; + IPropertyStore* pps = nullptr; + PROPVARIANT pv; + hr = CoInitializeEx (nullptr, COINIT_APARTMENTTHREADED); + if (FAILED (hr)) + return hr; + // Create a ShellLink object + hr = CoCreateInstance (CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl); + if (SUCCEEDED (hr)) + { + // Set the path to the shortcut target + psl->SetPath (targetPath); + // Set the AppUserModelID property for the shortcut + hr = psl->QueryInterface (IID_IPropertyStore, (void**)&pps); + if (SUCCEEDED (hr)) + { + hr = InitPropVariantFromString (appUserModelID, &pv); + if (SUCCEEDED (hr)) + { + hr = pps->SetValue (PKEY_AppUserModel_ID, pv); + if (SUCCEEDED (hr)) + { + hr = pps->Commit (); + } + PropVariantClear (&pv); + } + pps->Release (); + } + // Save the shortcut to disk + hr = psl->QueryInterface (IID_IPersistFile, (void**)&ppf); + if (SUCCEEDED (hr)) + { + hr = ppf->Save (shortcutPath, TRUE); + ppf->Release (); + } + psl->Release (); + } + return hr; +} \ No newline at end of file diff --git a/ShoutcutCreater/ShortcutCreater.h b/ShoutcutCreater/ShortcutCreater.h new file mode 100644 index 0000000..9f39361 --- /dev/null +++ b/ShoutcutCreater/ShortcutCreater.h @@ -0,0 +1,10 @@ +#pragma once +#ifdef SHORTCUT_EXPORTS +#define SHORUTCUT_API __declspec(dllexport) +#else +#define SHORUTCUT_API __declspec(dllimport) +#endif + +#include + +extern "C" SHORUTCUT_API HRESULT CreateShortcut (LPCWSTR shortcutPath, LPCWSTR targetPath, LPCWSTR appUserModelID); diff --git a/ShoutcutCreater/ShortcutCreater.sln b/ShoutcutCreater/ShortcutCreater.sln new file mode 100644 index 0000000..e25c5fe --- /dev/null +++ b/ShoutcutCreater/ShortcutCreater.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutCreater", "ToastNotification.vcxproj", "{E10C6272-B876-4DC6-9E13-7CA646863B50}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|Win32.ActiveCfg = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Debug|Win32.Build.0 = Debug|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|Win32.ActiveCfg = Release|Win32 + {E10C6272-B876-4DC6-9E13-7CA646863B50}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ShoutcutCreater/ToastNotification.vcxproj b/ShoutcutCreater/ToastNotification.vcxproj new file mode 100644 index 0000000..8e22a15 --- /dev/null +++ b/ShoutcutCreater/ToastNotification.vcxproj @@ -0,0 +1,101 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + $(VCTargetsPath11) + 12.0 + + + Win32Proj + {E10C6272-B876-4DC6-9E13-7CA646863B50} + ShortcutCreater + + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + false + v120 + Unicode + + + + + + + + + + + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + + WIN32;_DEBUG;SHORTCUT_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + true + false + /ZW:nostdlib /FUplatform.winmd /FUwindows.winmd %(AdditionalOptions) + Create + + + MachineX86 + true + NotSet + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + true + /ZW:nostdlib /FUplatform.winmd /FUWindows.winmd %(AdditionalOptions) + + + MachineX86 + true + Console + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ShoutcutCreater/stdafx.h b/ShoutcutCreater/stdafx.h new file mode 100644 index 0000000..e8d731e --- /dev/null +++ b/ShoutcutCreater/stdafx.h @@ -0,0 +1,5 @@ +#pragma once +#include +#include +#include +#include diff --git a/ToastNotification/AddPackageSample.cpp b/ToastNotification/AddPackageSample.cpp new file mode 100644 index 0000000..0019257 --- /dev/null +++ b/ToastNotification/AddPackageSample.cpp @@ -0,0 +1,34 @@ +//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +//// PARTICULAR PURPOSE. +//// +//// Copyright (c) Microsoft Corporation. All rights reserved + +#include "stdafx.h" +#include "PackageManager.h" +#include +using namespace std; +void callback (unsigned progress) +{ + std::cout << '\r' << progress << "%" << std::ends; +} + +[MTAThread] +int __cdecl main(Platform::Array^ args) +{ + wcout << L"Copyright (c) Microsoft Corporation. All rights reserved." << endl; + wcout << L"Add Package" << endl << endl; + + if (args->Length < 2) + { + wcout << L"Usage: addpkg.exe packageUri" << endl; + return 1; + } + HANDLE completedEvent = nullptr; + int returnValue = 0; + String^ inputPackageUri = args[1]; + cout << endl; + AddPackageFromPath (inputPackageUri->Data (), &callback); + return 0; +} diff --git a/ToastNotification/README.txt b/ToastNotification/README.txt new file mode 100644 index 0000000..09ff1df --- /dev/null +++ b/ToastNotification/README.txt @@ -0,0 +1,39 @@ +Add Package Sample +==================== +This sample demonstrates how to use IPackageManager to install a package. + +Prerequisites +============= +This sample requires Windows 8.1+. +This sample requires Visual Studio 12 Ultimate Developer Preview. +This sample requires the Windows Runtime Software Development Kit. + +Sample Language Implementations +=============================== +C++ + +Files: +====== +AddPackageSample.cpp + +To build the sample using the command prompt: +============================================= + 1. Open the Command Prompt window and navigate to the directory. + 2. Type msbuild AddPackageSample.sln. + + +To build the sample using Visual Studio 12 Ultimate Developer Preview (preferred method): +================================================ + 1. Open File Explorer and navigate to the directory. + 2. Double-click the icon for the .sln (solution) file to open the file in + Visual Studio. + 3. In the Build menu, select Build Solution. The application will be + built in the default \Debug or \Release directory. + + +To Run the sample: +================== + 1. Open a command prompt. + 2. Navigate to the directory containing AddPackageSample.exe + 2. Type AddPackageSample.exe "" at the command line. + For example, AddPackageSample.exe "file://C|/users/testuser/desktop/testpackage.appx" diff --git a/ToastNotification/ToastNotification.cpp b/ToastNotification/ToastNotification.cpp new file mode 100644 index 0000000..8dfccf6 --- /dev/null +++ b/ToastNotification/ToastNotification.cpp @@ -0,0 +1,226 @@ +#include "stdafx.h" +#include "ToastNotification.h" + +bool SaveIStreamToTempFile (IStream* stream, wchar_t* tempFilePath, size_t pathLen) +{ + wchar_t tempPath [MAX_PATH]; + if (!GetTempPathW (MAX_PATH, tempPath)) return false; + if (!GetTempFileNameW (tempPath, L"TST", 0, tempFilePath)) return false; + std::ofstream outFile (tempFilePath, std::ios::binary); + if (!outFile) return false; + // ȡ IStream + STATSTG stat; + HRESULT hr = stream->Stat (&stat, STATFLAG_NONAME); + if (FAILED (hr)) return false; + LARGE_INTEGER liZero = {}; + stream->Seek (liZero, STREAM_SEEK_SET, nullptr); + ULARGE_INTEGER remaining = stat.cbSize; + BYTE buffer [4096]; + ULONG bytesRead; + while (remaining.QuadPart > 0) + { + hr = stream->Read (buffer, min (sizeof (buffer), remaining.LowPart), &bytesRead); + if (FAILED (hr) || bytesRead == 0) break; + outFile.write ((char*)buffer, bytesRead); + remaining.QuadPart -= bytesRead; + } + return outFile.good (); +} + +// ̰߳ȫɾʱļ +void DeleteFileThreadSafe (wchar_t* filePath) +{ + Sleep (5000); // ȴ֪ͨʾ + DeleteFileW (filePath); +} + +bool CreateToastNotification ( + LPCWSTR identityName, + LPCWSTR title, + LPCWSTR text, + NOTICE_PRESS_CALLBACK callback, + HISTREAM imgFile +) +{ + ComPtr notifier; + ComPtr toast; + ComPtr toastFactory; + ComPtr xmlDoc; + HRESULT hr = RoInitialize (RO_INIT_MULTITHREADED); + if (FAILED (hr) && hr != RPC_E_CHANGED_MODE) return false; + ComPtr toastManager; + hr = RoGetActivationFactory (HStringReference (L"Windows.UI.Notifications.ToastNotificationManager").Get (), + __uuidof(IToastNotificationManagerStatics), + &toastManager); + if (FAILED (hr)) return false; + hr = toastManager->CreateToastNotifierWithId (HStringReference (identityName).Get (), ¬ifier); + if (FAILED (hr)) return false; + hr = RoActivateInstance (HStringReference (L"Windows.Data.Xml.Dom.XmlDocument").Get (), &xmlDoc); + if (FAILED (hr)) return false; + wchar_t xmlTemplateWithImage [] = + L"" + L"" + L"" + L"" + L"%s" + L"%s" + L"" + L"" + L""; + wchar_t xmlTemplateNoImage [] = + L"" + L"" + L"" + L"%s" + L"%s" + L"" + L"" + L""; + wchar_t xmlData [1024]; + wchar_t imagePath [MAX_PATH] = L""; + if (imgFile != NULL) + { + IStream* img = (IStream*)imgFile; + STATSTG stat; + hr = img->Stat (&stat, STATFLAG_DEFAULT); + if (SUCCEEDED (hr) && stat.pwcsName) + { + wcscpy_s (imagePath, stat.pwcsName); + CoTaskMemFree (stat.pwcsName); + } + else + { + if (!SaveIStreamToTempFile (img, imagePath, MAX_PATH)) return false; + wchar_t* tempFileCopy = _wcsdup (imagePath); + if (tempFileCopy) + { + CreateThread (nullptr, 0, (LPTHREAD_START_ROUTINE)DeleteFileThreadSafe, tempFileCopy, 0, nullptr); + } + } + swprintf_s (xmlData, xmlTemplateWithImage, imagePath, title, text); + } + else + { + swprintf_s (xmlData, xmlTemplateNoImage, title, text); + } + ComPtr xmlDocIO; + hr = xmlDoc.As (&xmlDocIO); + if (FAILED (hr)) return false; + hr = xmlDocIO->LoadXml (HStringReference (xmlData).Get ()); + if (FAILED (hr)) return false; + hr = RoGetActivationFactory (HStringReference (L"Windows.UI.Notifications.ToastNotification").Get (), + __uuidof(IToastNotificationFactory), + &toastFactory); + if (FAILED (hr)) return false; + hr = toastFactory->CreateToastNotification (xmlDoc.Get (), &toast); + if (FAILED (hr)) return false; + return SUCCEEDED (notifier->Show (toast.Get ())); +} + +HRESULT CreateShortcutWithAppIdA (LPCSTR pszShortcutPath, LPCSTR pszTargetPath, LPCSTR pszAppId) +{ + HRESULT hr; + // ʼ COM + hr = CoInitialize (NULL); + if (FAILED (hr)) + return hr; + // IShellLink ANSI汾 + IShellLinkA* pShellLinkA = NULL; + hr = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + IID_IShellLinkA, (void**)&pShellLinkA); + if (FAILED (hr)) + { + CoUninitialize (); + return hr; + } + // ÿݷʽĿ· + hr = pShellLinkA->SetPath (pszTargetPath); + if (FAILED (hr)) + { + pShellLinkA->Release (); + CoUninitialize (); + return hr; + } + // AppUserModelID + IPropertyStore* pPropStore = NULL; + hr = pShellLinkA->QueryInterface (IID_IPropertyStore, (void**)&pPropStore); + if (SUCCEEDED (hr)) + { + PROPVARIANT propvar; + hr = InitPropVariantFromString (_bstr_t (pszAppId), &propvar); + if (SUCCEEDED (hr)) + { + // PKEY_AppUserModel_ID propkey.h + hr = pPropStore->SetValue (PKEY_AppUserModel_ID, propvar); + if (SUCCEEDED (hr)) + hr = pPropStore->Commit (); + PropVariantClear (&propvar); + } + pPropStore->Release (); + } + // ݷʽļIPersistFile Ҫַ + IPersistFile* pPersistFile = NULL; + hr = pShellLinkA->QueryInterface (IID_IPersistFile, (void**)&pPersistFile); + if (SUCCEEDED (hr)) + { + // pszShortcutPath ANSI תΪ Unicode + wchar_t wszShortcutPath [MAX_PATH]; + MultiByteToWideChar (CP_ACP, 0, pszShortcutPath, -1, wszShortcutPath, MAX_PATH); + hr = pPersistFile->Save (wszShortcutPath, TRUE); + pPersistFile->Release (); + } + pShellLinkA->Release (); + CoUninitialize (); + return hr; +} + +HRESULT CreateShortcutWithAppIdW (LPCWSTR pszShortcutPath, LPCWSTR pszTargetPath, LPCWSTR pszAppId) +{ + HRESULT hr; + hr = CoInitialize (NULL); + if (FAILED (hr)) + { + return hr; + } + IShellLinkW* pShellLinkW = NULL; + hr = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void**)&pShellLinkW); + if (FAILED (hr)) + { + CoUninitialize (); + return hr; + } + hr = pShellLinkW->SetPath (pszTargetPath); + if (FAILED (hr)) + { + pShellLinkW->Release (); + CoUninitialize (); + return hr; + } + IPropertyStore* pPropStore = NULL; + hr = pShellLinkW->QueryInterface (IID_IPropertyStore, (void**)&pPropStore); + if (SUCCEEDED (hr)) + { + PROPVARIANT propvar; + hr = InitPropVariantFromString (pszAppId, &propvar); + if (SUCCEEDED (hr)) + { + hr = pPropStore->SetValue (PKEY_AppUserModel_ID, propvar); + if (SUCCEEDED (hr)) + { + hr = pPropStore->Commit (); + } + PropVariantClear (&propvar); + } + pPropStore->Release (); + } + IPersistFile* pPersistFile = NULL; + hr = pShellLinkW->QueryInterface (IID_IPersistFile, (void**)&pPersistFile); + if (SUCCEEDED (hr)) + { + hr = pPersistFile->Save (pszShortcutPath, TRUE); + pPersistFile->Release (); + } + pShellLinkW->Release (); + CoUninitialize (); + return hr; +} \ No newline at end of file diff --git a/ToastNotification/ToastNotification.h b/ToastNotification/ToastNotification.h new file mode 100644 index 0000000..0021e69 --- /dev/null +++ b/ToastNotification/ToastNotification.h @@ -0,0 +1,17 @@ +#pragma once +#ifdef TOASTNOTICE_EXPORTS +#define TOASTNOTICE_API __declspec(dllexport) +#else +#define TOASTNOTICE_API __declspec(dllimport) +#endif + +#include + +typedef void (*_NOTICE_PRESS_CALLBACK) (void); +typedef _NOTICE_PRESS_CALLBACK NOTICE_PRESS_CALLBACK; +// ʹ COM IStream * +typedef HANDLE HISTREAM; + +extern "C" TOASTNOTICE_API bool CreateToastNotification (LPCWSTR identityName, LPCWSTR title, LPCWSTR text, NOTICE_PRESS_CALLBACK callback, HISTREAM imgFile); +extern "C" TOASTNOTICE_API HRESULT CreateShortcutWithAppIdA (LPCSTR pszShortcutPath, LPCSTR pszTargetPath, LPCSTR pszAppId); +extern "C" TOASTNOTICE_API HRESULT CreateShortcutWithAppIdW (LPCWSTR pszShortcutPath, LPCWSTR pszTargetPath, LPCWSTR pszAppId); \ No newline at end of file diff --git a/ToastNotification/ToastNotification.sln b/ToastNotification/ToastNotification.sln new file mode 100644 index 0000000..264e1a6 --- /dev/null +++ b/ToastNotification/ToastNotification.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 12 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ToastNotification", "ToastNotification.vcxproj", "{59131AB7-2A7D-9A09-8223-174C3F5E0F57}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Win32.ActiveCfg = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Debug|Win32.Build.0 = Debug|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Win32.ActiveCfg = Release|Win32 + {59131AB7-2A7D-9A09-8223-174C3F5E0F57}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ToastNotification/ToastNotification.vcxproj b/ToastNotification/ToastNotification.vcxproj new file mode 100644 index 0000000..7786d2c --- /dev/null +++ b/ToastNotification/ToastNotification.vcxproj @@ -0,0 +1,170 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Release + ARM + + + Release + Win32 + + + + $(VCTargetsPath11) + 12.0 + + + Win32Proj + {E10C6272-B876-4DC6-9E13-7CA646863B50} + ToastNotification + + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + false + v120 + Unicode + + + DynamicLibrary + false + v120 + Unicode + + + + + + + + + + + + + + + + + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + false + $(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral + + + + WIN32;_DEBUG;TOASTNOTICE_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + true + false + /ZW:nostdlib /FUplatform.winmd /FUwindows.winmd %(AdditionalOptions) + Create + + + MachineX86 + true + NotSet + shlwapi.lib;%(AdditionalDependencies) + + + + + WIN32;_DEBUG;TOASTNOTICE_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + true + false + /ZW:nostdlib /FUplatform.winmd /FUwindows.winmd %(AdditionalOptions) + Create + + + true + NotSet + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + true + /ZW:nostdlib /FUplatform.winmd /FUWindows.winmd %(AdditionalOptions) + + + MachineX86 + true + Console + true + true + shlwapi.lib;%(AdditionalDependencies) + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + true + /ZW:nostdlib /FUplatform.winmd /FUWindows.winmd %(AdditionalOptions) + + + true + Console + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ToastNotification/stdafx.h b/ToastNotification/stdafx.h new file mode 100644 index 0000000..efb81d4 --- /dev/null +++ b/ToastNotification/stdafx.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +using namespace Microsoft::WRL; +using namespace ABI::Windows::UI::Notifications; +using namespace ABI::Windows::Data::Xml::Dom; +using namespace Microsoft::WRL::Wrappers;