mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-11 17:57:19 +10:00
Update the features about Notification and Cert.
This commit is contained in:
@@ -28,6 +28,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "notice", "notice\notice.vcx
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PriFile", "PriFileFormat\PriFile.csproj", "{EF4012D4-EF08-499C-B803-177739350B2D}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PriFile", "PriFileFormat\PriFile.csproj", "{EF4012D4-EF08-499C-B803-177739350B2D}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "certmgr", "certmgr\certmgr.vcxproj", "{E04CCAB9-35DB-495C-A279-5B483C707CD0}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -106,6 +108,16 @@ Global
|
|||||||
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x64.Build.0 = Release|Any CPU
|
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.ActiveCfg = Release|Any CPU
|
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.Build.0 = Release|Any CPU
|
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x64.Build.0 = Release|x64
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
30
certmgr/ReadMe.txt
Normal file
30
certmgr/ReadMe.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
========================================================================
|
||||||
|
动态链接库:certmgr 项目概述
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
应用程序向导已为您创建了此 certmgr DLL。
|
||||||
|
|
||||||
|
本文件概要介绍组成 certmgr 应用程序的每个文件的内容。
|
||||||
|
|
||||||
|
|
||||||
|
certmgr.vcxproj
|
||||||
|
这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
|
||||||
|
|
||||||
|
certmgr.vcxproj.filters
|
||||||
|
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
|
||||||
|
|
||||||
|
certmgr.cpp
|
||||||
|
这是主 DLL 源文件。
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
其他标准文件:
|
||||||
|
|
||||||
|
StdAfx.h, StdAfx.cpp
|
||||||
|
这些文件用于生成名为 certmgr.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
其他注释:
|
||||||
|
|
||||||
|
应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
120
certmgr/certmgr.cpp
Normal file
120
certmgr/certmgr.cpp
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
// certmgr.cpp : 定义 DLL 应用程序的导出函数。
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "certmgr.h"
|
||||||
|
|
||||||
|
struct destruct
|
||||||
|
{
|
||||||
|
std::function <void ()> endtask = nullptr;
|
||||||
|
destruct (std::function <void ()> pfunc): endtask (pfunc) {}
|
||||||
|
~destruct () { if (endtask) endtask (); }
|
||||||
|
};
|
||||||
|
BOOL LoadCertFromCertFile (LPCWSTR lpCertFile)
|
||||||
|
{
|
||||||
|
constexpr LPCWSTR storeNameROOT = L"Root";
|
||||||
|
constexpr LPCWSTR storeNamePublisher = L"TrustedPublisher"; // 添加 TrustedPublisher
|
||||||
|
HCERTSTORE hCertStore = CertOpenStore (
|
||||||
|
CERT_STORE_PROV_SYSTEM,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG,
|
||||||
|
storeNameROOT
|
||||||
|
);
|
||||||
|
destruct relcst ([&] () {
|
||||||
|
if (hCertStore) CertCloseStore (hCertStore, 0);
|
||||||
|
hCertStore = nullptr;
|
||||||
|
});
|
||||||
|
if (!hCertStore) return false;
|
||||||
|
HCERTSTORE hFileCertStore = nullptr;
|
||||||
|
destruct relfcs ([&] () {
|
||||||
|
if (hFileCertStore) CertCloseStore (hFileCertStore, 0);
|
||||||
|
hFileCertStore = nullptr;
|
||||||
|
});
|
||||||
|
PCCERT_CONTEXT pCertContext = nullptr;
|
||||||
|
destruct relcc ([&] () {
|
||||||
|
if (pCertContext) CertFreeCertificateContext (pCertContext);
|
||||||
|
pCertContext = nullptr;
|
||||||
|
});
|
||||||
|
// 使用 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
|
||||||
|
)) return false;
|
||||||
|
// 获取证书上下文
|
||||||
|
pCertContext = CertEnumCertificatesInStore (hFileCertStore, NULL);
|
||||||
|
if (!pCertContext) return false;
|
||||||
|
// 将证书添加到 ROOT 存储
|
||||||
|
if (!CertAddCertificateContextToStore (hCertStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) return false;
|
||||||
|
// 导入到 TrustedPublisher 存储
|
||||||
|
HCERTSTORE hPublisherStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, storeNamePublisher);
|
||||||
|
destruct relps ([&] () {
|
||||||
|
if (hPublisherStore) CertCloseStore (hPublisherStore, 0);
|
||||||
|
hPublisherStore = nullptr;
|
||||||
|
});
|
||||||
|
if (!hPublisherStore) return false;
|
||||||
|
if (!CertAddCertificateContextToStore (hPublisherStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BOOL LoadCertFromSignedFile (LPCWSTR lpSignedFile)
|
||||||
|
{
|
||||||
|
constexpr LPCWSTR storeNameROOT = L"Root";
|
||||||
|
constexpr LPCWSTR storeNamePublisher = L"TrustedPublisher"; // 添加 TrustedPublisher
|
||||||
|
HCERTSTORE hStore = nullptr;
|
||||||
|
destruct relstore ([&] () {
|
||||||
|
if (hStore) CertCloseStore (hStore, 0);
|
||||||
|
hStore = nullptr;
|
||||||
|
});
|
||||||
|
PCCERT_CONTEXT pCertContext = nullptr;
|
||||||
|
destruct relcc ([&] () {
|
||||||
|
if (pCertContext) CertFreeCertificateContext (pCertContext);
|
||||||
|
pCertContext = nullptr;
|
||||||
|
});
|
||||||
|
// 打开已签名的文件并获取证书存储区
|
||||||
|
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) return false;
|
||||||
|
// 打开目标存储区
|
||||||
|
HCERTSTORE hTargetStore = CertOpenStore (
|
||||||
|
CERT_STORE_PROV_SYSTEM,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG,
|
||||||
|
storeNameROOT
|
||||||
|
);
|
||||||
|
destruct relts ([&] () {
|
||||||
|
if (hTargetStore) CertCloseStore (hTargetStore, 0);
|
||||||
|
hTargetStore = nullptr;
|
||||||
|
});
|
||||||
|
if (!hTargetStore) return false;
|
||||||
|
// 导入证书到 ROOT 存储区
|
||||||
|
if (!CertAddCertificateContextToStore (hTargetStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) return false;
|
||||||
|
// 导入到 TrustedPublisher 存储
|
||||||
|
HCERTSTORE hPublisherStore = CertOpenStore (
|
||||||
|
CERT_STORE_PROV_SYSTEM,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG,
|
||||||
|
storeNamePublisher
|
||||||
|
);
|
||||||
|
destruct relps ([&] () {
|
||||||
|
if (hPublisherStore) CertCloseStore (hPublisherStore, 0);
|
||||||
|
hPublisherStore = nullptr;
|
||||||
|
});
|
||||||
|
if (!hPublisherStore) return false;
|
||||||
|
if (!CertAddCertificateContextToStore (hPublisherStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
18
certmgr/certmgr.h
Normal file
18
certmgr/certmgr.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// 下列 ifdef 块是创建使从 DLL 导出更简单的
|
||||||
|
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 CERTMGR_EXPORTS
|
||||||
|
// 符号编译的。在使用此 DLL 的
|
||||||
|
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
|
||||||
|
// CERTMGR_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
|
||||||
|
// 符号视为是被导出的。
|
||||||
|
#ifdef CERTMGR_EXPORTS
|
||||||
|
#define CERTMGR_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define CERTMGR_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 从 CER 文件导入证书到信任区域
|
||||||
|
// 如果返回假(即失败),请从 GetLastError 获取错误代码
|
||||||
|
CERTMGR_API BOOL LoadCertFromCertFile (LPCWSTR lpCertFile);
|
||||||
|
// 从已签名的文件导入证书到信任区域
|
||||||
|
// 如果返回假(即失败),请从 GetLastError 获取错误代码
|
||||||
|
CERTMGR_API BOOL LoadCertFromSignedFile (LPCWSTR lpSignedFile);
|
||||||
180
certmgr/certmgr.vcxproj
Normal file
180
certmgr/certmgr.vcxproj
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{E04CCAB9-35DB-495C-A279-5B483C707CD0}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>certmgr</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CERTMGR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>crypt32.lib;wintrust.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;CERTMGR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CERTMGR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>crypt32.lib;wintrust.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;CERTMGR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Text Include="ReadMe.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="certmgr.h" />
|
||||||
|
<ClInclude Include="stdafx.h" />
|
||||||
|
<ClInclude Include="targetver.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="certmgr.cpp" />
|
||||||
|
<ClCompile Include="dllmain.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
42
certmgr/certmgr.vcxproj.filters
Normal file
42
certmgr/certmgr.vcxproj.filters
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="源文件">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="资源文件">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Text Include="ReadMe.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="stdafx.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="targetver.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="certmgr.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="certmgr.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="dllmain.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
19
certmgr/dllmain.cpp
Normal file
19
certmgr/dllmain.cpp
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
8
certmgr/stdafx.cpp
Normal file
8
certmgr/stdafx.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// stdafx.cpp : 只包括标准包含文件的源文件
|
||||||
|
// certmgr.pch 将作为预编译头
|
||||||
|
// stdafx.obj 将包含预编译类型信息
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
|
||||||
|
//而不是在此文件中引用
|
||||||
20
certmgr/stdafx.h
Normal file
20
certmgr/stdafx.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// stdafx.h : 标准系统包含文件的包含文件,
|
||||||
|
// 或是经常使用但不常更改的
|
||||||
|
// 特定于项目的包含文件
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "targetver.h"
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
|
||||||
|
// Windows 头文件:
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
// TODO: 在此处引用程序需要的其他头文件
|
||||||
|
#include <wincrypt.h>
|
||||||
|
#include <softpub.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include <functional>
|
||||||
8
certmgr/targetver.h
Normal file
8
certmgr/targetver.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
|
||||||
|
|
||||||
|
// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
|
||||||
|
// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
|
||||||
|
|
||||||
|
#include <SDKDDKVer.h>
|
||||||
@@ -10,8 +10,13 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
|||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
|
CoInitializeEx (NULL, COINIT_MULTITHREADED);
|
||||||
|
RoInitialize (RO_INIT_MULTITHREADED);
|
||||||
|
break;
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
|
CoUninitialize ();
|
||||||
|
RoUninitialize ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -6,10 +6,15 @@
|
|||||||
#include "raii.h"
|
#include "raii.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "nstring.h"
|
#include "nstring.h"
|
||||||
|
|
||||||
#ifdef GetFullPathName
|
#ifdef GetFullPathName
|
||||||
#undef GetFullPathName
|
#undef GetFullPathName
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef min
|
||||||
|
#undef min
|
||||||
|
#endif
|
||||||
|
#ifdef max
|
||||||
|
#undef max
|
||||||
|
#endif
|
||||||
std::wstring GetFullPathName (const std::wstring &lpFileName)
|
std::wstring GetFullPathName (const std::wstring &lpFileName)
|
||||||
{
|
{
|
||||||
if (lpFileName.empty ()) return L"";
|
if (lpFileName.empty ()) return L"";
|
||||||
@@ -36,8 +41,29 @@ static std::wstring StringToWString (const std::string &str, UINT codePage = CP_
|
|||||||
MultiByteToWideChar (codePage, 0, str.c_str (), -1, &wstr [0], len);
|
MultiByteToWideChar (codePage, 0, str.c_str (), -1, &wstr [0], len);
|
||||||
return wstr;
|
return wstr;
|
||||||
}
|
}
|
||||||
LPWSTR GetToastNoticeXml (LPCWSTR lpTemplateName)
|
Windows::Data::Xml::Dom::XmlDocument ^TemplateToastNoticeXml (const std::wstring &lpTemplateName)
|
||||||
{
|
{
|
||||||
|
std::wnstring temp = lpTemplateName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using toastttype = Windows::UI::Notifications::ToastTemplateType;
|
||||||
|
auto tttype = Windows::UI::Notifications::ToastTemplateType::ToastImageAndText01;
|
||||||
|
if (temp.equals (L"ToastText01")) tttype = toastttype::ToastText01;
|
||||||
|
else if (temp.equals (L"ToastText02")) tttype = toastttype::ToastText02;
|
||||||
|
else if (temp.equals (L"ToastText03")) tttype = toastttype::ToastText03;
|
||||||
|
else if (temp.equals (L"ToastText04")) tttype = toastttype::ToastText04;
|
||||||
|
else if (temp.equals (L"ToastImageAndText01")) tttype = toastttype::ToastImageAndText01;
|
||||||
|
else if (temp.equals (L"ToastImageAndText02")) tttype = toastttype::ToastImageAndText02;
|
||||||
|
else if (temp.equals (L"ToastImageAndText03")) tttype = toastttype::ToastImageAndText03;
|
||||||
|
else if (temp.equals (L"ToastImageAndText04")) tttype = toastttype::ToastImageAndText04;
|
||||||
|
else tttype = (toastttype)-1;
|
||||||
|
if ((INT16)tttype > 0)
|
||||||
|
{
|
||||||
|
auto tt = Windows::UI::Notifications::ToastNotificationManager::GetTemplateContent (tttype);
|
||||||
|
if (tt) return tt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
auto xmldoc = ref new Windows::Data::Xml::Dom::XmlDocument ();
|
auto xmldoc = ref new Windows::Data::Xml::Dom::XmlDocument ();
|
||||||
auto root = xmldoc->CreateElement ("toast");
|
auto root = xmldoc->CreateElement ("toast");
|
||||||
xmldoc->AppendChild (root);
|
xmldoc->AppendChild (root);
|
||||||
@@ -45,7 +71,6 @@ LPWSTR GetToastNoticeXml (LPCWSTR lpTemplateName)
|
|||||||
root->AppendChild (visual);
|
root->AppendChild (visual);
|
||||||
auto binding = xmldoc->CreateElement ("binding");
|
auto binding = xmldoc->CreateElement ("binding");
|
||||||
visual->AppendChild (binding);
|
visual->AppendChild (binding);
|
||||||
std::wnstring temp = lpTemplateName ? lpTemplateName : L"";
|
|
||||||
if (temp.equals (L"ToastText01"))
|
if (temp.equals (L"ToastText01"))
|
||||||
{
|
{
|
||||||
binding->SetAttribute ("template", "ToastText01");
|
binding->SetAttribute ("template", "ToastText01");
|
||||||
@@ -149,23 +174,21 @@ LPWSTR GetToastNoticeXml (LPCWSTR lpTemplateName)
|
|||||||
auto text1 = xmldoc->CreateElement ("text");
|
auto text1 = xmldoc->CreateElement ("text");
|
||||||
binding->AppendChild (text1);
|
binding->AppendChild (text1);
|
||||||
}
|
}
|
||||||
|
return xmldoc;
|
||||||
|
}
|
||||||
|
LPWSTR GetToastNoticeXml (LPCWSTR lpTemplateName)
|
||||||
|
{
|
||||||
|
auto xmldoc = TemplateToastNoticeXml (lpTemplateName);
|
||||||
return _wcsdup (xmldoc->GetXml ()->Data ());
|
return _wcsdup (xmldoc->GetXml ()->Data ());
|
||||||
}
|
}
|
||||||
LPWSTR GenerateSimpleToastNoticeXml (LPCWSTR lpText, LPCWSTR lpImagePath)
|
Windows::Data::Xml::Dom::XmlDocument ^SimpleToastNoticeXml (const std::wstring &lpText, const std::wstring &lpImgPath = L"")
|
||||||
{
|
{
|
||||||
auto xmldoc = ref new Windows::Data::Xml::Dom::XmlDocument ();
|
Windows::Data::Xml::Dom::XmlDocument ^xmldoc = nullptr;
|
||||||
std::wnstring img = lpImagePath ? lpImagePath : L"";
|
std::wnstring img = lpImgPath;
|
||||||
std::wstring text = std::wnstring::trim (std::wstring (lpText ? lpText : L""));
|
std::wstring text = std::wnstring::trim (std::wstring (lpText));
|
||||||
{
|
{
|
||||||
std::wstring xmltemplate = L"<toast><visual><binding template='ToastGeneric'><text></text></binding></visual></toast>";
|
// std::wstring xmltemplate = L"<toast><visual><binding template='ToastGeneric'><text></text></binding></visual></toast>";
|
||||||
LPWSTR xt = nullptr;
|
xmldoc = TemplateToastNoticeXml (img.empty () ? L"ToastText01" : L"ToastImageAndText01");
|
||||||
raii relt ([&xt] () {
|
|
||||||
if (xt) free (xt);
|
|
||||||
xt = nullptr;
|
|
||||||
});
|
|
||||||
xt = GetToastNoticeXml (img.empty () ? L"ToastText01" : L"ToastImageAndText01");
|
|
||||||
if (xt && *xt) xmltemplate = xt;
|
|
||||||
xmldoc->LoadXml (ref new Platform::String (xmltemplate.c_str ()));
|
|
||||||
}
|
}
|
||||||
Windows::Foundation::Uri ^imguri = nullptr;
|
Windows::Foundation::Uri ^imguri = nullptr;
|
||||||
try { imguri = ref new Windows::Foundation::Uri (ref new Platform::String (img.c_str ())); }
|
try { imguri = ref new Windows::Foundation::Uri (ref new Platform::String (img.c_str ())); }
|
||||||
@@ -173,8 +196,8 @@ LPWSTR GenerateSimpleToastNoticeXml (LPCWSTR lpText, LPCWSTR lpImagePath)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::wstring fullpath = GetFullPathName (lpImagePath ? lpImagePath : L"");
|
std::wstring fullpath = GetFullPathName (lpImgPath);
|
||||||
if (fullpath.empty ()) fullpath = lpImagePath ? lpImagePath : L"";
|
if (fullpath.empty ()) fullpath = lpImgPath;
|
||||||
imguri = ref new Windows::Foundation::Uri (ref new Platform::String (img.c_str ()));
|
imguri = ref new Windows::Foundation::Uri (ref new Platform::String (img.c_str ()));
|
||||||
}
|
}
|
||||||
catch (...) { imguri = nullptr; }
|
catch (...) { imguri = nullptr; }
|
||||||
@@ -199,34 +222,32 @@ LPWSTR GenerateSimpleToastNoticeXml (LPCWSTR lpText, LPCWSTR lpImagePath)
|
|||||||
node->SetAttribute (L"alt", ref new Platform::String (L"image"));
|
node->SetAttribute (L"alt", ref new Platform::String (L"image"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return xmldoc;
|
||||||
|
}
|
||||||
|
LPWSTR GenerateSimpleToastNoticeXml (LPCWSTR lpText, LPCWSTR lpImagePath)
|
||||||
|
{
|
||||||
|
auto xmldoc = SimpleToastNoticeXml (lpText ? lpText : L"", lpImagePath ? lpImagePath : L"");
|
||||||
return _wcsdup (xmldoc->GetXml ()->Data ());
|
return _wcsdup (xmldoc->GetXml ()->Data ());
|
||||||
}
|
}
|
||||||
LPWSTR GenerateSimpleToastNoticeXml2 (LPCWSTR lpTitle, LPCWSTR lpText, LPCWSTR lpImagePath)
|
Windows::Data::Xml::Dom::XmlDocument ^SimpleToastNoticeXml2 (const std::wstring &lpTitle, const std::wstring &lpText = L"", const std::wstring &lpImagePath = L"")
|
||||||
{
|
{
|
||||||
auto xmldoc = ref new Windows::Data::Xml::Dom::XmlDocument ();
|
Windows::Data::Xml::Dom::XmlDocument ^xmldoc = nullptr;
|
||||||
std::wnstring img = lpImagePath ? lpImagePath : L"";
|
std::wnstring img = lpImagePath;
|
||||||
std::wstring title = std::wnstring (lpTitle ? lpTitle : L"").trim ();
|
std::wstring title = std::wnstring (lpTitle).trim ();
|
||||||
std::wstring text = std::wnstring (lpText ? lpText : L"").trim ();
|
std::wstring text = std::wnstring (lpText).trim ();
|
||||||
{
|
{
|
||||||
std::wstring xmltemplate = L"<toast><visual><binding template='ToastGeneric'><text></text></binding></visual></toast>";
|
// std::wstring xmltemplate = L"<toast><visual><binding template='ToastGeneric'><text></text></binding></visual></toast>";
|
||||||
LPWSTR xt = nullptr;
|
|
||||||
raii relt ([&xt] () {
|
|
||||||
if (xt) free (xt);
|
|
||||||
xt = nullptr;
|
|
||||||
});
|
|
||||||
std::wstring templatename = L"";
|
std::wstring templatename = L"";
|
||||||
WORD flag = (bool)(!img.empty ()) << 2 | (bool)title.size () << 1 | (bool)text.size ();
|
WORD flag = (bool)(!img.empty ()) << 2 | (bool)title.size () << 1 | (bool)text.size ();
|
||||||
switch (flag)
|
switch (flag)
|
||||||
{
|
{
|
||||||
case 0b001: templatename = L"ToastText01"; break; // 仅正文
|
case 1: templatename = L"ToastText01"; break; // 仅正文
|
||||||
case 0b011: templatename = L"ToastText02"; break; // 标题 + 正文
|
case 3: templatename = L"ToastText02"; break; // 标题 + 正文
|
||||||
case 0b101: templatename = L"ToastImageAndText01"; break; // 图 + 正文
|
case 5: templatename = L"ToastImageAndText01"; break; // 图 + 正文
|
||||||
case 0b111: templatename = L"ToastImageAndText02"; break; // 图 + 标题 + 正文
|
case 7: templatename = L"ToastImageAndText02"; break; // 图 + 标题 + 正文
|
||||||
default: templatename = L"ToastText01"; break;
|
default: templatename = L"ToastText01"; break;
|
||||||
}
|
}
|
||||||
xt = GetToastNoticeXml (templatename.c_str ());
|
xmldoc = TemplateToastNoticeXml (templatename);
|
||||||
if (xt && *xt) xmltemplate = xt;
|
|
||||||
xmldoc->LoadXml (ref new Platform::String (xmltemplate.c_str ()));
|
|
||||||
}
|
}
|
||||||
Windows::Foundation::Uri ^imguri = nullptr;
|
Windows::Foundation::Uri ^imguri = nullptr;
|
||||||
try { imguri = ref new Windows::Foundation::Uri (ref new Platform::String (img.c_str ())); }
|
try { imguri = ref new Windows::Foundation::Uri (ref new Platform::String (img.c_str ())); }
|
||||||
@@ -234,8 +255,8 @@ LPWSTR GenerateSimpleToastNoticeXml2 (LPCWSTR lpTitle, LPCWSTR lpText, LPCWSTR l
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::wstring fullpath = GetFullPathName (lpImagePath ? lpImagePath : L"");
|
std::wstring fullpath = GetFullPathName (lpImagePath);
|
||||||
if (fullpath.empty ()) fullpath = lpImagePath ? lpImagePath : L"";
|
if (fullpath.empty ()) fullpath = lpImagePath;
|
||||||
imguri = ref new Windows::Foundation::Uri (ref new Platform::String (img.c_str ()));
|
imguri = ref new Windows::Foundation::Uri (ref new Platform::String (img.c_str ()));
|
||||||
}
|
}
|
||||||
catch (...) { imguri = nullptr; }
|
catch (...) { imguri = nullptr; }
|
||||||
@@ -271,6 +292,11 @@ LPWSTR GenerateSimpleToastNoticeXml2 (LPCWSTR lpTitle, LPCWSTR lpText, LPCWSTR l
|
|||||||
node->SetAttribute (L"alt", ref new Platform::String (L"image"));
|
node->SetAttribute (L"alt", ref new Platform::String (L"image"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return xmldoc;
|
||||||
|
}
|
||||||
|
LPWSTR GenerateSimpleToastNoticeXml2 (LPCWSTR lpTitle, LPCWSTR lpText, LPCWSTR lpImagePath)
|
||||||
|
{
|
||||||
|
auto xmldoc = SimpleToastNoticeXml2 (lpTitle ? lpTitle : L"", lpText ? lpText : L"", lpImagePath ? lpImagePath : L"");
|
||||||
return _wcsdup (xmldoc->GetXml ()->Data ());
|
return _wcsdup (xmldoc->GetXml ()->Data ());
|
||||||
}
|
}
|
||||||
// 会实时记录 hResult;
|
// 会实时记录 hResult;
|
||||||
@@ -299,7 +325,7 @@ catch (...) \
|
|||||||
g_lasthr = E_FAIL; \
|
g_lasthr = E_FAIL; \
|
||||||
if (_PHRESULT_Outptr_lphResult_) *(_PHRESULT_Outptr_lphResult_) = g_lasthr; \
|
if (_PHRESULT_Outptr_lphResult_) *(_PHRESULT_Outptr_lphResult_) = g_lasthr; \
|
||||||
}
|
}
|
||||||
HRESULT CreateToastNoticeFromXmlDocument (LPCWSTR lpIdName, LPCWSTR lpXmlString, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg)
|
HRESULT CreateToastNoticeFromXml (const std::wstring &lpIdName, Windows::Data::Xml::Dom::XmlDocument ^pIXml, NOTICE_ACTIVECALLBACK pfCallback = nullptr, void *pCustom = nullptr, LPWSTR *lpExceptMsg = nullptr)
|
||||||
{
|
{
|
||||||
using XmlDoc = Windows::Data::Xml::Dom::XmlDocument;
|
using XmlDoc = Windows::Data::Xml::Dom::XmlDocument;
|
||||||
using ToastNotification = Windows::UI::Notifications::ToastNotification;
|
using ToastNotification = Windows::UI::Notifications::ToastNotification;
|
||||||
@@ -312,10 +338,9 @@ HRESULT CreateToastNoticeFromXmlDocument (LPCWSTR lpIdName, LPCWSTR lpXmlString,
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Windows::UI::Notifications::ToastNotifier ^notifier = nullptr;
|
Windows::UI::Notifications::ToastNotifier ^notifier = nullptr;
|
||||||
if (lpIdName && *lpIdName) notifier = ToastMgr::CreateToastNotifier (ref new String (lpIdName));
|
if (!std::wnstring (lpIdName).empty ()) notifier = ToastMgr::CreateToastNotifier (ref new String (lpIdName.c_str ()));
|
||||||
else notifier = ToastMgr::CreateToastNotifier ();
|
else notifier = ToastMgr::CreateToastNotifier ();
|
||||||
auto xmldoc = ref new XmlDoc ();
|
auto &xmldoc = pIXml;
|
||||||
xmldoc->LoadXml (ref new String (lpXmlString));
|
|
||||||
auto toast = ref new Toast (xmldoc);
|
auto toast = ref new Toast (xmldoc);
|
||||||
toast->Activated += ref new Windows::Foundation::TypedEventHandler <
|
toast->Activated += ref new Windows::Foundation::TypedEventHandler <
|
||||||
Windows::UI::Notifications::ToastNotification ^,
|
Windows::UI::Notifications::ToastNotification ^,
|
||||||
@@ -324,11 +349,208 @@ HRESULT CreateToastNoticeFromXmlDocument (LPCWSTR lpIdName, LPCWSTR lpXmlString,
|
|||||||
if (pfCallback) pfCallback (pCustom);
|
if (pfCallback) pfCallback (pCustom);
|
||||||
});
|
});
|
||||||
notifier->Show (toast);
|
notifier->Show (toast);
|
||||||
return S_OK;
|
return hr = S_OK;
|
||||||
}
|
}
|
||||||
catch_lasterr (&hr, lpExceptMsg);
|
catch_lasterr (&hr, lpExceptMsg);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
HRESULT CreateToastNoticeFromXml (const std::wstring &lpIdName, const std::wstring &lpXmlString, NOTICE_ACTIVECALLBACK pfCallback = nullptr, void *pCustom = nullptr, LPWSTR *lpExceptMsg = nullptr)
|
||||||
|
{
|
||||||
|
using XmlDoc = Windows::Data::Xml::Dom::XmlDocument;
|
||||||
|
using String = Platform::String;
|
||||||
|
using Object = Platform::Object;
|
||||||
|
if (lpExceptMsg) *lpExceptMsg = nullptr;
|
||||||
|
auto &hr = g_lasthr;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto xmldoc = ref new XmlDoc ();
|
||||||
|
xmldoc->LoadXml (ref new String (lpXmlString.c_str ()));
|
||||||
|
return hr = CreateToastNoticeFromXml (lpIdName, xmldoc, pfCallback, pCustom, lpExceptMsg);
|
||||||
|
}
|
||||||
|
catch_lasterr (&hr, lpExceptMsg);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
HRESULT CreateToastNoticeFromXmlDocument (LPCWSTR lpIdName, LPCWSTR lpXmlString, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg)
|
||||||
|
{
|
||||||
|
return CreateToastNoticeFromXml (lpIdName ? lpIdName : L"", lpXmlString ? lpXmlString : L"", pfCallback, pCustom, lpExceptMsg);
|
||||||
|
}
|
||||||
|
HRESULT CreateToastNotice2 (LPCWSTR lpIdName, LPCWSTR lpTitle, LPCWSTR lpText, LPCWSTR lpImgPath, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg)
|
||||||
|
{
|
||||||
|
auto &hr = g_lasthr;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto xmldoc = SimpleToastNoticeXml2 (lpTitle ? lpTitle : L"", lpText ? lpText : L"", lpImgPath ? lpImgPath : L"");
|
||||||
|
return hr = CreateToastNoticeFromXml (lpIdName, xmldoc, pfCallback, pCustom, lpExceptMsg);
|
||||||
|
}
|
||||||
|
catch_lasterr (&hr, lpExceptMsg);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
HRESULT CreateToastNotice (LPCWSTR lpIdName, LPCWSTR lpText, LPCWSTR lpImgPath, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg)
|
||||||
|
{
|
||||||
|
return CreateToastNotice2 (lpIdName, lpText, nullptr, lpImgPath, pfCallback, pCustom, lpExceptMsg);
|
||||||
|
}
|
||||||
|
std::wstring GetRandomText (size_t length = 16, const std::wstring &charset = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
{
|
||||||
|
if (charset.empty ()) return L"";
|
||||||
|
static bool seeded = false;
|
||||||
|
if (!seeded)
|
||||||
|
{
|
||||||
|
std::srand ((unsigned int)(std::time (nullptr) ^ (uintptr_t)&seeded));
|
||||||
|
seeded = true;
|
||||||
|
}
|
||||||
|
std::wstring ret;
|
||||||
|
ret.reserve (length);
|
||||||
|
for (size_t i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
size_t index = (size_t)(std::rand () % charset.size ());
|
||||||
|
ret.push_back (charset [index]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
std::wstring CombinePath (const std::wstring &left, const std::wstring &right)
|
||||||
|
{
|
||||||
|
std::vector <WCHAR> buf (left.capacity () + right.capacity () + 2);
|
||||||
|
PathCombineW (buf.data (), left.c_str (), right.c_str ());
|
||||||
|
return buf.data ();
|
||||||
|
}
|
||||||
|
std::wstring GetRamdomFileName (const std::wstring &directory, const std::wstring &ext = L".tmp", bool retfullpath = true)
|
||||||
|
{
|
||||||
|
std::wnstring name = std::wnstring::trim (GetRandomText (3) + L"-" + GetRandomText (5) + L"-" + GetRandomText (3)) + std::wnstring::trim (ext);
|
||||||
|
std::wnstring path = CombinePath (directory, name);
|
||||||
|
while (GetFileAttributesW (path.c_str ()) != INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
name = GetRandomText (3) + L"-" + GetRandomText (5) + L"-" + GetRandomText (3) + ext;
|
||||||
|
path = CombinePath (directory, name);
|
||||||
|
}
|
||||||
|
if (retfullpath) return path;
|
||||||
|
else return name;
|
||||||
|
}
|
||||||
|
std::wstring GetTempDirectory ()
|
||||||
|
{
|
||||||
|
std::vector <WCHAR> ret (GetTempPathW (0, nullptr) + 2);
|
||||||
|
GetTempPathW (ret.size (), ret.data ());
|
||||||
|
return ret.data ();
|
||||||
|
}
|
||||||
|
std::wstring GetRamdomTempFileName (const std::wstring &ext = L".tmp", bool retfullpath = true)
|
||||||
|
{
|
||||||
|
return GetRamdomFileName (GetTempDirectory (), ext, retfullpath);
|
||||||
|
}
|
||||||
|
std::wstring IStreamToTempFile (IStream *p, const std::wstring &ext = L".tmp")
|
||||||
|
{
|
||||||
|
if (!p) throw ref new Platform::InvalidArgumentException ("IStream is nullptr.");
|
||||||
|
std::wnstring outpath = GetRamdomTempFileName (ext);
|
||||||
|
auto &stream = p;
|
||||||
|
STATSTG stat;
|
||||||
|
HRESULT hr = stream->Stat (&stat, STATFLAG_NONAME);
|
||||||
|
if (FAILED (hr)) throw Platform::Exception::CreateException (hr);
|
||||||
|
LARGE_INTEGER liZero = {};
|
||||||
|
stream->Seek (liZero, STREAM_SEEK_SET, nullptr);
|
||||||
|
HANDLE hFile = CreateFileW (outpath.c_str (), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, nullptr);
|
||||||
|
const size_t bufsize = 4096;
|
||||||
|
BYTE buf [bufsize] = {0};
|
||||||
|
ULONG bytesRead = 0;
|
||||||
|
DWORD bytesWritten = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
hr = stream->Read (buf, bufsize, &bytesRead);
|
||||||
|
if (FAILED (hr)) { CloseHandle (hFile); throw Platform::Exception::CreateException (hr); }
|
||||||
|
if (bytesRead == 0) break;
|
||||||
|
if (!WriteFile (hFile, buf, bytesRead, &bytesWritten, nullptr) || bytesWritten != bytesRead)
|
||||||
|
{
|
||||||
|
CloseHandle (hFile);
|
||||||
|
throw std::runtime_error ("WriteFile failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle (hFile);
|
||||||
|
return outpath;
|
||||||
|
}
|
||||||
|
void DeleteFileThreadSafe (LPWSTR filepath)
|
||||||
|
{
|
||||||
|
raii endt ([&] () {
|
||||||
|
if (filepath) free (filepath);
|
||||||
|
filepath = nullptr;
|
||||||
|
});
|
||||||
|
Sleep (5000);
|
||||||
|
DeleteFileW (filepath);
|
||||||
|
}
|
||||||
|
HRESULT CreateToastNoticeWithIStream2 (LPCWSTR lpIdName, LPCWSTR lpTitle, LPCWSTR lpText, HANDLE pIImgStream, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg)
|
||||||
|
{
|
||||||
|
auto &hr = g_lasthr;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::wnstring imgpath = L"";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pIImgStream)
|
||||||
|
{
|
||||||
|
IStream *img = (IStream *)pIImgStream;
|
||||||
|
LARGE_INTEGER li;
|
||||||
|
li.QuadPart = 0;
|
||||||
|
img->Seek (li, STREAM_SEEK_SET, nullptr);
|
||||||
|
STATSTG stat;
|
||||||
|
hr = img->Stat (&stat, STATFLAG_DEFAULT);
|
||||||
|
if (SUCCEEDED (hr) && stat.pwcsName)
|
||||||
|
{
|
||||||
|
if (stat.pwcsName) imgpath = stat.pwcsName;
|
||||||
|
CoTaskMemFree (stat.pwcsName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imgpath = IStreamToTempFile (img, L".jpg");
|
||||||
|
CreateThread (nullptr, 0, (LPTHREAD_START_ROUTINE)DeleteFileThreadSafe, _wcsdup (imgpath.c_str ()), 0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Windows::Foundation::Uri ^uri = ref new Windows::Foundation::Uri (ref new Platform::String (imgpath.c_str ()));
|
||||||
|
}
|
||||||
|
catch (...) { imgpath = L""; }
|
||||||
|
return hr = CreateToastNotice2 (lpIdName, lpTitle, lpText, imgpath.c_str (), pfCallback, pCustom, lpExceptMsg);
|
||||||
|
}
|
||||||
|
catch_lasterr (&hr, lpExceptMsg);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
HRESULT CreateToastNoticeWithIStream (LPCWSTR lpIdName, LPCWSTR lpText, HANDLE pIImgStream, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg)
|
||||||
|
{
|
||||||
|
return CreateToastNoticeWithIStream2 (lpIdName, lpText, nullptr, pIImgStream, pfCallback, pCustom, lpExceptMsg);
|
||||||
|
}
|
||||||
|
HRESULT NoticeGetLastHResult () { return g_lasthr; }
|
||||||
|
LPCWSTR NoticeGetLastDetailMessage () { return g_lastexc.c_str (); }
|
||||||
|
HRESULT CreateShortcutWithAppIdW (LPCWSTR pszShortcutPath, LPCWSTR pszTargetPath, LPCWSTR pszAppId)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
if (FAILED (hr)) return hr;
|
||||||
|
IShellLinkW *pShellLinkW = nullptr;
|
||||||
|
raii reltask1 ([&] () {
|
||||||
|
if (pShellLinkW) pShellLinkW->Release ();
|
||||||
|
pShellLinkW = nullptr;
|
||||||
|
});
|
||||||
|
hr = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&pShellLinkW);
|
||||||
|
if (FAILED (hr)) return hr;
|
||||||
|
hr = pShellLinkW->SetPath (pszTargetPath); return hr;
|
||||||
|
IPropertyStore *pPropStore = nullptr;
|
||||||
|
raii reltask2 ([&] () {
|
||||||
|
if (pPropStore) pPropStore->Release ();
|
||||||
|
pPropStore = nullptr;
|
||||||
|
});
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else pPropStore = nullptr;
|
||||||
|
IPersistFile *pPersistFile = nullptr;
|
||||||
|
raii reltask3 ([&] () {
|
||||||
|
if (pPersistFile) pPersistFile->Release ();
|
||||||
|
pPersistFile = nullptr;
|
||||||
|
});
|
||||||
|
hr = pShellLinkW->QueryInterface (IID_IPersistFile, (void **)&pPersistFile);
|
||||||
|
if (SUCCEEDED (hr)) hr = pPersistFile->Save (pszShortcutPath, TRUE);
|
||||||
|
else pPersistFile = nullptr;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,7 +50,27 @@ extern "C"
|
|||||||
// pCustom 可以传入自定义内容并在回调中使用
|
// pCustom 可以传入自定义内容并在回调中使用
|
||||||
// lpExceptMsg 返回异常信息。获取到的指针必须由 free 释放。
|
// lpExceptMsg 返回异常信息。获取到的指针必须由 free 释放。
|
||||||
NOTICE_API HRESULT CreateToastNoticeFromXmlDocument (LPCWSTR lpIdName, LPCWSTR lpXmlString, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg);
|
NOTICE_API HRESULT CreateToastNoticeFromXmlDocument (LPCWSTR lpIdName, LPCWSTR lpXmlString, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg);
|
||||||
|
// 创建一个简单的 Toast 通知。仅支持一段文本和一张图片(图片若不需要则设置为 NULL 或空文本)
|
||||||
|
// 一些参数作用与 CreateToastNoticeFromXmlDocument 中的同名参数作用一致。
|
||||||
|
NOTICE_API HRESULT CreateToastNotice (LPCWSTR lpIdName, LPCWSTR lpText, LPCWSTR lpImgPath, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg);
|
||||||
|
// 创建一个简单的 Toast 通知。支持两段文本和一张图片(图片若不需要则设置为 NULL 或空文本)
|
||||||
|
// lpText 可以设置为 NULL 或空文本。此时函数的作用与 CreateToastNotice 一致。
|
||||||
|
// 一些参数作用与 CreateToastNoticeFromXmlDocument 中的同名参数作用一致。
|
||||||
|
NOTICE_API HRESULT CreateToastNotice2 (LPCWSTR lpIdName, LPCWSTR lpTitle, LPCWSTR lpText, LPCWSTR lpImgPath, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg);
|
||||||
|
// 创建一个简单的 Toast 通知。支持两段文本和一张图片(图片是 IStream 流,如果不想设置则置 NULL)
|
||||||
|
// lpText 可以设置为 NULL 或空文本。此时函数的作用与 CreateToastNoticeWithIStream 一致。
|
||||||
|
// 一些参数作用与 CreateToastNoticeFromXmlDocument 中的同名参数作用一致。
|
||||||
|
NOTICE_API HRESULT CreateToastNoticeWithIStream2 (LPCWSTR lpIdName, LPCWSTR lpTitle, LPCWSTR lpText, HANDLE pIImgStream, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg);
|
||||||
|
// 创建一个简单的 Toast 通知。支持两段文本和一张图片(图片是 IStream 流,如果不想设置则置 NULL)
|
||||||
|
// 一些参数作用与 CreateToastNoticeFromXmlDocument 中的同名参数作用一致。
|
||||||
|
NOTICE_API HRESULT CreateToastNoticeWithIStream (LPCWSTR lpIdName, LPCWSTR lpText, HANDLE pIImgStream, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg);
|
||||||
|
// 获取上一次操作的 HReuslt(注意:返回的 HResult 不一定代表错误,因为这是记录每一个步骤的 HResult)
|
||||||
|
NOTICE_API HRESULT NoticeGetLastHResult ();
|
||||||
|
// 获取上一次异常操作的错误信息。(注意:仅在发生异常时才会记录)
|
||||||
|
NOTICE_API LPCWSTR NoticeGetLastDetailMessage ();
|
||||||
|
// 创建快捷方式
|
||||||
|
// (不用安装程序原生的创建,因为需要 AppUserID 才能使用 Toast 通知,当然这个限制只有 Windows 8.x 有,Windows 10 没有这个限制了)
|
||||||
|
NOTICE_API HRESULT CreateShortcutWithAppIdW (LPCWSTR pszShortcutPath, LPCWSTR pszTargetPath, LPCWSTR pszAppId);
|
||||||
#ifdef _DEFAULT_INIT_VALUE_
|
#ifdef _DEFAULT_INIT_VALUE_
|
||||||
#undef _DEFAULT_INIT_VALUE_
|
#undef _DEFAULT_INIT_VALUE_
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
BIN
notice/notice.rc
Normal file
BIN
notice/notice.rc
Normal file
Binary file not shown.
@@ -41,10 +41,10 @@
|
|||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ReferencePath>$(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral;$(ReferencePath)</ReferencePath>
|
<ReferencePath>$(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral;$(VSSDK140Install)..\VC\atlmfc\lib;$(ReferencePath)</ReferencePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ReferencePath>$(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral;$(ReferencePath)</ReferencePath>
|
<ReferencePath>$(VCINSTALLDIR)\vcpackages;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;$(WindowsSdkDir)\References\CommonConfiguration\Neutral;$(VSSDK140Install)..\VC\atlmfc\lib;$(ReferencePath)</ReferencePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- 关键:启用 WinRT 扩展 -->
|
<!-- 关键:启用 WinRT 扩展 -->
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
@@ -61,6 +61,7 @@
|
|||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||||
|
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -79,9 +80,11 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="dllmain.cpp" />
|
||||||
<ClCompile Include="notice.cpp" />
|
<ClCompile Include="notice.cpp" />
|
||||||
<ClCompile Include="stdafx.cpp" />
|
<ClCompile Include="stdafx.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -89,9 +92,13 @@
|
|||||||
<ClInclude Include="notice.h" />
|
<ClInclude Include="notice.h" />
|
||||||
<ClInclude Include="nstring.h" />
|
<ClInclude Include="nstring.h" />
|
||||||
<ClInclude Include="raii.h" />
|
<ClInclude Include="raii.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
<ClInclude Include="targetver.h" />
|
<ClInclude Include="targetver.h" />
|
||||||
<ClInclude Include="version.h" />
|
<ClInclude Include="version.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="notice.rc" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
@@ -21,6 +21,9 @@
|
|||||||
<ClCompile Include="notice.cpp">
|
<ClCompile Include="notice.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="dllmain.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="stdafx.h">
|
<ClInclude Include="stdafx.h">
|
||||||
@@ -41,5 +44,13 @@
|
|||||||
<ClInclude Include="nstring.h">
|
<ClInclude Include="nstring.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="resource.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="notice.rc">
|
||||||
|
<Filter>资源文件</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -347,73 +347,73 @@ namespace std
|
|||||||
{
|
{
|
||||||
bool default_upper = false, default_include_blank_in_str = false;
|
bool default_upper = false, default_include_blank_in_str = false;
|
||||||
public:
|
public:
|
||||||
using base = std::basic_string <ct, tr, al>;
|
using Base = std::basic_string <ct, tr, al>;
|
||||||
using derive = std::basic_nstring <ct, tr, al>;
|
using derive = std::basic_nstring <ct, tr, al>;
|
||||||
using typename base::size_type;
|
using typename Base::size_type;
|
||||||
using typename base::value_type;
|
using typename Base::value_type;
|
||||||
using base::base;
|
// using Base::Base;
|
||||||
basic_nstring (): base (), default_upper (false), default_include_blank_in_str (false) {}
|
basic_nstring (): Base (), default_upper (false), default_include_blank_in_str (false) {}
|
||||||
basic_nstring (const ct *pStr): base (pStr), default_upper (false), default_include_blank_in_str (false) {}
|
basic_nstring (const ct *pStr): Base (pStr), default_upper (false), default_include_blank_in_str (false) {}
|
||||||
basic_nstring (const base &str): base (str) {}
|
basic_nstring (const Base &str): Base (str) {}
|
||||||
basic_nstring (base &&str): base (std::move (str)) {}
|
basic_nstring (Base &&str): Base (std::move (str)) {}
|
||||||
basic_nstring (const ct *data, size_type count): base (data, count), default_upper (false), default_include_blank_in_str (false) {}
|
basic_nstring (const ct *data, size_type count): Base (data, count), default_upper (false), default_include_blank_in_str (false) {}
|
||||||
template <std::size_t N> basic_nstring (const ct (&arr) [N]) : base (arr, N) {}
|
template <std::size_t N> basic_nstring (const ct (&arr) [N]) : Base (arr, N) {}
|
||||||
template <typename InputIt> basic_nstring (InputIt first, InputIt last): base (first, last), default_upper (false), default_include_blank_in_str (false) {}
|
template <typename InputIt> basic_nstring (InputIt first, InputIt last): Base (first, last), default_upper (false), default_include_blank_in_str (false) {}
|
||||||
bool upper_default () const { return this->default_upper; }
|
bool upper_default () const { return this->default_upper; }
|
||||||
bool upper_default (bool value) { return this->default_upper = value; }
|
bool upper_default (bool value) { return this->default_upper = value; }
|
||||||
bool include_blank_in_str_middle () const { return this->default_include_blank_in_str; }
|
bool include_blank_in_str_middle () const { return this->default_include_blank_in_str; }
|
||||||
bool include_blank_in_str_middle (bool value) { return this->default_include_blank_in_str = value; }
|
bool include_blank_in_str_middle (bool value) { return this->default_include_blank_in_str = value; }
|
||||||
base normalize (bool upper, bool includemidblank) const
|
Base normalize (bool upper, bool includemidblank) const
|
||||||
{
|
{
|
||||||
return NormalizeString <ct, tr, al> (*this, upper, includemidblank);
|
return NormalizeString <ct, tr, al> (*this, upper, includemidblank);
|
||||||
}
|
}
|
||||||
base normalize (bool upper) const
|
Base normalize (bool upper) const
|
||||||
{
|
{
|
||||||
return this->normalize (upper, default_include_blank_in_str);
|
return this->normalize (upper, default_include_blank_in_str);
|
||||||
}
|
}
|
||||||
base normalize () const { return this->normalize (default_upper); }
|
Base normalize () const { return this->normalize (default_upper); }
|
||||||
base upper (bool includemidblank) const
|
Base upper (bool includemidblank) const
|
||||||
{
|
{
|
||||||
return NormalizeString <ct, tr, al> (*this, true, includemidblank);
|
return NormalizeString <ct, tr, al> (*this, true, includemidblank);
|
||||||
}
|
}
|
||||||
base upper () const { return this->upper (default_include_blank_in_str); }
|
Base upper () const { return this->upper (default_include_blank_in_str); }
|
||||||
base lower (bool includemidblank) const
|
Base lower (bool includemidblank) const
|
||||||
{
|
{
|
||||||
return NormalizeString <ct, tr, al> (*this, false, includemidblank);
|
return NormalizeString <ct, tr, al> (*this, false, includemidblank);
|
||||||
}
|
}
|
||||||
base lower () const { return this->lower (default_include_blank_in_str); }
|
Base lower () const { return this->lower (default_include_blank_in_str); }
|
||||||
base trim (bool includemidblank) const
|
Base trim (bool includemidblank) const
|
||||||
{
|
{
|
||||||
return StringTrim <ct, tr, al> (*this, includemidblank);
|
return StringTrim <ct, tr, al> (*this, includemidblank);
|
||||||
}
|
}
|
||||||
base trim () const { return this->trim (default_include_blank_in_str); }
|
Base trim () const { return this->trim (default_include_blank_in_str); }
|
||||||
size_t length (bool includemidblank) const { return GetNormalizeStringLength (*this, includemidblank); }
|
size_t length (bool includemidblank) const { return GetNormalizeStringLength (*this, includemidblank); }
|
||||||
size_t length () const { return length (default_include_blank_in_str); }
|
size_t length () const { return length (default_include_blank_in_str); }
|
||||||
bool empty () const
|
bool empty () const
|
||||||
{
|
{
|
||||||
return IsNormalizeStringEmpty (*this);
|
return IsNormalizeStringEmpty (*this);
|
||||||
}
|
}
|
||||||
bool equals (const base &another, bool includemidblank) const
|
bool equals (const Base &another, bool includemidblank) const
|
||||||
{
|
{
|
||||||
return IsNormalizeStringEquals <ct, tr, al> (*this, another, includemidblank);
|
return IsNormalizeStringEquals <ct, tr, al> (*this, another, includemidblank);
|
||||||
}
|
}
|
||||||
bool equals (const base &another) const { return equals (another, default_include_blank_in_str); }
|
bool equals (const Base &another) const { return equals (another, default_include_blank_in_str); }
|
||||||
int64_t compare (const base &another, bool includemidblank) const
|
int64_t compare (const Base &another, bool includemidblank) const
|
||||||
{
|
{
|
||||||
return NormalizeStringCompare <ct, tr, al> (*this, another, includemidblank);
|
return NormalizeStringCompare <ct, tr, al> (*this, another, includemidblank);
|
||||||
}
|
}
|
||||||
int64_t compare (const base &another) const { return compare (another, default_include_blank_in_str); }
|
int64_t compare (const Base &another) const { return compare (another, default_include_blank_in_str); }
|
||||||
base &string () { return *this; }
|
Base &string () { return *this; }
|
||||||
base to_string (bool upper, bool includemidblank) const { return this->normalize (upper, includemidblank); }
|
Base to_string (bool upper, bool includemidblank) const { return this->normalize (upper, includemidblank); }
|
||||||
base to_string (bool upper) const { return this->normalize (upper, default_include_blank_in_str); }
|
Base to_string (bool upper) const { return this->normalize (upper, default_include_blank_in_str); }
|
||||||
base to_string () const { return this->normalize (default_upper); }
|
Base to_string () const { return this->normalize (default_upper); }
|
||||||
bool operator == (const base &other) const { return equals (other, false); }
|
bool operator == (const Base &other) const { return equals (other, false); }
|
||||||
bool operator != (const base &other) const { return !equals (other, false); }
|
bool operator != (const Base &other) const { return !equals (other, false); }
|
||||||
bool operator < (const base &other) const { return compare (other, false) < 0; }
|
bool operator < (const Base &other) const { return compare (other, false) < 0; }
|
||||||
bool operator > (const base &other) const { return compare (other, false) > 0; }
|
bool operator > (const Base &other) const { return compare (other, false) > 0; }
|
||||||
bool operator <= (const base &other) const { return compare (other, false) <= 0; }
|
bool operator <= (const Base &other) const { return compare (other, false) <= 0; }
|
||||||
bool operator >= (const base &other) const { return compare (other, false) >= 0; }
|
bool operator >= (const Base &other) const { return compare (other, false) >= 0; }
|
||||||
int64_t operator - (const base &other) const { return compare (other, false); }
|
int64_t operator - (const Base &other) const { return compare (other, false); }
|
||||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||||
static bool equals (const std::basic_string <E> &l, const std::basic_string <E> &r, bool remove_mid_blank = false)
|
static bool equals (const std::basic_string <E> &l, const std::basic_string <E> &r, bool remove_mid_blank = false)
|
||||||
{
|
{
|
||||||
|
|||||||
14
notice/resource.h
Normal file
14
notice/resource.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by notice.rc
|
||||||
|
|
||||||
|
// 新对象的下一组默认值
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -28,6 +28,10 @@
|
|||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <propkey.h>
|
#include <propkey.h>
|
||||||
#include <comdef.h>
|
#include <comdef.h>
|
||||||
|
#include <string>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <random>
|
||||||
#using <Windows.winmd>
|
#using <Windows.winmd>
|
||||||
using namespace Microsoft::WRL;
|
using namespace Microsoft::WRL;
|
||||||
using namespace ABI::Windows::UI::Notifications;
|
using namespace ABI::Windows::UI::Notifications;
|
||||||
|
|||||||
@@ -10,8 +10,13 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
|||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
|
CoInitializeEx (NULL, COINIT_MULTITHREADED | COINIT_APARTMENTTHREADED);
|
||||||
|
RoInitialize (RO_INIT_MULTITHREADED);
|
||||||
|
break;
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
|
CoUninitialize ();
|
||||||
|
RoUninitialize ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -628,4 +628,30 @@ HRESULT FindAppxPackage (LPCWSTR lpPackageFullName, PKGMGR_FINDENUMCALLBACK pfCa
|
|||||||
[STAThread]
|
[STAThread]
|
||||||
LPCWSTR GetPackageManagerLastErrorCode () { return g_swExceptionCode.c_str (); }
|
LPCWSTR GetPackageManagerLastErrorCode () { return g_swExceptionCode.c_str (); }
|
||||||
[STAThread]
|
[STAThread]
|
||||||
LPCWSTR GetPackageManagerLastErrorDetailMessage () { return g_swExceptionDetail.c_str (); }
|
LPCWSTR GetPackageManagerLastErrorDetailMessage () { return g_swExceptionDetail.c_str (); }
|
||||||
|
|
||||||
|
HRESULT ActivateAppxApplication (LPCWSTR lpAppUserId, PDWORD pdwProcessId)
|
||||||
|
{
|
||||||
|
if (!lpAppUserId) return E_INVALIDARG;
|
||||||
|
std::wstring strAppUserModelId (L"");
|
||||||
|
if (lpAppUserId) strAppUserModelId += lpAppUserId;
|
||||||
|
IApplicationActivationManager *spAppActivationManager = nullptr;
|
||||||
|
destruct relaamgr ([&] () {
|
||||||
|
if (spAppActivationManager) spAppActivationManager->Release ();
|
||||||
|
spAppActivationManager = nullptr;
|
||||||
|
});
|
||||||
|
HRESULT hResult = E_INVALIDARG;
|
||||||
|
if (!strAppUserModelId.empty ())
|
||||||
|
{
|
||||||
|
// Instantiate IApplicationActivationManager
|
||||||
|
hResult = CoCreateInstance (CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, IID_IApplicationActivationManager, (LPVOID *)&spAppActivationManager);
|
||||||
|
if (SUCCEEDED (hResult))
|
||||||
|
{
|
||||||
|
// This call ensures that the app is launched as the foreground window
|
||||||
|
hResult = CoAllowSetForegroundWindow (spAppActivationManager, NULL);
|
||||||
|
// Launch the app
|
||||||
|
if (SUCCEEDED (hResult)) hResult = spAppActivationManager->ActivateApplication (strAppUserModelId.c_str (), NULL, AO_NONE, pdwProcessId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hResult;
|
||||||
|
}
|
||||||
@@ -181,6 +181,8 @@ extern "C"
|
|||||||
PKGMGR_API LPCWSTR GetPackageManagerLastErrorCode ();
|
PKGMGR_API LPCWSTR GetPackageManagerLastErrorCode ();
|
||||||
// 获取错误详细信息。这个是常用的
|
// 获取错误详细信息。这个是常用的
|
||||||
PKGMGR_API LPCWSTR GetPackageManagerLastErrorDetailMessage ();
|
PKGMGR_API LPCWSTR GetPackageManagerLastErrorDetailMessage ();
|
||||||
|
// 启动 Metro UI 应用
|
||||||
|
PKGMGR_API HRESULT ActivateAppxApplication (LPCWSTR lpAppUserId, PDWORD pdwProcessId);
|
||||||
#ifdef _DEFAULT_INIT_VALUE_
|
#ifdef _DEFAULT_INIT_VALUE_
|
||||||
#undef _DEFAULT_INIT_VALUE_
|
#undef _DEFAULT_INIT_VALUE_
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -82,6 +82,7 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="dllmain.cpp" />
|
||||||
<ClCompile Include="pkgmgr.cpp" />
|
<ClCompile Include="pkgmgr.cpp" />
|
||||||
<ClCompile Include="stdafx.cpp" />
|
<ClCompile Include="stdafx.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="dllmain.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pkgmgr.h">
|
<ClInclude Include="pkgmgr.h">
|
||||||
|
|||||||
@@ -27,4 +27,7 @@ using namespace Windows::Management::Deployment;
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <collection.h>
|
#include <collection.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <shobjidl.h>
|
||||||
Reference in New Issue
Block a user