* 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:
wcheng-msft 2019-04-25 16:33:50 -07:00 коммит произвёл GitHub
Родитель d7017a0cc1
Коммит 7a22748c77
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
62 изменённых файлов: 791 добавлений и 634 удалений

Просмотреть файл

@ -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*/, &registeredTask));
}
}
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);