Startuptask (#87)
* adding startup task. compiles but does not link. * works, but need to fix hardcoded user * Remove hardcoded user IDs * fix crash in quietux (installcomplete ui not set) fix crash on early error in errorHandler. * fix target libs for other flavors * remove unused constant * handle multiple startup tasks, add additional comments per PR feedback. * explain more in comment why startuptask is not the same on win7/win10 * rename namespace to MsixCoreLib fixups to startuptask due to merge with master split out RETURN_IF_FAILED in the MsixCoreLib to the separate provider re-create GUID for the separate logging providers for the exe and lib. * fix startup task removal, enable lib logging from exe
This commit is contained in:
Родитель
d7017a0cc1
Коммит
7a22748c77
|
@ -7,8 +7,9 @@
|
|||
#include "AddRemovePrograms.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
#include "Constants.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR AddRemovePrograms::HandlerName = L"AddRemovePrograms";
|
||||
|
||||
|
|
|
@ -4,27 +4,27 @@
|
|||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// Handles adding/removing the entry that allows an app to show up in AddRemovePrograms in the Control Panel (appwiz.cpl)
|
||||
class AddRemovePrograms : IPackageHandler
|
||||
{
|
||||
public:
|
||||
/// Creates a registry entry in the Uninstall key.
|
||||
/// This is read by the control panel's AddRemovePrograms to show packages that can be removed.
|
||||
HRESULT ExecuteForAddRequest();
|
||||
/// Handles adding/removing the entry that allows an app to show up in AddRemovePrograms in the Control Panel (appwiz.cpl)
|
||||
class AddRemovePrograms : IPackageHandler
|
||||
{
|
||||
public:
|
||||
/// Creates a registry entry in the Uninstall key.
|
||||
/// This is read by the control panel's AddRemovePrograms to show packages that can be removed.
|
||||
HRESULT ExecuteForAddRequest();
|
||||
|
||||
/// Removes the registry entry.
|
||||
HRESULT ExecuteForRemoveRequest();
|
||||
/// Removes the registry entry.
|
||||
HRESULT ExecuteForRemoveRequest();
|
||||
|
||||
static const PCWSTR HandlerName;
|
||||
static HRESULT CreateHandler(_In_ MsixRequest* msixRequest, _Out_ IPackageHandler** instance);
|
||||
~AddRemovePrograms() {}
|
||||
private:
|
||||
MsixRequest* m_msixRequest = nullptr;
|
||||
static const PCWSTR HandlerName;
|
||||
static HRESULT CreateHandler(_In_ MsixRequest* msixRequest, _Out_ IPackageHandler** instance);
|
||||
~AddRemovePrograms() {}
|
||||
private:
|
||||
MsixRequest* m_msixRequest = nullptr;
|
||||
|
||||
AddRemovePrograms() {}
|
||||
AddRemovePrograms(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
AddRemovePrograms() {}
|
||||
AddRemovePrograms(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
|
||||
};
|
||||
};
|
||||
}
|
|
@ -8,7 +8,8 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR ComInterface::HandlerName = L"ComInterface";
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "MsixRequest.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
class ComInterface : IPackageHandler
|
||||
{
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR ComServer::HandlerName = L"ComServer";
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "RegistryKey.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
#include <vector>
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
class ComServer : IPackageHandler
|
||||
{
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
#include "CommandLineInterface.hpp"
|
||||
#include "Win7MSIXInstallerLogger.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "..\Win7MSIXInstallerLib\GeneralUtil.hpp"
|
||||
#include "Util.hpp"
|
||||
#include "resource.h"
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
std::map<std::wstring, Option, CaseInsensitiveLess> CommandLineInterface::s_options =
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@ static const std::wstring ftaCategoryNameInManifest = L"windows.fileTypeAssociat
|
|||
static const std::wstring protocolCategoryNameInManifest = L"windows.protocol";
|
||||
static const std::wstring ComServerCategoryNameInManifest = L"windows.comServer";
|
||||
static const std::wstring comInterfaceCategoryNameInManifest = L"windows.comInterface";
|
||||
static const std::wstring startupTaskCategoryNameInManifest = L"windows.startupTask";
|
||||
|
||||
static const std::wstring categoryAttribute = L"Category";
|
||||
static const std::wstring nameAttribute = L"Name";
|
||||
|
@ -58,6 +59,7 @@ static const std::wstring oleMiscFlagAttribute = L"OleMiscFlag";
|
|||
static const std::wstring appendMenuFlagAttribute = L"AppendMenuFlag";
|
||||
static const std::wstring oleVerbFlagAttribute = L"OleVerbFlag";
|
||||
static const std::wstring resourceIndexAttribute = L"ResourceIndex";
|
||||
static const std::wstring taskIdAttribute = L"TaskId";
|
||||
|
||||
static const std::wstring extensionQuery = L"/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='Extensions']/*[local-name()='Extension']";
|
||||
static const std::wstring ftaQuery = L"*[local-name()='FileTypeAssociation']";
|
||||
|
@ -85,6 +87,7 @@ static const std::wstring aspectQuery = L"*[local-name()='Aspect']";
|
|||
static const std::wstring defaultIconQuery = L"*[local-name()='DefaultIcon']";
|
||||
static const std::wstring toolboxBitmapQuery = L"*[local-name()='ToolboxBitmap32']";
|
||||
static const std::wstring comVerbQuery = L"*[local-name()='Verbs']/*[local-name()='Verb']";
|
||||
static const std::wstring startupTaskQuery = L"*[local-name()='StartupTask']";
|
||||
|
||||
static const std::wstring clsidKeyName = L"CLSID";
|
||||
static const std::wstring inprocHandlerKeyName = L"InprocHandler32";
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
|
||||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
#include "ErrorHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR ErrorHandler::HandlerName = L"ErrorHandler";
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
class ErrorHandler : IPackageHandler
|
||||
{
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
#include "RegistryDevirtualizer.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR Extractor::HandlerName = L"Extractor";
|
||||
|
||||
|
@ -223,7 +224,7 @@ HRESULT Extractor::RemoveVfsFiles()
|
|||
RETURN_IF_FAILED(CreateStreamOnFileUTF16(blockMapPath.c_str(), true /*forRead*/, &stream));
|
||||
|
||||
ComPtr<IAppxFactory> appxFactory;
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(Win7MsixInstallerLib_MyAllocate, Win7MsixInstallerLib_MyFree, m_msixRequest->GetValidationOptions(), &appxFactory));
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(MyAllocate, MyFree, m_msixRequest->GetValidationOptions(), &appxFactory));
|
||||
|
||||
ComPtr<IAppxBlockMapReader> blockMapReader;
|
||||
RETURN_IF_FAILED(appxFactory->CreateBlockMapReader(stream.Get(), &blockMapReader));
|
||||
|
@ -405,8 +406,8 @@ HRESULT Extractor::NeedToCopyFile(std::wstring sourceFullPath, std::wstring targ
|
|||
bool sourceFileIsUnversioned = false;
|
||||
RETURN_IF_FAILED(GetFileVersion(sourceFullPath, sourceFileVersion, sourceFileIsUnversioned));
|
||||
|
||||
std::wstring targetVersionString = Win7MsixInstallerLib_ConvertVersionToString(targetFileVersion);
|
||||
std::wstring sourceVersionString = Win7MsixInstallerLib_ConvertVersionToString(sourceFileVersion);
|
||||
std::wstring targetVersionString = ConvertVersionToString(targetFileVersion);
|
||||
std::wstring sourceVersionString = ConvertVersionToString(sourceFileVersion);
|
||||
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Target Exists, file versioning information",
|
||||
|
@ -499,7 +500,7 @@ HRESULT Extractor::RemoveVfsFile(std::wstring fileName)
|
|||
TraceLoggingValue(GetLastError(), "error"));
|
||||
}
|
||||
|
||||
Win7MsixInstallerLib_GetPathParent(fullPath);
|
||||
MsixCoreLib_GetPathParent(fullPath);
|
||||
|
||||
// instead of checking if the directory is empty, just try to delete it.
|
||||
// if it's not empty it'll fail with expected error code that we can ignore
|
||||
|
@ -523,14 +524,14 @@ HRESULT Extractor::ConvertVfsNameToFullPath(std::wstring fileName, std::wstring&
|
|||
{
|
||||
//The following code gets remainingFilePath from "VFS\FirstDir\...\file.ext" to "\...\file.ext"
|
||||
std::wstring remainingFilePath = fileName;
|
||||
Win7MsixInstallerLib_GetPathChild(remainingFilePath); // remove the VFS directory
|
||||
MsixCoreLib_GetPathChild(remainingFilePath); // remove the VFS directory
|
||||
|
||||
std::map<std::wstring, std::wstring> map = FilePathMappings::GetInstance().GetMap();
|
||||
for (auto& pair : map)
|
||||
{
|
||||
if (remainingFilePath.find(pair.first) != std::wstring::npos)
|
||||
{
|
||||
Win7MsixInstallerLib_GetPathChild(remainingFilePath); // remove the FirstDir directory.
|
||||
MsixCoreLib_GetPathChild(remainingFilePath); // remove the FirstDir directory.
|
||||
|
||||
// Pre-pend the VFS target directory to obtain the full path for the target location
|
||||
fileFullPath = pair.second + std::wstring(L"\\") + remainingFilePath;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// Extractor extracts the files and registry settings from the package to the file system and registry.
|
||||
class Extractor : IPackageHandler
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include <shlobj_core.h>
|
||||
#include <KnownFolders.h>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
void Win7MsixInstallerLib_GetPathChild(std::wstring &path)
|
||||
void MsixCoreLib_GetPathChild(std::wstring &path)
|
||||
{
|
||||
while (path.front() != '\\')
|
||||
{
|
||||
|
@ -14,7 +15,7 @@ void Win7MsixInstallerLib_GetPathChild(std::wstring &path)
|
|||
path.erase(0, 1);
|
||||
}
|
||||
|
||||
void Win7MsixInstallerLib_GetPathParent(std::wstring &path)
|
||||
void MsixCoreLib_GetPathParent(std::wstring &path)
|
||||
{
|
||||
while (!path.empty() && path.back() != '\\')
|
||||
{
|
||||
|
@ -48,7 +49,7 @@ std::wstring FilePathMappings::GetExecutablePath(std::wstring packageExecutableP
|
|||
//Checks if the executable is inside the VFS
|
||||
if (executionPathWSTR.find(L"VFS") != std::wstring::npos)
|
||||
{
|
||||
Win7MsixInstallerLib_GetPathChild(executionPathWSTR);
|
||||
MsixCoreLib_GetPathChild(executionPathWSTR);
|
||||
//Checks if the executable is in one of the known folders
|
||||
for (auto pair : m_map)
|
||||
{
|
||||
|
@ -57,7 +58,7 @@ std::wstring FilePathMappings::GetExecutablePath(std::wstring packageExecutableP
|
|||
//The executable exists in an unpacked directory
|
||||
std::wstring executablePath = pair.second;
|
||||
|
||||
Win7MsixInstallerLib_GetPathChild(executionPathWSTR);
|
||||
MsixCoreLib_GetPathChild(executionPathWSTR);
|
||||
executablePath.push_back(L'\\');
|
||||
executablePath.append(executionPathWSTR);
|
||||
return executablePath;
|
||||
|
@ -109,7 +110,7 @@ HRESULT FilePathMappings::InitializePaths()
|
|||
appVSystem32SpoolPath.append(L"\\spool");
|
||||
|
||||
std::wstring systemDrive = std::wstring(windowsPath.Get());
|
||||
Win7MsixInstallerLib_GetPathParent(systemDrive);
|
||||
MsixCoreLib_GetPathParent(systemDrive);
|
||||
m_map[L"AppVPackageDrive"] = systemDrive;
|
||||
m_map[L"SystemX86"] = std::wstring(systemX86Path.Get());
|
||||
m_map[L"System"] = std::wstring(systemPath.Get());
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
#include "GeneralUtil.hpp"
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// FilePath Mappings maps the VFS tokens to the actual folder on disk.
|
||||
/// For instance, VFS token: Windows, actual folder: C:\windows
|
||||
|
@ -40,8 +40,8 @@ private:
|
|||
}
|
||||
/// Removes the first directory from a path.
|
||||
/// @param path - A path that contains at least one parent directory
|
||||
void Win7MsixInstallerLib_GetPathChild(std::wstring &path);
|
||||
void MsixCoreLib_GetPathChild(std::wstring &path);
|
||||
|
||||
/// Removes the innermost child file from a path
|
||||
/// @param path - A file path
|
||||
void Win7MsixInstallerLib_GetPathParent(std::wstring &path);
|
||||
void MsixCoreLib_GetPathParent(std::wstring &path);
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "RegistryKey.hpp"
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR FileTypeAssociation::HandlerName = L"FileTypeAssociation";
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "RegistryDevirtualizer.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// Data structs to be filled in from the information in the manifest
|
||||
struct Verb
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define FOOTPRINTFILES_H
|
||||
|
||||
#include "AppxPackaging.hpp"
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
// Describes the FootprintFilesType structure
|
||||
template<typename Type>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "Package.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// Interface for a logical chunk of work done on an Msix request
|
||||
class IPackageHandler
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include "InstallComplete.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR InstallComplete::HandlerName = L"InstallComplete";
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
class InstallComplete : IPackageHandler
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// MSIXWindows.hpp define NOMINMAX because we want to use std::min/std::max from <algorithm>
|
||||
// GdiPlus.h requires a definiton for min and max. Use std namespace *BEFORE* including it.
|
||||
using namespace std;
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
#include <GdiPlus.h>
|
||||
|
||||
static const int g_width = 500; // width of window
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <windows.h>
|
||||
#include <string>
|
||||
#include "Util.hpp"
|
||||
#include "..\Win7MSIXInstallerLib\GeneralUtil.hpp"
|
||||
#include <IPackageManager.hpp>
|
||||
#include <IMsixResponse.hpp>
|
||||
#include "resource.h"
|
||||
|
@ -32,7 +33,7 @@ public:
|
|||
HRESULT LaunchInstalledApp();
|
||||
void ConfirmAppCancel(HWND parentHWnd);
|
||||
|
||||
UI(_In_ Win7MsixInstallerLib::IPackageManager* packageManager, _In_ const std::wstring & path, UIType type) : m_packageManager(packageManager), m_type(type)
|
||||
UI(_In_ MsixCoreLib::IPackageManager* packageManager, _In_ const std::wstring & path, UIType type) : m_packageManager(packageManager), m_type(type)
|
||||
{
|
||||
m_path = std::wstring(path);
|
||||
m_closeUI = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
@ -40,10 +41,10 @@ public:
|
|||
~UI() {}
|
||||
|
||||
private:
|
||||
Win7MsixInstallerLib::IPackageManager* m_packageManager = nullptr;
|
||||
std::shared_ptr<Win7MsixInstallerLib::IPackage> m_packageInfo = nullptr;
|
||||
MsixCoreLib::IPackageManager* m_packageManager = nullptr;
|
||||
std::shared_ptr<MsixCoreLib::IPackage> m_packageInfo = nullptr;
|
||||
std::wstring m_path;
|
||||
std::shared_ptr<Win7MsixInstallerLib::IMsixResponse> m_msixResponse;
|
||||
std::shared_ptr<MsixCoreLib::IMsixResponse> m_msixResponse;
|
||||
|
||||
//Parent Window Hwnd
|
||||
HWND hWnd = NULL;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <experimental/filesystem> // C++-standard header file name
|
||||
#include <filesystem> // Microsoft-specific implementation header file name
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
|
||||
// handlers
|
||||
#include "Extractor.hpp"
|
||||
|
@ -25,6 +26,7 @@
|
|||
#include "Protocol.hpp"
|
||||
#include "ComInterface.hpp"
|
||||
#include "ComServer.hpp"
|
||||
#include "StartupTask.hpp"
|
||||
#include "FileTypeAssociation.hpp"
|
||||
#include "ProcessPotentialUpdate.hpp"
|
||||
#include "InstallComplete.hpp"
|
||||
|
@ -37,7 +39,7 @@
|
|||
// GdiPlus.h requires a definiton for min and max. Use std namespace *BEFORE* including it.
|
||||
using namespace std;
|
||||
#include <GdiPlus.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
struct HandlerInfo
|
||||
{
|
||||
CreateHandler create;
|
||||
|
@ -48,7 +50,7 @@ struct HandlerInfo
|
|||
std::map<PCWSTR, HandlerInfo> AddHandlers =
|
||||
{
|
||||
//HandlerName Function to create NextHandler ErrorHandlerInfo
|
||||
{PopulatePackageInfo::HandlerName, {PopulatePackageInfo::CreateHandler, ValidateTargetDeviceFamily::HandlerName, ErrorHandler::HandlerName}},
|
||||
{PopulatePackageInfo::HandlerName, {PopulatePackageInfo::CreateHandler, ValidateTargetDeviceFamily::HandlerName, nullptr /*nothing to rollback if we can't open the package*/}},
|
||||
{ValidateTargetDeviceFamily::HandlerName, {ValidateTargetDeviceFamily::CreateHandler, ProcessPotentialUpdate::HandlerName, ErrorHandler::HandlerName}},
|
||||
{ProcessPotentialUpdate::HandlerName, {ProcessPotentialUpdate::CreateHandler, Extractor::HandlerName, ErrorHandler::HandlerName}},
|
||||
{Extractor::HandlerName, {Extractor::CreateHandler, StartMenuLink::HandlerName, ErrorHandler::HandlerName}},
|
||||
|
@ -56,7 +58,8 @@ std::map<PCWSTR, HandlerInfo> AddHandlers =
|
|||
{AddRemovePrograms::HandlerName, {AddRemovePrograms::CreateHandler, Protocol::HandlerName, ErrorHandler::HandlerName}},
|
||||
{Protocol::HandlerName, {Protocol::CreateHandler, ComInterface::HandlerName, ErrorHandler::HandlerName}},
|
||||
{ComInterface::HandlerName, {ComInterface::CreateHandler, ComServer::HandlerName, ErrorHandler::HandlerName}},
|
||||
{ComServer::HandlerName, {ComServer::CreateHandler, FileTypeAssociation::HandlerName, ErrorHandler::HandlerName}},
|
||||
{ComServer::HandlerName, {ComServer::CreateHandler, StartupTask::HandlerName, ErrorHandler::HandlerName}},
|
||||
{StartupTask::HandlerName, {StartupTask::CreateHandler, FileTypeAssociation::HandlerName, ErrorHandler::HandlerName}},
|
||||
{FileTypeAssociation::HandlerName, {FileTypeAssociation::CreateHandler, InstallComplete::HandlerName, ErrorHandler::HandlerName}},
|
||||
{InstallComplete::HandlerName, {InstallComplete::CreateHandler, nullptr, ErrorHandler::HandlerName}},
|
||||
{ErrorHandler::HandlerName, {ErrorHandler::CreateHandler, nullptr, nullptr}},
|
||||
|
@ -70,7 +73,8 @@ std::map<PCWSTR, HandlerInfo> RemoveHandlers =
|
|||
{AddRemovePrograms::HandlerName, {AddRemovePrograms::CreateHandler, Protocol::HandlerName}},
|
||||
{Protocol::HandlerName, {Protocol::CreateHandler, ComInterface::HandlerName}},
|
||||
{ComInterface::HandlerName, {ComInterface::CreateHandler, ComServer::HandlerName}},
|
||||
{ComServer::HandlerName, {ComServer::CreateHandler, FileTypeAssociation::HandlerName}},
|
||||
{ComServer::HandlerName, {ComServer::CreateHandler, StartupTask::HandlerName}},
|
||||
{StartupTask::HandlerName, {StartupTask::CreateHandler, FileTypeAssociation::HandlerName}},
|
||||
{FileTypeAssociation::HandlerName, {FileTypeAssociation::CreateHandler, Extractor::HandlerName}},
|
||||
{Extractor::HandlerName, {Extractor::CreateHandler, nullptr}},
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "FilePaths.hpp"
|
||||
#include "MsixResponse.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
enum OperationType
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "MsixResponse.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
void MsixResponse::Update(InstallationStep status, float progress)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "IMsixResponse.hpp"
|
||||
|
||||
#include "GeneralUtil.hpp"
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// The response class tracks the response state of the msix deploy operation
|
||||
/// (if the operation was cancelled, progress bar updates)
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
#include "Package.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
#include <fstream>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
//
|
||||
// Gets the stream of a file.
|
||||
|
@ -42,7 +43,7 @@ HRESULT GetStreamFromFile(IAppxPackageReader* package, LPCWCHAR name, IStream**
|
|||
|
||||
std::wstring PackageBase::GetVersion()
|
||||
{
|
||||
return Win7MsixInstallerLib_ConvertVersionToString(m_version);
|
||||
return ConvertVersionToString(m_version);
|
||||
}
|
||||
|
||||
HRESULT PackageBase::ParseManifest(IMsixElement* element)
|
||||
|
@ -151,7 +152,7 @@ HRESULT PackageBase::SetManifestReader(IAppxManifestReader * manifestReader)
|
|||
Text<WCHAR> packageFullName;
|
||||
RETURN_IF_FAILED(manifestId->GetPackageFullName(&packageFullName));
|
||||
m_packageFullName = packageFullName.Get();
|
||||
m_packageFamilyName = Win7MsixInstallerLib_GetFamilyNameFromFullName(m_packageFullName);
|
||||
m_packageFamilyName = GetFamilyNameFromFullName(m_packageFullName);
|
||||
|
||||
ComPtr<IMsixDocumentElement> domElement;
|
||||
RETURN_IF_FAILED(manifestReader->QueryInterface(UuidOfImpl<IMsixDocumentElement>::iid, reinterpret_cast<void**>(&domElement)));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "MSIXWindows.hpp"
|
||||
#include "IPackage.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
|
||||
class PackageBase
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
#include <TraceLoggingProvider.h>
|
||||
#include <experimental/filesystem> // C++-standard header file name
|
||||
#include "Constants.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR PopulatePackageInfo::HandlerName = L"PopulatePackageInfo";
|
||||
|
||||
|
@ -19,7 +20,7 @@ HRESULT PopulatePackageInfo::GetPackageInfoFromPackage(const std::wstring & pack
|
|||
// On non-Win32 platforms CoCreateAppxFactory will return 0x80070032 (e.g. HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED))
|
||||
// So on all platforms, it's always safe to call CoCreateAppxFactoryWithHeap, just be sure to bring your own heap!
|
||||
ComPtr<IAppxFactory> appxFactory;
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(Win7MsixInstallerLib_MyAllocate, Win7MsixInstallerLib_MyFree, validationOption, &appxFactory));
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(MyAllocate, MyFree, validationOption, &appxFactory));
|
||||
|
||||
// Create a new package reader using the factory.
|
||||
ComPtr<IAppxPackageReader> packageReader;
|
||||
|
@ -43,7 +44,7 @@ HRESULT PopulatePackageInfo::GetPackageInfoFromManifest(const std::wstring & dir
|
|||
|
||||
// Create a new package reader using the factory.
|
||||
ComPtr<IAppxFactory> appxFactory;
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(Win7MsixInstallerLib_MyAllocate, Win7MsixInstallerLib_MyFree, validationOption, &appxFactory));
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(MyAllocate, MyFree, validationOption, &appxFactory));
|
||||
|
||||
ComPtr<IAppxManifestReader> manifestReader;
|
||||
RETURN_IF_FAILED(appxFactory->CreateManifestReader(inputStream.Get(), &manifestReader));
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "MsixRequest.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
class PopulatePackageInfo : IPackageHandler
|
||||
{
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "ProcessPotentialUpdate.hpp"
|
||||
#include <filesystem>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
const PCWSTR ProcessPotentialUpdate::HandlerName = L"ProcessPotentialUpdate";
|
||||
|
||||
HRESULT ProcessPotentialUpdate::ExecuteForAddRequest()
|
||||
|
@ -14,9 +15,9 @@ HRESULT ProcessPotentialUpdate::ExecuteForAddRequest()
|
|||
|
||||
for (auto& p : std::experimental::filesystem::directory_iterator(FilePathMappings::GetInstance().GetMsix7Directory()))
|
||||
{
|
||||
std::wstring installedPackageFamilyName = Win7MsixInstallerLib_GetFamilyNameFromFullName(p.path().filename());
|
||||
if (Win7MsixInstallerLib_CaseInsensitiveEquals(currentPackageFamilyName, installedPackageFamilyName)
|
||||
&& !Win7MsixInstallerLib_CaseInsensitiveEquals(m_msixRequest->GetPackageInfo()->GetPackageFullName(), p.path().filename()))
|
||||
std::wstring installedPackageFamilyName = GetFamilyNameFromFullName(p.path().filename());
|
||||
if (CaseInsensitiveEquals(currentPackageFamilyName, installedPackageFamilyName)
|
||||
&& !CaseInsensitiveEquals(m_msixRequest->GetPackageInfo()->GetPackageFullName(), p.path().filename()))
|
||||
{
|
||||
RETURN_IF_FAILED(RemovePackage(p.path().filename()));
|
||||
return S_OK;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// Determines if the incoming add request is actually an update to an existing package.
|
||||
/// If it is, it'll remove the outdated package
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR Protocol::HandlerName = L"Protocol";
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <vector>
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
|
||||
/// Data structs to be filled in from the information in the manifest
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
#include "FilePaths.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <vector>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
struct VirtualRegistryMapping
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <vector>
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// Handles the conversion of the information stored in Registry.dat
|
||||
/// to the currently running OS's registry, which is referred to here as "actual registry"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "RegistryKey.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
HRESULT RegistryKey::Open(
|
||||
_In_ const HKEY hkey,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "GeneralUtil.hpp"
|
||||
namespace Win7MsixInstallerLib
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// Encapsulates and lifetimes the HKEY used by the RegOpenKey et al APIs.
|
||||
class RegistryKey
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#include "StartMenuLink.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR StartMenuLink::HandlerName = L"StartMenuLink";
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
/// Handles adding/removing the shortcut in the start menu to launch the application
|
||||
class StartMenuLink : IPackageHandler
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include <shlobj_core.h>
|
||||
#include <CommCtrl.h>
|
||||
|
||||
#include "FilePaths.hpp"
|
||||
#include "StartupTask.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
#include <taskschd.h>
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR StartupTask::HandlerName = L"StartupTask";
|
||||
|
||||
const PCWSTR StartupTask::TaskDefinitionXmlPrefix =
|
||||
L"<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\
|
||||
<Principals>\
|
||||
<Principal id=\"Author\">\
|
||||
<LogonType>InteractiveToken</LogonType>\
|
||||
<RunLevel>LeastPrivilege</RunLevel>\
|
||||
</Principal>\
|
||||
</Principals>\
|
||||
<Triggers>\
|
||||
<LogonTrigger>\
|
||||
<Enabled>true</Enabled>\
|
||||
</LogonTrigger>\
|
||||
</Triggers>\
|
||||
<Settings>\
|
||||
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>\
|
||||
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>\
|
||||
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>\
|
||||
<AllowHardTerminate>true</AllowHardTerminate>\
|
||||
<StartWhenAvailable>false</StartWhenAvailable>\
|
||||
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>\
|
||||
<AllowStartOnDemand>true</AllowStartOnDemand>\
|
||||
<Enabled>true</Enabled>\
|
||||
<Hidden>false</Hidden>\
|
||||
<RunOnlyIfIdle>false</RunOnlyIfIdle>\
|
||||
<WakeToRun>false</WakeToRun>\
|
||||
<Priority>7</Priority>\
|
||||
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>\
|
||||
</Settings>\
|
||||
<Actions Context=\"Author\">\
|
||||
<Exec>\
|
||||
<Command>\"";
|
||||
const PCWSTR StartupTask::TaskDefinitionXmlPostfix =
|
||||
L"\"</Command>\
|
||||
</Exec>\
|
||||
</Actions>\
|
||||
</Task>";
|
||||
|
||||
const PCWSTR windowsTaskFolderName = L"\\Microsoft\\Windows";
|
||||
const PCWSTR taskFolderName = L"MsixCore";
|
||||
|
||||
HRESULT StartupTask::ExecuteForAddRequest()
|
||||
{
|
||||
if (m_tasks.empty())
|
||||
{
|
||||
// Startup tasks are not required, if there are none, nothing to do.
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
AutoCoInitialize coInit;
|
||||
RETURN_IF_FAILED(coInit.Initialize(COINIT_MULTITHREADED));
|
||||
{
|
||||
// New scope so that ComPtrs are released prior to calling CoUninitialize
|
||||
|
||||
VARIANT variantNull;
|
||||
ZeroMemory(&variantNull, sizeof(VARIANT));
|
||||
variantNull.vt = VT_NULL;
|
||||
|
||||
ComPtr<ITaskService> taskService;
|
||||
RETURN_IF_FAILED(CoCreateInstance(CLSID_TaskScheduler,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_ITaskService,
|
||||
reinterpret_cast<void**>(&taskService)));
|
||||
RETURN_IF_FAILED(taskService->Connect(variantNull /*serverName*/, variantNull /*user*/, variantNull /*domain*/, variantNull /*password*/));
|
||||
|
||||
Bstr rootFolderPathBstr(windowsTaskFolderName);
|
||||
ComPtr<ITaskFolder> rootFolder;
|
||||
RETURN_IF_FAILED(taskService->GetFolder(rootFolderPathBstr, &rootFolder));
|
||||
|
||||
Bstr taskFolderBstr(taskFolderName);
|
||||
ComPtr<ITaskFolder> msixCoreFolder;
|
||||
HRESULT hrCreateFolder = rootFolder->CreateFolder(taskFolderBstr, variantNull /*sddl*/, &msixCoreFolder);
|
||||
if (hrCreateFolder == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
RETURN_IF_FAILED(rootFolder->GetFolder(taskFolderBstr, &msixCoreFolder));
|
||||
}
|
||||
else
|
||||
{
|
||||
RETURN_IF_FAILED(hrCreateFolder);
|
||||
}
|
||||
|
||||
ComPtr<ITaskDefinition> taskDefinition;
|
||||
RETURN_IF_FAILED(taskService->NewTask(0, &taskDefinition));
|
||||
|
||||
for (auto task = m_tasks.begin(); task != m_tasks.end(); ++task)
|
||||
{
|
||||
std::wstring taskDefinitionXml = TaskDefinitionXmlPrefix + task->executable + TaskDefinitionXmlPostfix;
|
||||
Bstr taskDefinitionXmlBstr(taskDefinitionXml);
|
||||
RETURN_IF_FAILED(taskDefinition->put_XmlText(taskDefinitionXmlBstr));
|
||||
|
||||
Bstr taskNameBstr(task->name);
|
||||
ComPtr<IRegisteredTask> registeredTask;
|
||||
RETURN_IF_FAILED(msixCoreFolder->RegisterTaskDefinition(taskNameBstr, taskDefinition.Get(), TASK_CREATE_OR_UPDATE,
|
||||
variantNull /*userId*/, variantNull /*password*/, TASK_LOGON_INTERACTIVE_TOKEN, variantNull /*sddl*/, ®isteredTask));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT StartupTask::ExecuteForRemoveRequest()
|
||||
{
|
||||
if (m_tasks.empty())
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
AutoCoInitialize coInit;
|
||||
RETURN_IF_FAILED(coInit.Initialize(COINIT_MULTITHREADED));
|
||||
{
|
||||
// New scope so that ComPtrs are released prior to calling CoUninitialize
|
||||
|
||||
VARIANT variantNull;
|
||||
ZeroMemory(&variantNull, sizeof(VARIANT));
|
||||
variantNull.vt = VT_NULL;
|
||||
|
||||
ComPtr<ITaskService> taskService;
|
||||
RETURN_IF_FAILED(CoCreateInstance(CLSID_TaskScheduler,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_ITaskService,
|
||||
reinterpret_cast<void**>(&taskService)));
|
||||
RETURN_IF_FAILED(taskService->Connect(variantNull, variantNull, variantNull, variantNull));
|
||||
|
||||
Bstr rootFolderPathBstr(windowsTaskFolderName);
|
||||
ComPtr<ITaskFolder> rootFolder;
|
||||
RETURN_IF_FAILED(taskService->GetFolder(rootFolderPathBstr, &rootFolder));
|
||||
|
||||
Bstr taskFolderBstr(taskFolderName);
|
||||
ComPtr<ITaskFolder> msixCoreFolder;
|
||||
RETURN_IF_FAILED(rootFolder->GetFolder(taskFolderBstr, &msixCoreFolder));
|
||||
|
||||
for (auto task = m_tasks.begin(); task != m_tasks.end(); ++task)
|
||||
{
|
||||
Bstr taskNameBstr(task->name);
|
||||
ComPtr<IRegisteredTask> registeredTask;
|
||||
RETURN_IF_FAILED(msixCoreFolder->DeleteTask(taskNameBstr, 0 /*flags*/));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT StartupTask::ParseManifest()
|
||||
{
|
||||
std::wstring currentPackageFamilyName = GetFamilyNameFromFullName(m_msixRequest->GetPackageInfo()->GetPackageFullName());
|
||||
|
||||
ComPtr<IMsixDocumentElement> domElement;
|
||||
RETURN_IF_FAILED(m_msixRequest->GetPackageInfo()->GetManifestReader()->QueryInterface(UuidOfImpl<IMsixDocumentElement>::iid, reinterpret_cast<void**>(&domElement)));
|
||||
|
||||
ComPtr<IMsixElement> element;
|
||||
RETURN_IF_FAILED(domElement->GetDocumentElement(&element));
|
||||
|
||||
ComPtr<IMsixElementEnumerator> extensionEnum;
|
||||
RETURN_IF_FAILED(element->GetElements(extensionQuery.c_str(), &extensionEnum));
|
||||
BOOL hasCurrent = FALSE;
|
||||
RETURN_IF_FAILED(extensionEnum->GetHasCurrent(&hasCurrent));
|
||||
while (hasCurrent)
|
||||
{
|
||||
ComPtr<IMsixElement> extensionElement;
|
||||
RETURN_IF_FAILED(extensionEnum->GetCurrent(&extensionElement));
|
||||
Text<wchar_t> extensionCategory;
|
||||
RETURN_IF_FAILED(extensionElement->GetAttributeValue(categoryAttribute.c_str(), &extensionCategory));
|
||||
|
||||
if (wcscmp(extensionCategory.Get(), startupTaskCategoryNameInManifest.c_str()) == 0)
|
||||
{
|
||||
Text<wchar_t> executable;
|
||||
RETURN_IF_FAILED(extensionElement->GetAttributeValue(executableAttribute.c_str(), &executable));
|
||||
|
||||
ComPtr<IMsixElementEnumerator> startupTaskEnum;
|
||||
RETURN_IF_FAILED(extensionElement->GetElements(startupTaskQuery.c_str(), &startupTaskEnum));
|
||||
BOOL taskHasCurrent = FALSE;
|
||||
RETURN_IF_FAILED(startupTaskEnum->GetHasCurrent(&taskHasCurrent));
|
||||
if (taskHasCurrent)
|
||||
{
|
||||
ComPtr<IMsixElement> startupTaskElement;
|
||||
RETURN_IF_FAILED(startupTaskEnum->GetCurrent(&startupTaskElement));
|
||||
|
||||
Text<wchar_t> taskId;
|
||||
RETURN_IF_FAILED(startupTaskElement->GetAttributeValue(taskIdAttribute.c_str(), &taskId));
|
||||
|
||||
Task task;
|
||||
task.executable = FilePathMappings::GetInstance().GetExecutablePath(executable.Get(), m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
task.name = currentPackageFamilyName + L" " + taskId.Get();
|
||||
|
||||
m_tasks.push_back(task);
|
||||
}
|
||||
}
|
||||
RETURN_IF_FAILED(extensionEnum->MoveNext(&hasCurrent));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT StartupTask::CreateHandler(MsixRequest * msixRequest, IPackageHandler ** instance)
|
||||
{
|
||||
std::unique_ptr<StartupTask> localInstance(new StartupTask(msixRequest));
|
||||
if (localInstance == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
RETURN_IF_FAILED(localInstance->ParseManifest());
|
||||
|
||||
*instance = localInstance.release();
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "RegistryKey.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
struct Task
|
||||
{
|
||||
std::wstring name;
|
||||
std::wstring executable;
|
||||
};
|
||||
|
||||
class StartupTask : IPackageHandler
|
||||
{
|
||||
public:
|
||||
|
||||
/// Using task scheduler APIs, creates a scheduled task to run the executable listed in the windows.startupTask extension when the user logs on.
|
||||
/// This diverges from the Windows 10 handling of startupTask, as there is built-in OS support to run the tasks on logon without using task scheduler.
|
||||
/// Windows 7 and 8 and some versions of windows 10 do not have OS support to understand startupTasks in the same way, so we're using task scheduler instead.
|
||||
HRESULT ExecuteForAddRequest();
|
||||
|
||||
/// Removes the scheduled tasks added
|
||||
HRESULT ExecuteForRemoveRequest();
|
||||
|
||||
static const PCWSTR HandlerName;
|
||||
static HRESULT CreateHandler(_In_ MsixRequest* msixRequest, _Out_ IPackageHandler** instance);
|
||||
~StartupTask() {}
|
||||
private:
|
||||
|
||||
MsixRequest* m_msixRequest = nullptr;
|
||||
|
||||
std::vector<Task> m_tasks;
|
||||
|
||||
/// Parses the manifest to find the executable to run as part of startup task
|
||||
HRESULT ParseManifest();
|
||||
|
||||
StartupTask() {}
|
||||
StartupTask(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
|
||||
static const PCWSTR TaskDefinitionXmlPrefix;
|
||||
static const PCWSTR TaskDefinitionXmlPostfix;
|
||||
};
|
||||
}
|
|
@ -3,21 +3,6 @@
|
|||
#include <codecvt>
|
||||
#include <iostream>
|
||||
|
||||
std::string utf16_to_utf8(const std::wstring& utf16string)
|
||||
{
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8<wchar_t>>{}.to_bytes(utf16string.data());
|
||||
std::string result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring utf8_to_utf16(const std::string& utf8string)
|
||||
{
|
||||
// see https://connect.microsoft.com/VisualStudio/feedback/details/1403302/unresolved-external-when-using-codecvt-utf8
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8_utf16<unsigned short>, unsigned short>{}.from_bytes(utf8string.data());
|
||||
std::wstring result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring GetStringResource(UINT resourceId)
|
||||
{
|
||||
HMODULE instance = GetModuleHandle(nullptr);
|
||||
|
@ -32,9 +17,4 @@ std::wstring GetStringResource(UINT resourceId)
|
|||
std::wstring stringResource(buffer);
|
||||
|
||||
return stringResource;
|
||||
}
|
||||
|
||||
bool CaseInsensitiveEquals(const std::wstring& left, const std::wstring& right)
|
||||
{
|
||||
return (_wcsicmp(left.c_str(), right.c_str()) == 0);
|
||||
}
|
|
@ -4,214 +4,9 @@
|
|||
#include <winmeta.h>
|
||||
#include <string.h>
|
||||
|
||||
/// Converts a wstring from utf16 to utf8
|
||||
///
|
||||
/// @param utf16string - A utf16 wstring
|
||||
/// @return utf8 string
|
||||
std::string utf16_to_utf8(const std::wstring& utf16string);
|
||||
|
||||
/// Converts a string from utf8 to utf16
|
||||
///
|
||||
/// @param utf8string - A utf8 string
|
||||
/// @return utf16 string
|
||||
std::wstring utf8_to_utf16(const std::string& utf8string);
|
||||
|
||||
/// Helper to get string resource
|
||||
///
|
||||
/// @param resourceId - resource ID, these should be listed in resource.h
|
||||
/// @return string for the resource, resolved from the stringtable defined in Win7MsixInstaller.rc
|
||||
std::wstring GetStringResource(UINT resourceId);
|
||||
|
||||
/// Determines if two strings are case-insensitive equals
|
||||
///
|
||||
/// @param left - one of the two strings
|
||||
/// @param right - the other of the two strings
|
||||
/// @return true if the strings equal, false otherwise
|
||||
bool CaseInsensitiveEquals(const std::wstring& left, const std::wstring& right);
|
||||
|
||||
//
|
||||
// A designated memory allocator
|
||||
//
|
||||
// Parameters:
|
||||
// cb - The size of memory
|
||||
//
|
||||
inline LPVOID STDMETHODCALLTYPE MyAllocate(SIZE_T cb) { return std::malloc(cb); }
|
||||
|
||||
//
|
||||
// A designated memory freeing method
|
||||
//
|
||||
// Parameters:
|
||||
// pv - A pointer to the file to release
|
||||
//
|
||||
inline void STDMETHODCALLTYPE MyFree(LPVOID pv) { std::free(pv); }
|
||||
|
||||
//
|
||||
// Stripped down ComPtr class provided for those platforms that do not already have a ComPtr class.
|
||||
//
|
||||
template <class T>
|
||||
class ComPtr
|
||||
{
|
||||
public:
|
||||
// default ctor
|
||||
ComPtr() = default;
|
||||
ComPtr(T* ptr) : m_ptr(ptr) { InternalAddRef(); }
|
||||
|
||||
~ComPtr() { InternalRelease(); }
|
||||
inline T* operator->() const { return m_ptr; }
|
||||
inline T* Get() const { return m_ptr; }
|
||||
|
||||
inline T** operator&()
|
||||
{
|
||||
InternalRelease();
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
inline T* operator=(__in_opt T* ptr) throw()
|
||||
{
|
||||
InternalRelease();
|
||||
m_ptr = ptr;
|
||||
InternalAddRef();
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
void Release() { InternalRelease(); }
|
||||
|
||||
protected:
|
||||
T * m_ptr = nullptr;
|
||||
|
||||
inline void InternalAddRef() { if (m_ptr) { m_ptr->AddRef(); } }
|
||||
inline void InternalRelease()
|
||||
{
|
||||
T* temp = m_ptr;
|
||||
if (temp)
|
||||
{
|
||||
m_ptr = nullptr;
|
||||
temp->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class AutoPtr
|
||||
{
|
||||
public:
|
||||
AutoPtr() = default;
|
||||
AutoPtr(T * ptr) : m_ptr(ptr) {}
|
||||
|
||||
~AutoPtr() { delete m_ptr; }
|
||||
void Free() { delete m_ptr; m_ptr = 0; }
|
||||
|
||||
inline T* Detach()
|
||||
{
|
||||
T* old = m_ptr;
|
||||
m_ptr = 0;
|
||||
return old;
|
||||
}
|
||||
|
||||
inline operator const T* () const
|
||||
{
|
||||
return (T*)m_ptr;
|
||||
}
|
||||
|
||||
inline operator T* ()
|
||||
{
|
||||
return (T*)m_ptr;
|
||||
}
|
||||
|
||||
inline const T& operator*() const
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
inline T& operator*()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
inline const T* Get() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline T* Get()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline T** operator&()
|
||||
{
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
inline T** AddressOf()
|
||||
{
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
inline T** FreeAndAddressOf()
|
||||
{
|
||||
Free();
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
inline const T* operator->() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
inline T* operator->()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline T* operator=(T* ptr)
|
||||
{
|
||||
if (m_ptr != ptr)
|
||||
{
|
||||
delete m_ptr;
|
||||
m_ptr = ptr;
|
||||
}
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
T* m_ptr = nullptr;
|
||||
};
|
||||
|
||||
//
|
||||
// Helper class to free string buffers obtained from the packaging APIs.
|
||||
//
|
||||
template<typename T>
|
||||
class Text
|
||||
{
|
||||
public:
|
||||
T** operator&() { return &content; }
|
||||
~Text() { Cleanup(); }
|
||||
T* Get() { return content; }
|
||||
|
||||
T* content = nullptr;
|
||||
protected:
|
||||
void Cleanup() { if (content) { MyFree(content); content = nullptr; } }
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Helper class to free string buffers created using OLE memory allocator.
|
||||
//
|
||||
template<typename T>
|
||||
class TextOle
|
||||
{
|
||||
public:
|
||||
T** operator&() { return &content; }
|
||||
~TextOle() { Cleanup(); }
|
||||
T* Get() { return content; }
|
||||
|
||||
T* content = nullptr;
|
||||
protected:
|
||||
void Cleanup() { if (content) { CoTaskMemFree(content); content = nullptr; } }
|
||||
};
|
||||
|
||||
HRESULT GetAttributeValueFromElement(IMsixElement* element, std::wstring attributeName, std::wstring& attributeValue);
|
||||
/// The manifest ID is missing the curly braces;
|
||||
/// This adds the curly braces to convert it into a proper Guid form.
|
||||
std::wstring GuidFromManifestId(std::wstring id);
|
||||
|
||||
HRESULT FileExists(std::wstring file, _Out_ bool &exists);
|
|
@ -7,8 +7,9 @@
|
|||
#include "ValidateTargetDeviceFamily.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
#include <VersionHelpers.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
const PCWSTR ValidateTargetDeviceFamily::HandlerName = L"ValidateTargetDeviceFamily";
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
class ValidateTargetDeviceFamily : IPackageHandler
|
||||
{
|
||||
|
|
|
@ -13,16 +13,21 @@
|
|||
#include "CommandLineInterface.hpp"
|
||||
#include "Win7MSIXInstallerLogger.hpp"
|
||||
#include "Util.hpp"
|
||||
#include "..\Win7MSIXInstallerLib\GeneralUtil.hpp"
|
||||
#include "resource.h"
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
#include <Win7MSIXInstallerActions.hpp>
|
||||
using namespace std;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_MsixTraceLoggingProvider);
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
// Register the provider
|
||||
// Register the providers
|
||||
TraceLoggingRegister(g_MsixUITraceLoggingProvider);
|
||||
TraceLoggingRegister(g_MsixTraceLoggingProvider);
|
||||
|
||||
HRESULT hrCoInitialize = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
if (FAILED(hrCoInitialize))
|
||||
|
@ -40,8 +45,8 @@ int main(int argc, char * argv[])
|
|||
{
|
||||
case OperationType::Add:
|
||||
{
|
||||
AutoPtr<Win7MsixInstallerLib::IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(Win7MsixInstallerLib_CreatePackageManager(&packageManager));
|
||||
AutoPtr<IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(MsixCoreLib_CreatePackageManager(&packageManager));
|
||||
|
||||
if (cli.IsQuietMode())
|
||||
{
|
||||
|
@ -61,8 +66,8 @@ int main(int argc, char * argv[])
|
|||
}
|
||||
case OperationType::Remove:
|
||||
{
|
||||
AutoPtr<Win7MsixInstallerLib::IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(Win7MsixInstallerLib_CreatePackageManager(&packageManager));
|
||||
AutoPtr<IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(MsixCoreLib_CreatePackageManager(&packageManager));
|
||||
|
||||
auto packageFullName = cli.GetPackageFullName();
|
||||
auto res = packageManager->RemovePackage(packageFullName);
|
||||
|
@ -74,10 +79,10 @@ int main(int argc, char * argv[])
|
|||
}
|
||||
case OperationType::FindPackage:
|
||||
{
|
||||
AutoPtr<Win7MsixInstallerLib::IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(Win7MsixInstallerLib_CreatePackageManager(&packageManager));
|
||||
AutoPtr<IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(MsixCoreLib_CreatePackageManager(&packageManager));
|
||||
|
||||
shared_ptr<Win7MsixInstallerLib::IInstalledPackage> packageInfo = packageManager->FindPackage(cli.GetPackageFullName());
|
||||
shared_ptr<IInstalledPackage> packageInfo = packageManager->FindPackage(cli.GetPackageFullName());
|
||||
if (packageInfo == NULL)
|
||||
{
|
||||
std::wcout << std::endl;
|
||||
|
@ -96,8 +101,8 @@ int main(int argc, char * argv[])
|
|||
}
|
||||
case OperationType::FindAllPackages:
|
||||
{
|
||||
AutoPtr<Win7MsixInstallerLib::IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(Win7MsixInstallerLib_CreatePackageManager(&packageManager));
|
||||
AutoPtr<IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(MsixCoreLib_CreatePackageManager(&packageManager));
|
||||
|
||||
auto packages = packageManager->FindPackages();
|
||||
|
||||
|
@ -120,9 +125,9 @@ int main(int argc, char * argv[])
|
|||
cli.DisplayHelp();
|
||||
}
|
||||
|
||||
|
||||
// Stop TraceLogging and unregister the provider
|
||||
// Stop TraceLogging and unregister the providers
|
||||
TraceLoggingUnregister(g_MsixUITraceLoggingProvider);
|
||||
TraceLoggingUnregister(g_MsixTraceLoggingProvider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@
|
|||
<AdditionalLibraryDirectories>..\Debug;..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>win7msixinstallerlib.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>win7msixinstallerlib.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;version.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
|
@ -122,7 +122,7 @@
|
|||
<AdditionalLibraryDirectories>..\x64\Debug;..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>win7msixinstallerlib.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>win7msixinstallerlib.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;version.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
|
@ -153,7 +153,7 @@
|
|||
<AdditionalLibraryDirectories>..\Release;..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>win7msixinstallerlib.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>win7msixinstallerlib.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;version.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
|
@ -180,7 +180,7 @@
|
|||
<AdditionalLibraryDirectories>..\x64\Release;..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>win7msixinstallerlib.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>win7msixinstallerlib.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;version.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
|
@ -190,16 +190,16 @@
|
|||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Util.hpp" />
|
||||
<ClInclude Include="CommandLineInterface.hpp" />
|
||||
<ClInclude Include="InstallUI.hpp" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="Util.hpp" />
|
||||
<ClInclude Include="Win7MSIXInstallerLogger.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Util.cpp" />
|
||||
<ClCompile Include="InstallUI.cpp" />
|
||||
<ClCompile Include="CommandLineInterface.cpp" />
|
||||
<ClCompile Include="Util.cpp" />
|
||||
<ClCompile Include="Win7MSIXInstaller.cpp" />
|
||||
<ClCompile Include="Win7MSIXInstallerLogger.cpp" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -27,18 +27,9 @@
|
|||
<ClInclude Include="Win7MSIXInstallerLogger.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ComInterface.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ComServer.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Util.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ValidateTargetDeviceFamily.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="InstallUI.cpp">
|
||||
|
@ -53,18 +44,9 @@
|
|||
<ClCompile Include="Win7MSIXInstaller.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ComInterface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ComServer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ValidateTargetDeviceFamily.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Win7MSIXInstaller.rc">
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#include "Win7MSIXInstallerLogger.hpp"
|
||||
// Define the GUID to use in TraceLoggingProviderRegister
|
||||
// {035426d5-d599-48e0-868d-c59f15901637}
|
||||
// {db5b779e-2dcf-41bc-ab0e-40a6e02f1438}
|
||||
// One way to enable:
|
||||
// logman create trace <nameoftrace> -p "{035426d5-d599-48e0-868d-c59f15901637}" -o <filename>
|
||||
// i.e. logman create trace MsixTrace -p "{035426d5-d599-48e0-868d-c59f15901637}" -o c:\msixtrace.etl
|
||||
// logman create trace <nameoftrace> -p "{db5b779e-2dcf-41bc-ab0e-40a6e02f1438}" -o <filename>
|
||||
// i.e. logman create trace MsixTrace -p "{db5b779e-2dcf-41bc-ab0e-40a6e02f1438}" -o c:\msixtrace.etl
|
||||
// logman start MsixTrace
|
||||
// logman stop MsixTrace
|
||||
// tracerpt.exe, Windows Performance Analyzer or other tools can be used to view the etl file.
|
||||
TRACELOGGING_DEFINE_PROVIDER(
|
||||
g_MsixUITraceLoggingProvider,
|
||||
"MsixInstallerUITraceLoggingProvider",
|
||||
(0x035426d5, 0xd599, 0x48e0, 0x86, 0x8d, 0xc5, 0x9f, 0x15, 0x90, 0x16, 0x37));
|
||||
g_MsixUITraceLoggingProvider,
|
||||
"MsixInstallerUITraceLoggingProvider",
|
||||
(0xdb5b779e, 0x2dcf, 0x41bc, 0xab, 0x0e, 0x40, 0xa6, 0xe0, 0x2f, 0x14, 0x38));
|
||||
|
|
|
@ -1,82 +1,80 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "MsixTraceLoggingProvider.hpp"
|
||||
#include <string>
|
||||
#include <codecvt>
|
||||
#include <iostream>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
TRACELOGGING_DEFINE_PROVIDER(
|
||||
g_MsixTraceLoggingProvider,
|
||||
"MsixTraceLoggingProvider",
|
||||
(0x033321d3, 0xd599, 0x48e0, 0x86, 0x8d, 0xc5, 0x9f, 0x15, 0x90, 0x16, 0x37));
|
||||
|
||||
/// Converts a wstring from utf16 to utf8
|
||||
///
|
||||
/// @param utf16string - A utf16 wstring
|
||||
/// @return utf8 string
|
||||
std::string Win7MsixInstallerLib_utf16_to_utf8(const std::wstring& utf16string)
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8<wchar_t>>{}.to_bytes(utf16string.data());
|
||||
std::string result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Helper to convert version number to a version string of the form a.b.c.d
|
||||
///
|
||||
/// @param version - version number
|
||||
/// @return a.b.c.d string representation of version
|
||||
std::wstring Win7MsixInstallerLib_ConvertVersionToString(UINT64 version)
|
||||
{
|
||||
return std::to_wstring((version >> 0x30) & 0xFFFF) + L"."
|
||||
+ std::to_wstring((version >> 0x20) & 0xFFFF) + L"."
|
||||
+ std::to_wstring((version >> 0x10) & 0xFFFF) + L"."
|
||||
+ std::to_wstring((version) & 0xFFFF);
|
||||
}
|
||||
|
||||
std::wstring Win7MsixInstallerLib_GetFamilyNameFromFullName(const std::wstring& fullName)
|
||||
{
|
||||
return fullName.substr(0, fullName.find(L"_")) + fullName.substr(fullName.find_last_of(L"_"));
|
||||
}
|
||||
|
||||
bool Win7MsixInstallerLib_CaseInsensitiveEquals(const std::wstring& left, const std::wstring& right)
|
||||
{
|
||||
return (_wcsicmp(left.c_str(), right.c_str()) == 0);
|
||||
}
|
||||
|
||||
HRESULT GetAttributeValueFromElement(IMsixElement * element, const std::wstring attributeName, std::wstring & attributeValue)
|
||||
{
|
||||
Text<wchar_t> textValue;
|
||||
RETURN_IF_FAILED(element->GetAttributeValue(attributeName.c_str(), &textValue));
|
||||
if (textValue.Get() != nullptr)
|
||||
std::string utf16_to_utf8(const std::wstring& utf16string)
|
||||
{
|
||||
attributeValue = textValue.Get();
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8<wchar_t>>{}.to_bytes(utf16string.data());
|
||||
std::string result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
std::wstring GuidFromManifestId(std::wstring id)
|
||||
{
|
||||
return L"{" + id + L"}";
|
||||
}
|
||||
|
||||
HRESULT FileExists(std::wstring file, _Out_ bool &exists)
|
||||
{
|
||||
DWORD fileAttributes = GetFileAttributesW(file.c_str());
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
std::wstring utf8_to_utf16(const std::string& utf8string)
|
||||
{
|
||||
DWORD lastError = GetLastError();
|
||||
if ((lastError == ERROR_FILE_NOT_FOUND) || (lastError == ERROR_PATH_NOT_FOUND))
|
||||
// see https://connect.microsoft.com/VisualStudio/feedback/details/1403302/unresolved-external-when-using-codecvt-utf8
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8_utf16<unsigned short>, unsigned short>{}.from_bytes(utf8string.data());
|
||||
std::wstring result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring ConvertVersionToString(UINT64 version)
|
||||
{
|
||||
return std::to_wstring((version >> 0x30) & 0xFFFF) + L"."
|
||||
+ std::to_wstring((version >> 0x20) & 0xFFFF) + L"."
|
||||
+ std::to_wstring((version >> 0x10) & 0xFFFF) + L"."
|
||||
+ std::to_wstring((version) & 0xFFFF);
|
||||
}
|
||||
|
||||
std::wstring GetFamilyNameFromFullName(const std::wstring& fullName)
|
||||
{
|
||||
return fullName.substr(0, fullName.find(L"_")) + fullName.substr(fullName.find_last_of(L"_"));
|
||||
}
|
||||
|
||||
bool CaseInsensitiveEquals(const std::wstring& left, const std::wstring& right)
|
||||
{
|
||||
return (_wcsicmp(left.c_str(), right.c_str()) == 0);
|
||||
}
|
||||
|
||||
HRESULT GetAttributeValueFromElement(IMsixElement * element, const std::wstring attributeName, std::wstring & attributeValue)
|
||||
{
|
||||
Text<wchar_t> textValue;
|
||||
RETURN_IF_FAILED(element->GetAttributeValue(attributeName.c_str(), &textValue));
|
||||
if (textValue.Get() != nullptr)
|
||||
{
|
||||
exists = false;
|
||||
attributeValue = textValue.Get();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
std::wstring GuidFromManifestId(std::wstring id)
|
||||
{
|
||||
return L"{" + id + L"}";
|
||||
}
|
||||
|
||||
HRESULT FileExists(std::wstring file, _Out_ bool &exists)
|
||||
{
|
||||
DWORD fileAttributes = GetFileAttributesW(file.c_str());
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
DWORD lastError = GetLastError();
|
||||
if ((lastError == ERROR_FILE_NOT_FOUND) || (lastError == ERROR_PATH_NOT_FOUND))
|
||||
{
|
||||
exists = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HRESULT_FROM_WIN32(lastError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return HRESULT_FROM_WIN32(lastError);
|
||||
exists = true;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
exists = true;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
|
@ -1,242 +1,302 @@
|
|||
#pragma once
|
||||
#include <windows.h>
|
||||
#include "AppxPackaging.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include <winmeta.h>
|
||||
#include <string.h>
|
||||
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_MsixTraceLoggingProvider);
|
||||
|
||||
// Definition of function to return error if failed
|
||||
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||
#define RETURN_IF_FAILED(a) \
|
||||
{ \
|
||||
HRESULT __hr = a; \
|
||||
if (FAILED(__hr)) \
|
||||
{ \
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider, \
|
||||
"RETURN_IF_FAILED", \
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_ERROR), \
|
||||
TraceLoggingValue(#a, "Code"), \
|
||||
TraceLoggingHResult(__hr, "HR"), \
|
||||
TraceLoggingUInt32(__LINE__, "Line"), \
|
||||
TraceLoggingValue(__FILENAME__, "Filename")); \
|
||||
return __hr; \
|
||||
} \
|
||||
}
|
||||
|
||||
//
|
||||
// Converts a wstring from utf16 to utf8
|
||||
//
|
||||
// Parameters:
|
||||
// utf16string - A utf16 wstring
|
||||
//
|
||||
std::string Win7MsixInstallerLib_utf16_to_utf8(const std::wstring& utf16string);
|
||||
|
||||
|
||||
// Helper to convert version number to a version number string
|
||||
std::wstring Win7MsixInstallerLib_ConvertVersionToString(UINT64 version);
|
||||
|
||||
//
|
||||
// A designated memory allocator
|
||||
//
|
||||
// Parameters:
|
||||
// cb - The size of memory
|
||||
//
|
||||
inline LPVOID STDMETHODCALLTYPE Win7MsixInstallerLib_MyAllocate(SIZE_T cb) { return std::malloc(cb); }
|
||||
|
||||
//
|
||||
// A designated memory freeing method
|
||||
//
|
||||
// Parameters:
|
||||
// pv - A pointer to the file to release
|
||||
//
|
||||
inline void STDMETHODCALLTYPE Win7MsixInstallerLib_MyFree(LPVOID pv) { std::free(pv); }
|
||||
|
||||
/// Converts a packageFullName (i.e. examplePackageName_1.0.0.0_x64_resourceId_8wekyb3d8bbwe)
|
||||
/// into a packageFamilyName (i.e. examplePackageName_8wekyb3d8bbwe)
|
||||
///
|
||||
/// @param fullName - the packageFullName, assumed to be properly formatted and not validated.
|
||||
/// @return packageFamilyName for the packageFullName
|
||||
std::wstring Win7MsixInstallerLib_GetFamilyNameFromFullName(const std::wstring& fullName);
|
||||
|
||||
/// Determines if two strings are case-insensitive equals
|
||||
///
|
||||
/// @param left - one of the two strings
|
||||
/// @param right - the other of the two strings
|
||||
/// @return true if the strings equal, false otherwise
|
||||
bool Win7MsixInstallerLib_CaseInsensitiveEquals(const std::wstring& left, const std::wstring& right);
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
namespace MsixCoreLib
|
||||
{
|
||||
//
|
||||
// Stripped down ComPtr class provided for those platforms that do not already have a ComPtr class.
|
||||
//
|
||||
template <class T>
|
||||
class ComPtr
|
||||
{
|
||||
public:
|
||||
// default ctor
|
||||
ComPtr() = default;
|
||||
ComPtr(T* ptr) : m_ptr(ptr) { InternalAddRef(); }
|
||||
//
|
||||
// Converts a wstring from utf16 to utf8
|
||||
//
|
||||
// Parameters:
|
||||
// utf16string - A utf16 wstring
|
||||
//
|
||||
std::string utf16_to_utf8(const std::wstring& utf16string);
|
||||
|
||||
~ComPtr() { InternalRelease(); }
|
||||
inline T* operator->() const { return m_ptr; }
|
||||
inline T* Get() const { return m_ptr; }
|
||||
/// Converts a string from utf8 to utf16
|
||||
///
|
||||
/// @param utf8string - A utf8 string
|
||||
/// @return utf16 string
|
||||
std::wstring utf8_to_utf16(const std::string& utf8string);
|
||||
|
||||
inline T** operator&()
|
||||
{
|
||||
InternalRelease();
|
||||
return &m_ptr;
|
||||
}
|
||||
// Helper to convert version number to a version number string
|
||||
std::wstring ConvertVersionToString(UINT64 version);
|
||||
|
||||
inline T* operator=(__in_opt T* ptr) throw()
|
||||
{
|
||||
InternalRelease();
|
||||
m_ptr = ptr;
|
||||
InternalAddRef();
|
||||
return m_ptr;
|
||||
}
|
||||
//
|
||||
// A designated memory allocator
|
||||
//
|
||||
// Parameters:
|
||||
// cb - The size of memory
|
||||
//
|
||||
inline LPVOID STDMETHODCALLTYPE MyAllocate(SIZE_T cb) { return std::malloc(cb); }
|
||||
|
||||
void Release() { InternalRelease(); }
|
||||
//
|
||||
// A designated memory freeing method
|
||||
//
|
||||
// Parameters:
|
||||
// pv - A pointer to the file to release
|
||||
//
|
||||
inline void STDMETHODCALLTYPE MyFree(LPVOID pv) { std::free(pv); }
|
||||
|
||||
protected:
|
||||
T * m_ptr = nullptr;
|
||||
/// Converts a packageFullName (i.e. examplePackageName_1.0.0.0_x64_resourceId_8wekyb3d8bbwe)
|
||||
/// into a packageFamilyName (i.e. examplePackageName_8wekyb3d8bbwe)
|
||||
///
|
||||
/// @param fullName - the packageFullName, assumed to be properly formatted and not validated.
|
||||
/// @return packageFamilyName for the packageFullName
|
||||
std::wstring GetFamilyNameFromFullName(const std::wstring& fullName);
|
||||
|
||||
inline void InternalAddRef() { if (m_ptr) { m_ptr->AddRef(); } }
|
||||
inline void InternalRelease()
|
||||
{
|
||||
T* temp = m_ptr;
|
||||
if (temp)
|
||||
{
|
||||
m_ptr = nullptr;
|
||||
temp->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
/// Determines if two strings are case-insensitive equals
|
||||
///
|
||||
/// @param left - one of the two strings
|
||||
/// @param right - the other of the two strings
|
||||
/// @return true if the strings equal, false otherwise
|
||||
bool CaseInsensitiveEquals(const std::wstring& left, const std::wstring& right);
|
||||
|
||||
template <class T>
|
||||
class AutoPtr
|
||||
{
|
||||
public:
|
||||
AutoPtr() = default;
|
||||
AutoPtr(T * ptr) : m_ptr(ptr) {}
|
||||
//
|
||||
// Stripped down ComPtr class provided for those platforms that do not already have a ComPtr class.
|
||||
//
|
||||
template <class T>
|
||||
class ComPtr
|
||||
{
|
||||
public:
|
||||
// default ctor
|
||||
ComPtr() = default;
|
||||
ComPtr(T* ptr) : m_ptr(ptr) { InternalAddRef(); }
|
||||
|
||||
~AutoPtr() { delete m_ptr; }
|
||||
void Free() { delete m_ptr; m_ptr = 0; }
|
||||
~ComPtr() { InternalRelease(); }
|
||||
inline T* operator->() const { return m_ptr; }
|
||||
inline T* Get() const { return m_ptr; }
|
||||
|
||||
inline T* Detach()
|
||||
{
|
||||
T* old = m_ptr;
|
||||
m_ptr = 0;
|
||||
return old;
|
||||
}
|
||||
inline T** operator&()
|
||||
{
|
||||
InternalRelease();
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
inline operator const T* () const
|
||||
{
|
||||
return (T*)m_ptr;
|
||||
}
|
||||
inline T* operator=(__in_opt T* ptr) throw()
|
||||
{
|
||||
InternalRelease();
|
||||
m_ptr = ptr;
|
||||
InternalAddRef();
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline operator T* ()
|
||||
{
|
||||
return (T*)m_ptr;
|
||||
}
|
||||
void Release() { InternalRelease(); }
|
||||
|
||||
inline const T& operator*() const
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
inline T& operator*()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
protected:
|
||||
T * m_ptr = nullptr;
|
||||
|
||||
inline const T* Get() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
inline void InternalAddRef() { if (m_ptr) { m_ptr->AddRef(); } }
|
||||
inline void InternalRelease()
|
||||
{
|
||||
T* temp = m_ptr;
|
||||
if (temp)
|
||||
{
|
||||
m_ptr = nullptr;
|
||||
temp->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline T* Get()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
template <class T>
|
||||
class AutoPtr
|
||||
{
|
||||
public:
|
||||
AutoPtr() = default;
|
||||
AutoPtr(T * ptr) : m_ptr(ptr) {}
|
||||
|
||||
inline T** operator&()
|
||||
{
|
||||
return &m_ptr;
|
||||
}
|
||||
~AutoPtr() { delete m_ptr; }
|
||||
void Free() { delete m_ptr; m_ptr = 0; }
|
||||
|
||||
inline T** AddressOf()
|
||||
{
|
||||
return &m_ptr;
|
||||
}
|
||||
inline T* Detach()
|
||||
{
|
||||
T* old = m_ptr;
|
||||
m_ptr = 0;
|
||||
return old;
|
||||
}
|
||||
|
||||
inline T** FreeAndAddressOf()
|
||||
{
|
||||
Free();
|
||||
return &m_ptr;
|
||||
}
|
||||
inline operator const T* () const
|
||||
{
|
||||
return (T*)m_ptr;
|
||||
}
|
||||
|
||||
inline const T* operator->() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
inline T* operator->()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
inline operator T* ()
|
||||
{
|
||||
return (T*)m_ptr;
|
||||
}
|
||||
|
||||
inline T* operator=(T* ptr)
|
||||
{
|
||||
if (m_ptr != ptr)
|
||||
{
|
||||
delete m_ptr;
|
||||
m_ptr = ptr;
|
||||
}
|
||||
return m_ptr;
|
||||
}
|
||||
inline const T& operator*() const
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
inline T& operator*()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
T* m_ptr = nullptr;
|
||||
};
|
||||
inline const T* Get() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Helper class to free string buffers obtained from the packaging APIs.
|
||||
//
|
||||
template<typename T>
|
||||
class Text
|
||||
{
|
||||
public:
|
||||
T** operator&() { return &content; }
|
||||
~Text() { Cleanup(); }
|
||||
T* Get() { return content; }
|
||||
inline T* Get()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T* content = nullptr;
|
||||
protected:
|
||||
void Cleanup() { if (content) { Win7MsixInstallerLib_MyFree(content); content = nullptr; } }
|
||||
};
|
||||
inline T** operator&()
|
||||
{
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
inline T** AddressOf()
|
||||
{
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
inline T** FreeAndAddressOf()
|
||||
{
|
||||
Free();
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
inline const T* operator->() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
inline T* operator->()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline T* operator=(T* ptr)
|
||||
{
|
||||
if (m_ptr != ptr)
|
||||
{
|
||||
delete m_ptr;
|
||||
m_ptr = ptr;
|
||||
}
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
T* m_ptr = nullptr;
|
||||
};
|
||||
|
||||
//
|
||||
// Helper class to free string buffers obtained from the packaging APIs.
|
||||
//
|
||||
template<typename T>
|
||||
class Text
|
||||
{
|
||||
public:
|
||||
T** operator&() { return &content; }
|
||||
~Text() { Cleanup(); }
|
||||
T* Get() { return content; }
|
||||
|
||||
T* content = nullptr;
|
||||
protected:
|
||||
void Cleanup() { if (content) { MyFree(content); content = nullptr; } }
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Helper class to free string buffers created using OLE memory allocator.
|
||||
//
|
||||
template<typename T>
|
||||
class TextOle
|
||||
{
|
||||
public:
|
||||
T** operator&() { return &content; }
|
||||
~TextOle() { Cleanup(); }
|
||||
T* Get() { return content; }
|
||||
//
|
||||
// Helper class to free string buffers created using OLE memory allocator.
|
||||
//
|
||||
template<typename T>
|
||||
class TextOle
|
||||
{
|
||||
public:
|
||||
T** operator&() { return &content; }
|
||||
~TextOle() { Cleanup(); }
|
||||
T* Get() { return content; }
|
||||
|
||||
T* content = nullptr;
|
||||
protected:
|
||||
void Cleanup() { if (content) { CoTaskMemFree(content); content = nullptr; } }
|
||||
};
|
||||
}
|
||||
T* content = nullptr;
|
||||
protected:
|
||||
void Cleanup() { if (content) { CoTaskMemFree(content); content = nullptr; } }
|
||||
};
|
||||
|
||||
HRESULT GetAttributeValueFromElement(IMsixElement* element, std::wstring attributeName, std::wstring& attributeValue);
|
||||
/// The manifest ID is missing the curly braces;
|
||||
/// This adds the curly braces to convert it into a proper Guid form.
|
||||
std::wstring GuidFromManifestId(std::wstring id);
|
||||
|
||||
HRESULT FileExists(std::wstring file, _Out_ bool &exists);
|
||||
HRESULT GetAttributeValueFromElement(IMsixElement* element, std::wstring attributeName, std::wstring& attributeValue);
|
||||
/// The manifest ID is missing the curly braces;
|
||||
/// This adds the curly braces to convert it into a proper Guid form.
|
||||
std::wstring GuidFromManifestId(std::wstring id);
|
||||
|
||||
HRESULT FileExists(std::wstring file, _Out_ bool &exists);
|
||||
|
||||
class AutoCoInitialize
|
||||
{
|
||||
public:
|
||||
inline AutoCoInitialize()
|
||||
: hr(CO_E_NOTINITIALIZED)
|
||||
{
|
||||
}
|
||||
|
||||
inline ~AutoCoInitialize()
|
||||
{
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
Uninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
inline HRESULT Initialize(
|
||||
_In_ DWORD threadingModel = COINIT_MULTITHREADED)
|
||||
{
|
||||
HRESULT hr = CoInitializeEx(NULL, threadingModel);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
this->hr = hr;
|
||||
}
|
||||
else if (hr == RPC_E_CHANGED_MODE)
|
||||
{
|
||||
// Thread was already initialized with a different apartment model, don't need to initialize again.
|
||||
// But leave this->hr as a FAILED value as we didn't successfully initialize COM so we better not uninitialize it later
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline void Uninitialize()
|
||||
{
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CoUninitialize();
|
||||
this->hr = CO_E_NOTINITIALIZED;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Actions Not Supported
|
||||
AutoCoInitialize(_In_ const AutoCoInitialize&);
|
||||
AutoCoInitialize& operator=(_In_ const AutoCoInitialize&);
|
||||
|
||||
private:
|
||||
HRESULT hr;
|
||||
};
|
||||
|
||||
class Bstr
|
||||
{
|
||||
BSTR m_bstr;
|
||||
public:
|
||||
operator BSTR() && = delete;
|
||||
operator BSTR() & { return m_bstr; }
|
||||
Bstr() { m_bstr = nullptr; }
|
||||
Bstr(std::wstring text)
|
||||
{
|
||||
m_bstr = ::SysAllocStringLen(text.c_str(), static_cast<UINT>(text.length()));
|
||||
}
|
||||
~Bstr() { ::SysFreeString(m_bstr); }
|
||||
|
||||
BSTR* AddressOf()
|
||||
{
|
||||
::SysFreeString(m_bstr);
|
||||
return &m_bstr;
|
||||
}
|
||||
|
||||
BSTR& Get() { return m_bstr; }
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#include "Win7MSIXInstallerLogger.hpp"
|
||||
|
||||
// Define the GUID to use in TraceLoggingProviderRegister
|
||||
// {033321d3-d599-48e0-868d-c59f15901637}
|
||||
// One way to enable:
|
||||
// logman create trace <nameoftrace> -p "{033321d3-d599-48e0-868d-c59f15901637}" -o <filename>
|
||||
// i.e. logman create trace MsixTrace -p "{033321d3-d599-48e0-868d-c59f15901637}" -o c:\msixtrace.etl
|
||||
// logman start MsixTrace
|
||||
// logman stop MsixTrace
|
||||
// tracerpt.exe, Windows Performance Analyzer or other tools can be used to view the etl file.
|
||||
TRACELOGGING_DEFINE_PROVIDER(
|
||||
g_MsixTraceLoggingProvider,
|
||||
"MsixTraceLoggingProvider",
|
||||
(0x033321d3, 0xd599, 0x48e0, 0x86, 0x8d, 0xc5, 0x9f, 0x15, 0x90, 0x16, 0x37));
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <TraceLoggingProvider.h>
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_MsixTraceLoggingProvider);
|
||||
|
||||
|
||||
// Definition of function to return error if failed
|
||||
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||
#define RETURN_IF_FAILED(a) \
|
||||
{ \
|
||||
HRESULT __hr = a; \
|
||||
if (FAILED(__hr)) \
|
||||
{ \
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider, \
|
||||
"RETURN_IF_FAILED", \
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_ERROR), \
|
||||
TraceLoggingValue(#a, "Code"), \
|
||||
TraceLoggingHResult(__hr, "HR"), \
|
||||
TraceLoggingUInt32(__LINE__, "Line"), \
|
||||
TraceLoggingValue(__FILENAME__, "Filename")); \
|
||||
return __hr; \
|
||||
} \
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
#include <thread>
|
||||
|
||||
using namespace std;
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
PackageManager::PackageManager()
|
||||
{
|
||||
|
@ -116,8 +116,8 @@ shared_ptr<IInstalledPackage> PackageManager::FindPackageByFamilyName(const wstr
|
|||
for (auto& p : experimental::filesystem::directory_iterator(msix7Directory))
|
||||
{
|
||||
|
||||
auto installedAppFamilyName = Win7MsixInstallerLib_GetFamilyNameFromFullName(p.path().filename());
|
||||
if (Win7MsixInstallerLib_CaseInsensitiveEquals(installedAppFamilyName, packageFamilyName))
|
||||
auto installedAppFamilyName = GetFamilyNameFromFullName(p.path().filename());
|
||||
if (CaseInsensitiveEquals(installedAppFamilyName, packageFamilyName))
|
||||
{
|
||||
return GetPackageInfo(msix7Directory, p.path());
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "inc/IPackageManager.hpp"
|
||||
#include "inc/IPackage.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib {
|
||||
namespace MsixCoreLib {
|
||||
|
||||
class PackageManager :
|
||||
public IPackageManager
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "Win7MSIXInstallerActions.hpp"
|
||||
#include "PackageManager.hpp"
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
using namespace MsixCoreLib;
|
||||
|
||||
HRESULT Win7MsixInstallerLib_CreatePackageManager(Win7MsixInstallerLib::IPackageManager** packageManager)
|
||||
HRESULT MsixCoreLib_CreatePackageManager(MsixCoreLib::IPackageManager** packageManager)
|
||||
{
|
||||
*packageManager = new PackageManager();
|
||||
return S_OK;
|
||||
|
|
|
@ -189,6 +189,7 @@
|
|||
<ClInclude Include="..\Win7MSIXInstaller\ComServer.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\Constants.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\ErrorHandler.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\StartupTask.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\ValidateTargetDeviceFamily.hpp" />
|
||||
<ClInclude Include="inc\IMsixResponse.hpp" />
|
||||
<ClInclude Include="inc\DeploymentOptions.hpp" />
|
||||
|
@ -204,6 +205,7 @@
|
|||
<ClInclude Include="inc\Win7MSIXInstallerActions.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\IPackageHandler.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\MsixResponse.hpp" />
|
||||
<ClInclude Include="MsixTraceLoggingProvider.hpp" />
|
||||
<ClInclude Include="PackageManager.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\Package.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\PopulatePackageInfo.hpp" />
|
||||
|
@ -222,9 +224,11 @@
|
|||
<ClCompile Include="..\Win7MSIXInstaller\FileTypeAssociation.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\InstallComplete.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\MsixRequest.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\StartupTask.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\ValidateTargetDeviceFamily.cpp" />
|
||||
<ClCompile Include="GeneralUtil.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\MsixResponse.cpp" />
|
||||
<ClCompile Include="MsixTraceLoggingProvider.cpp" />
|
||||
<ClCompile Include="PackageManager.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\Package.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\PopulatePackageInfo.cpp" />
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <functional>
|
||||
#include <windows.h>
|
||||
|
||||
namespace Win7MsixInstallerLib {
|
||||
namespace MsixCoreLib {
|
||||
|
||||
enum InstallationStep {
|
||||
InstallationStepUnknown,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <Windows.h>
|
||||
namespace Win7MsixInstallerLib {
|
||||
namespace MsixCoreLib {
|
||||
|
||||
class IPackage {
|
||||
public:
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "DeploymentOptions.hpp"
|
||||
|
||||
|
||||
namespace Win7MsixInstallerLib {
|
||||
namespace MsixCoreLib {
|
||||
class IPackageManager
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#include "IPackageManager.hpp"
|
||||
|
||||
extern "C" HRESULT Win7MsixInstallerLib_CreatePackageManager(Win7MsixInstallerLib::IPackageManager** packageManager);
|
||||
extern "C" HRESULT MsixCoreLib_CreatePackageManager(MsixCoreLib::IPackageManager** packageManager);
|
||||
|
|
Загрузка…
Ссылка в новой задаче