// 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 PKGMGR_EXPORTS // 符号编译的。在使用此 DLL 的 // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将 // PKGMGR_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的 // 符号视为是被导出的。 #ifdef PKGMGR_EXPORTS #define PKGMGR_API __declspec(dllexport) #else #define PKGMGR_API __declspec(dllimport) #endif // 这里的 API 常用“Appx”在函数名中,此举是为了防止与其他类似的函数名混淆。 #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus #define _DEFAULT_INIT_VALUE_(_init_value_) = _init_value_ #ifndef PKGMGR_EXPORTS #define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_) = _init_value_ #else #define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_) #endif #else #define _DEFAULT_INIT_VALUE_(_init_value_) #define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_) #endif // 进度回调。pCustom 可以传入自定义内容 typedef void (*PKGMRR_PROGRESSCALLBACK) (DWORD dwProgress, void *pCustom); #define PKGMGR_RESULT_OK S_OK #define PKGMGR_RESULT_ERROR E_FAIL #define PKGMGR_RESULT_CANCEL E_ABORT #define PKGMGR_RESULT_STARTED E_PENDING typedef struct _REGISTER_PACKAGE_DEFENDENCIES { DWORD dwSize _DEFAULT_INIT_VALUE_ (0); LPWSTR alpDepUris [1]; } REGISTER_PACKAGE_DEFENDENCIES, *PREGISTER_PACKAGE_DEFENDENCIES; typedef const REGISTER_PACKAGE_DEFENDENCIES CREGISTER_PACKAGE_DEFENDENCIES, *PCREGISTER_PACKAGE_DEFENDENCIES; // 下面值与 Windows::Management::Deployment::DeploymentOptions 一一对应。由于需要写成 API,所以 // 只能如此。 // 可查阅文档 https://learn.microsoft.com/zh-cn/uwp/api/windows.management.deployment.deploymentoptions?view=winrt-26100 // 如果当前正在使用此包或依赖于此包的任何包,则会强制关闭与该包关联的进程,以便可以继续注册。 #define DEPOLYOPTION_FORCE_APP_SHUTDOWN 0x00000001 // 设置此选项时,应用将在开发模式下安装。 有关开发模式的信息,请参阅 备注。 // 使用此选项可启用关键应用开发方案。不能将此选项与捆绑包结合使用。 // 如果将此选项与捆绑包一起使用,调用将返回ERROR_INSTALL_FAILED。 #define DEPOLYOPTION_DEVELOPMENT_MODE 0x00000002 // 设置此选项时,将指示应用跳过资源适用性检查。 这会有效地暂存或注册用户传递给 命令的所有资源包, // 这会强制对捆绑包中包含的所有包具有适用性。 如果用户传入捆绑包,则将注册所有包含的资源包。 // 仅限 Windows。 #define DEPOLYOPTION_INSTALL_ALL_RESOURCES 0x00000020 // 使用默认行为。 #define DEPOLYOPTION_NONE 0x00000000 // 发现拼写错了,只能将错就错(反正 IDE 不会给宏注释): #define DEPLOYOPTION_FORCE_APP_SHUTDOWN DEPOLYOPTION_FORCE_APP_SHUTDOWN #define DEPLOYOPTION_DEVELOPMENT_MODE DEPOLYOPTION_DEVELOPMENT_MODE #define DEPLOYOPTION_INSTALL_ALL_RESOURCES DEPOLYOPTION_INSTALL_ALL_RESOURCES #define DEPLOYOPTION_NONE DEPOLYOPTION_NONE // 安装一个 Appx/AppxBundle/Msix/MsixBundle 包 // 注意:传入的文件路径为 DOS/NT 风格。如:C:\Windows\... // 该函数类似于 PowerShell 的 Add-AppxPackage // dwDeployOption 接受 DEPOLYOPTION_* 常量 // 输出的错误信息别忘了用 PackageManagerFreeString 释放 PKGMGR_API HRESULT AddAppxPackageFromPath (LPCWSTR lpPkgPath, PCREGISTER_PACKAGE_DEFENDENCIES alpDepUrlList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPLOYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 安装一个 Appx/AppxBundle/Msix/MsixBundle 包 // 注意:传入的文件路径为 URI。 // 该函数类似于 PowerShell 的 Add-AppxPackage // dwDeployOption 接受 DEPOLYOPTION_* 常量 // 输出的错误信息别忘了用 PackageManagerFreeString 释放 PKGMGR_API HRESULT AddAppxPackageFromURI (LPCWSTR lpFileUri, PCREGISTER_PACKAGE_DEFENDENCIES alpDepFullNameList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPLOYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); typedef struct _FIND_PACKAGE_ID { UINT64 qwVersion _DEFAULT_INIT_VALUE_ (0); // x86: 0 // x64: 9 // Arm: 5 // Neutral: 11 // Arm64: 12 // Unknown: 65535(-1) WORD wProcessArchitecture _DEFAULT_INIT_VALUE_ ((WORD)-1); WORD wPadding [3]; LPCWSTR lpName _DEFAULT_INIT_VALUE_ (NULL); LPCWSTR lpFullName _DEFAULT_INIT_VALUE_ (NULL); LPCWSTR lpFamilyName _DEFAULT_INIT_VALUE_ (NULL); LPCWSTR lpPublisher _DEFAULT_INIT_VALUE_ (NULL); LPCWSTR lpPublisherId _DEFAULT_INIT_VALUE_ (NULL); LPCWSTR lpResourceId _DEFAULT_INIT_VALUE_ (NULL); } FIND_PACKAGE_ID, *PFIND_PACKAGE_ID; typedef struct _FIND_PACKAGE_PROPERTIES { LPCWSTR lpDisplayName _DEFAULT_INIT_VALUE_ (NULL); LPCWSTR lpDescription _DEFAULT_INIT_VALUE_ (NULL); LPCWSTR lpPublisher _DEFAULT_INIT_VALUE_ (NULL); LPCWSTR lpLogoUri _DEFAULT_INIT_VALUE_ (NULL); BOOL bIsFramework _DEFAULT_INIT_VALUE_ (FALSE); BOOL bIsResourcePackage _DEFAULT_INIT_VALUE_ (FALSE); BOOL bIsBundle _DEFAULT_INIT_VALUE_ (FALSE); BOOL bIsDevelopmentMode _DEFAULT_INIT_VALUE_ (FALSE); } FIND_PACKAGE_PROPERTIES, *PFIND_PACKAGE_PROPERTIES; typedef struct _FIND_PACKAGE_INFO { FIND_PACKAGE_ID piIdentity; FIND_PACKAGE_PROPERTIES piProperties; LPCWSTR lpInstallLocation _DEFAULT_INIT_VALUE_ (NULL); // 多个用户由 ";" 分隔 LPCWSTR lpUsers _DEFAULT_INIT_VALUE_ (NULL); // 多个用户由 ";" 分隔 LPCWSTR lpSIDs _DEFAULT_INIT_VALUE_ (NULL); DWORD dwDependencesSize _DEFAULT_INIT_VALUE_ (0); // 这个项无意义,仅用于内存对齐 DWORD dwPadding _DEFAULT_INIT_VALUE_ (0); // 这个项无意义,除非之后我想通过动态内存方式写依赖项的数组。 UINT64 ullBuffer _DEFAULT_INIT_VALUE_ (0); } FIND_PACKAGE_INFO, *PFIND_PACKAGE_INFO; typedef const FIND_PACKAGE_INFO CFIND_PACKAGE_INFO, *LPCFIND_PACKAGE_INFO; // 注:回调时的指针不要手动释放 typedef void (*PKGMGR_FINDENUMCALLBACK) (LPCFIND_PACKAGE_INFO pNowItem, void *pCustom); // 通过回调来获取所有包的信息。回调函数允许传自定义内容。返回的值可以判断是否成功。 // 该函数类似于 PowerShell 的 Get-AppxPackage // 注意:回调函数中包的信息无法修改,也不能擅自释放。且随着函数的执行完毕自动释放。这就要求在回调中自行拷贝一份。 // 输出的错误信息别忘了用 PackageManagerFreeString 释放 PKGMGR_API HRESULT GetAppxPackages (PKGMGR_FINDENUMCALLBACK pfCallback, void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 移除一个已经安装到电脑上的应用。注意:传入的是包完整名。 // 输出的错误信息别忘了用 PackageManagerFreeString 释放 PKGMGR_API HRESULT RemoveAppxPackage (LPCWSTR lpPkgFullName, PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 清理指定用户的指定 包 。 用于清除删除用户用户配置文件后为用户安装的包。 // 输出的错误信息别忘了用 PackageManagerFreeString 释放 PKGMGR_API HRESULT CleanupAppxPackage (LPCWSTR lpPkgName, LPCWSTR lpUserSID, PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 注册应用包 // dwDeployOption 接受 DEPOLYOPTION_* 常量 PKGMGR_API HRESULT RegisterAppxPackageByPath (LPCWSTR lpManifestPath, PCREGISTER_PACKAGE_DEFENDENCIES alpDependencyUriList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPOLYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 注册应用包 // dwDeployOption 接受 DEPOLYOPTION_* 常量 PKGMGR_API HRESULT RegisterAppxPackageByUri (LPCWSTR lpManifestUri, PCREGISTER_PACKAGE_DEFENDENCIES alpDependencyUriList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPOLYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 注册应用包 // dwDeployOption 接受 DEPOLYOPTION_* 常量 PKGMGR_API HRESULT RegisterAppxPackageByFullName (LPCWSTR lpPackageFullName, PCREGISTER_PACKAGE_DEFENDENCIES alpDepFullNameList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPOLYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 请查阅 https://learn.microsoft.com/zh-cn/uwp/api/windows.management.deployment.packagestate?view=winrt-26100 // 包可用。 #define PACKAGESTATUS_NORMAL 0 // 包的许可证无效。 #define PACKAGESTATUS_LICENSE_INVALID 1 // 包有效负载由未知源修改。 #define PACKAGESTATUS_MODIFIED 2 // 包有效负载被故意篡改。 #define PACKAGESTATUS_TAMPERED 3 // 例如,将 包的状态设置为“可用”、“已篡改”等。 // dwStatus 请使用 PACKAGESTATUS_* 常量 PKGMGR_API HRESULT SetAppxPackageStatus (LPCWSTR lpPackageFullName, DWORD dwStatus, LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 在不注册包的情况下将 包 暂存到系统。 // dwDeployOption 接受 DEPOLYOPTION_* 常量 PKGMGR_API HRESULT StageAppxPackageFromURI (LPCWSTR lpFileUri, PCREGISTER_PACKAGE_DEFENDENCIES alpDepUriList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPOLYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 在不注册包的情况下将 包 暂存到系统。 // dwDeployOption 接受 DEPOLYOPTION_* 常量 PKGMGR_API HRESULT StageAppxPackageFromPath (LPCWSTR lpFileUri, PCREGISTER_PACKAGE_DEFENDENCIES alpDepUriList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPOLYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 在不注册包的情况下将 包的 漫游数据暂存到系统。 在暂存包之后、为特定用户注册包之前调用此方法。 // dwDeployOption 接受 DEPOLYOPTION_* 常量 PKGMGR_API HRESULT StageAppxUserData (LPCWSTR lpPackageFullName, PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 为当前用户汇报已安装的包或其依赖项包。 // 仅当更新包的版本高于已安装包的版本时,才能更新已安装的包。 如果不存在以前版本的包,则操作将失败。 // 注意:传入的文件路径为 DOS/NT 风格。如:C:\Windows\... // dwDeployOption 接受 DEPOLYOPTION_* 常量 // 输出的错误信息别忘了用 PackageManagerFreeString 释放 PKGMGR_API HRESULT UpdateAppxPackageFromPath (LPCWSTR lpPkgPath, PCREGISTER_PACKAGE_DEFENDENCIES alpDepUrlList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPOLYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 为当前用户汇报已安装的包或其依赖项包。 // 仅当更新包的版本高于已安装包的版本时,才能更新已安装的包。 如果不存在以前版本的包,则操作将失败。 // 注意:传入的文件路径为 URI。 // dwDeployOption 接受 DEPOLYOPTION_* 常量 // 输出的错误信息别忘了用 PackageManagerFreeString 释放 PKGMGR_API HRESULT UpdateAppxPackageFromURI (LPCWSTR lpFileUri, PCREGISTER_PACKAGE_DEFENDENCIES alpDepFullNameList _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), DWORD dwDeployOption _DEFAULT_INIT_VALUE_FORFUNC_ (DEPOLYOPTION_NONE), PKGMRR_PROGRESSCALLBACK pfCallback _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 检索有关为任何用户安装的指定 包 的信息。 PKGMGR_API HRESULT FindAppxPackage (LPCWSTR lpPackageFullName, PKGMGR_FINDENUMCALLBACK pfCallback, void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 获取错误代码。错误代码不一定有,且更多有效信息来自错误详细信息。 PKGMGR_API LPCWSTR GetPackageManagerLastErrorCode (); // 获取错误详细信息。这个是常用的 PKGMGR_API LPCWSTR GetPackageManagerLastErrorDetailMessage (); // 启动 Metro UI 应用 PKGMGR_API HRESULT ActivateAppxApplication (LPCWSTR lpAppUserId, PDWORD pdwProcessId); // 根据提供的包身份名和发布者检索 PKGMGR_API HRESULT FindAppxPackagesByIdentity (LPCWSTR lpPkgName, LPCWSTR lpPkgPublisher, PKGMGR_FINDENUMCALLBACK pfCallback, void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 根据提供的包系列名检索 PKGMGR_API HRESULT FindAppxPackagesByFamilyName (LPCWSTR lpPkgFamilyName, PKGMGR_FINDENUMCALLBACK pfCallback, void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL)); // 释放由 pkgmgr.dll 返回的动态字符串。 PKGMGR_API void PackageManagerFreeString (LPWSTR lpString); #ifndef TEMPLATE_STRUCT #define TEMPLATE_STRUCT(_typename_) typedef struct _typename_##__ _typename_ #endif // ! TEMPLATE_STRUCT TEMPLATE_STRUCT (WRTAPPDATA); typedef WRTAPPDATA *HWRTAPPDATA; // 创建应用数据管理器。通过 Package Family Name PKGMGR_API HRESULT CreateAppDataManager (LPCWSTR lpFamilyName, HWRTAPPDATA *ppApplicationData, LPWSTR *pErrorCode, LPWSTR *pDetailMsg); // 从本地、漫游和临时应用数据存储中删除所有应用程序数据。 PKGMGR_API HRESULT WRTAppDataClearAll (HWRTAPPDATA hAppData, LPWSTR *pErrorCode, LPWSTR *pDetailMsg); PKGMGR_API HRESULT ActivateAppxApplicationWithArgs (LPCWSTR lpAppUserId, LPCWSTR lpArguments, PDWORD pdwProcessId); #ifdef _DEFAULT_INIT_VALUE_ #undef _DEFAULT_INIT_VALUE_ #endif #ifdef _DEFAULT_INIT_VALUE_FORFUNC_ #undef _DEFAULT_INIT_VALUE_FORFUNC_ #endif #ifdef __cplusplus } #endif #ifdef __cplusplus #include #include #include #include void IAsyncProgressCallback (DWORD dwProgress, void *pCustom) { using cbfunc = std::function ; if (auto func = reinterpret_cast (pCustom)) (*func)(dwProgress); } HRESULT AddAppxPackageFromPath ( const std::wstring &pkgpath, const std::vector &deplist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * deplist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = deplist.size (); for (size_t i = 0; i < deplist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)deplist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = AddAppxPackageFromPath (pkgpath.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT AddAppxPackageFromURI ( const std::wstring &pkguri, const std::vector &deplist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * deplist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = deplist.size (); for (size_t i = 0; i < deplist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)deplist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = AddAppxPackageFromURI (pkguri.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } struct find_pkginfo { bool isvalid = false; struct { std::wstring name, publisher, publisher_id, full_name, family_name, resource_id; UINT64 version = 0; // x86: 0 // x64: 9 // Arm: 5 // Neutral: 11 // Arm64: 12 // Unknown: 65535(-1) WORD architecture = -1; } identity; struct { std::wstring display_name, description, publisher, logo_uri; bool is_framework = false, resource_package = false; } properties; bool is_bundle = false; bool is_development_mode = false; std::wstring install_location; std::vector users, sids; #define safestring(_pstr_) (_pstr_ ? _pstr_ : L"") static find_pkginfo parse (LPCFIND_PACKAGE_INFO fpi) { if (!fpi) return find_pkginfo (); find_pkginfo fpkg; fpkg.identity.name += safestring (fpi->piIdentity.lpName); fpkg.identity.publisher += safestring (fpi->piIdentity.lpPublisher); fpkg.identity.publisher_id += safestring (fpi->piIdentity.lpPublisherId); fpkg.identity.family_name += safestring (fpi->piIdentity.lpFamilyName); fpkg.identity.full_name += safestring (fpi->piIdentity.lpFullName); fpkg.identity.resource_id += safestring (fpi->piIdentity.lpResourceId); fpkg.identity.version = fpi->piIdentity.qwVersion; fpkg.identity.architecture = fpi->piIdentity.wProcessArchitecture; fpkg.properties.display_name += safestring (fpi->piProperties.lpDisplayName); fpkg.properties.description += safestring (fpi->piProperties.lpDescription); fpkg.properties.publisher += safestring (fpi->piProperties.lpPublisher); fpkg.properties.logo_uri += safestring (fpi->piProperties.lpLogoUri); fpkg.properties.is_framework = fpi->piProperties.bIsFramework; fpkg.properties.resource_package = fpi->piProperties.bIsResourcePackage; fpkg.is_bundle = fpi->piProperties.bIsBundle; fpkg.is_development_mode = fpi->piProperties.bIsDevelopmentMode; fpkg.install_location += safestring (fpi->lpInstallLocation); std::wstring users; users += safestring (fpi->lpUsers); std::wstring sids; sids += safestring (fpi->lpSIDs); std::wstring part = L""; for (size_t i = 0; i < users.length (); i ++) { auto &wch = users [i]; if (wch == L';' || wch == L'0') { if (!part.empty ()) fpkg.users.push_back (part); part = L""; continue; } part += wch; } if (!part.empty ()) fpkg.users.push_back (part); part = L""; for (size_t i = 0; i < sids.length (); i ++) { auto &wch = sids [i]; if (wch == L';' || wch == L'0') { if (!part.empty ()) fpkg.sids.push_back (part); part = L""; continue; } part += wch; } if (!part.empty ()) fpkg.sids.push_back (part); fpkg.isvalid = true; return fpkg; } #ifdef safestring #undef safestring #endif }; void IAsyncFindEnumCallback (LPCFIND_PACKAGE_INFO pNowItem, void *pCustom) { if (pNowItem) { try { auto fpkg = find_pkginfo::parse (pNowItem); if (fpkg.isvalid) { using cbfunc = std::function ; auto func = reinterpret_cast (pCustom); if (func) (*func)(fpkg); } } catch (const std::exception &e) { OutputDebugStringA (e.what ()); } } } HRESULT GetAppxPackages ( std::function callback, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = GetAppxPackages (&IAsyncFindEnumCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT GetAppxPackages ( std::vector &out_pkgs, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { return GetAppxPackages ([&] (const find_pkginfo &fpi) { out_pkgs.push_back (fpi); }, errorcode, detailmsg); } HRESULT GetAppxPackages ( const std::wstring &package_family_name, std::function callback, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = FindAppxPackagesByFamilyName (package_family_name.c_str (), &IAsyncFindEnumCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT GetAppxPackages ( const std::wstring &package_family_name, std::vector &out_pkgs, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { return GetAppxPackages (package_family_name , [&] (const find_pkginfo &fpi) { out_pkgs.push_back (fpi); }, errorcode, detailmsg); } HRESULT GetAppxPackages ( const std::wstring &package_id_name, const std::wstring &package_id_publisher, std::function callback, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = FindAppxPackagesByIdentity (package_id_name.c_str (), package_id_publisher.c_str (), &IAsyncFindEnumCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT GetAppxPackages ( const std::wstring &package_id_name, const std::wstring &package_id_publisher, std::vector &out_pkgs, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { return GetAppxPackages (package_id_name, package_id_publisher, [&] (const find_pkginfo &fpi) { out_pkgs.push_back (fpi); }, errorcode, detailmsg); } HRESULT FindAppxPackage ( const std::wstring &package_fullname, std::function callback, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = FindAppxPackage (package_fullname.c_str (), &IAsyncFindEnumCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT FindAppxPackage ( const std::wstring &package_fullname, find_pkginfo &out_pkginf, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { return FindAppxPackage (package_fullname, [&] (const find_pkginfo &fpkg) { out_pkginf = fpkg; }, errorcode, detailmsg); } HRESULT RemoveAppxPackage ( const std::wstring &package_fullname, std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = RemoveAppxPackage (package_fullname.c_str (), &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT CleanupAppxPackage ( const std::wstring &package_name, const std::wstring &user_sid, std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = CleanupAppxPackage (package_name.c_str (), user_sid.c_str (), &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT RegisterAppxPackageByPath ( const std::wstring &manifest_path, const std::vector &depurilist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * depurilist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = depurilist.size (); for (size_t i = 0; i < depurilist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)depurilist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = RegisterAppxPackageByPath (manifest_path.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT RegisterAppxPackageByUri ( const std::wstring &manifest_uri, const std::vector &deplist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * deplist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = deplist.size (); for (size_t i = 0; i < deplist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)deplist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = RegisterAppxPackageByUri (manifest_uri.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT RegisterAppxPackageByFullName ( const std::wstring &package_full_name, const std::vector &deplist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * deplist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = deplist.size (); for (size_t i = 0; i < deplist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)deplist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = RegisterAppxPackageByFullName (package_full_name.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT StageAppxPackageFromURI ( const std::wstring &file_uri, const std::vector &deplist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * deplist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = deplist.size (); for (size_t i = 0; i < deplist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)deplist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = StageAppxPackageFromURI (file_uri.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT StageAppxPackageFromPath ( const std::wstring &file_path, const std::vector &deplist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * deplist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = deplist.size (); for (size_t i = 0; i < deplist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)deplist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = StageAppxPackageFromURI (file_path.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT StageAppxUserData ( const std::wstring &package_full_name, std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = StageAppxUserData (package_full_name.c_str (), &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT UpdateAppxPackageFromPath ( const std::wstring &file_path, const std::vector &deplist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * deplist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = deplist.size (); for (size_t i = 0; i < deplist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)deplist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = UpdateAppxPackageFromPath (file_path.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT UpdateAppxPackageFromURI ( const std::wstring &file_uri, const std::vector &deplist = std::vector (), DWORD deployoption = DEPOLYOPTION_NONE, // 使用 DEPOLYOPTION_* 前缀 std::function callback = nullptr, std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { std::vector bytes (sizeof (REGISTER_PACKAGE_DEFENDENCIES) + sizeof (LPWSTR) * deplist.size ()); auto lpdeplist = (PREGISTER_PACKAGE_DEFENDENCIES)bytes.data (); lpdeplist->dwSize = deplist.size (); for (size_t i = 0; i < deplist.size (); i ++) lpdeplist->alpDepUris [i] = (LPWSTR)deplist [i].c_str (); LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = UpdateAppxPackageFromURI (file_uri.c_str (), lpdeplist, deployoption, &IAsyncProgressCallback, &callback, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT SetAppxPackageStatus ( const std::wstring &package_full_name, DWORD status, // PACKAGESTATUS_* 前缀常量 std::wstring &errorcode = std::wstring (), std::wstring &detailmsg = std::wstring () ) { LPWSTR lperr = nullptr, lpmsg = nullptr; HRESULT hr = SetAppxPackageStatus (package_full_name.c_str (), status, &lperr, &lpmsg); errorcode = lperr ? lperr : L""; detailmsg = lpmsg ? lpmsg : L""; if (lperr) PackageManagerFreeString (lperr); if (lpmsg) PackageManagerFreeString (lpmsg); return hr; } HRESULT ActivateAppxApplication ( const std::wstring &app_user_id, PDWORD ret_processid = nullptr ) { return ActivateAppxApplication (app_user_id.c_str (), ret_processid); } #endif