Split win7MsixInstaller in 2 parts: a standalone library and a .exe providing the UI. (#69)
* Split win7MsixInstaller in 2 parts * Add 2 synchronous method: AddPackage and RemovePackage * add callback to AddPackageAsync and RemovePackageAsync and convert all pointers to unique_ptr/shared_ptr * rename GetPackageInfoMsix to GetMsixPackageInfo add MsixResponse::SetErrorStatus * merge PackageBase::SetExecutableAndAppIdFromManifestElement and PackageBase::SetDisplayNameFromManifestElement + use package->GetPublisherDisplayName() instead of recomputing it in AddRemovePrograms
This commit is contained in:
Родитель
4497f4dab8
Коммит
f23aa1268b
|
@ -4,9 +4,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
VisualStudioVersion = 15.0.27703.2026
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win7MSIXInstaller", "Win7MSIXInstaller\Win7MSIXInstaller.vcxproj", "{AAD31763-5E65-47FD-958A-08E35AB83025}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064} = {46BE19BD-72E0-4452-9919-33A1F8A5F064}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Win7MSIXInstallerSetup", "Win7MSIXInstallerSetup\Win7MSIXInstallerSetup.vdproj", "{C79C79A4-00CE-40C8-BCCE-A5C8F28A4E8D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win7MSIXInstallerLib", "Win7MSIXInstallerLib\Win7MSIXInstallerLib.vcxproj", "{46BE19BD-72E0-4452-9919-33A1F8A5F064}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B0C6E315-832B-4665-B979-4111A8C2F93B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
|
@ -36,6 +41,14 @@ Global
|
|||
{C79C79A4-00CE-40C8-BCCE-A5C8F28A4E8D}.Debug|x86.ActiveCfg = Debug
|
||||
{C79C79A4-00CE-40C8-BCCE-A5C8F28A4E8D}.Release|x64.ActiveCfg = Release
|
||||
{C79C79A4-00CE-40C8-BCCE-A5C8F28A4E8D}.Release|x86.ActiveCfg = Release
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064}.Debug|x64.Build.0 = Debug|x64
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064}.Debug|x86.Build.0 = Debug|Win32
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064}.Release|x64.ActiveCfg = Release|x64
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064}.Release|x64.Build.0 = Release|x64
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064}.Release|x86.ActiveCfg = Release|Win32
|
||||
{46BE19BD-72E0-4452-9919-33A1F8A5F064}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "Constants.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR AddRemovePrograms::HandlerName = L"AddRemovePrograms";
|
||||
|
||||
|
@ -18,7 +19,7 @@ HRESULT AddRemovePrograms::ExecuteForAddRequest()
|
|||
return HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
|
||||
}
|
||||
|
||||
PackageInfo* packageInfo = m_msixRequest->GetPackageInfo();
|
||||
auto packageInfo = m_msixRequest->GetPackageInfo();
|
||||
std::wstring packageFullName = packageInfo->GetPackageFullName();
|
||||
|
||||
RegistryKey uninstallKey;
|
||||
|
@ -30,7 +31,7 @@ HRESULT AddRemovePrograms::ExecuteForAddRequest()
|
|||
std::wstring displayName = packageInfo->GetDisplayName();
|
||||
RETURN_IF_FAILED(packageKey.SetStringValue(L"DisplayName", displayName));
|
||||
|
||||
std::wstring directoryPath = packageInfo->GetPackageDirectoryPath();
|
||||
std::wstring directoryPath = m_msixRequest->GetPackageDirectoryPath();
|
||||
RETURN_IF_FAILED(packageKey.SetStringValue(L"InstallLocation", directoryPath));
|
||||
|
||||
WCHAR filePath[MAX_PATH];
|
||||
|
@ -43,15 +44,12 @@ HRESULT AddRemovePrograms::ExecuteForAddRequest()
|
|||
std::wstring uninstallCommand = filePath + std::wstring(L" -RemovePackage ") + packageFullName;
|
||||
RETURN_IF_FAILED(packageKey.SetStringValue(L"UninstallString", uninstallCommand));
|
||||
|
||||
std::wstring publisherString(packageInfo->GetPublisher());
|
||||
auto publisherCommonName = publisherString.substr(publisherString.find_first_of(L"=") + 1,
|
||||
publisherString.find_first_of(L",") - publisherString.find_first_of(L"=") - 1);
|
||||
RETURN_IF_FAILED(packageKey.SetStringValue(L"Publisher", publisherCommonName));
|
||||
RETURN_IF_FAILED(packageKey.SetStringValue(L"Publisher", packageInfo->GetPublisherDisplayName()));
|
||||
|
||||
std::wstring versionString(ConvertVersionToString(packageInfo->GetVersion()));
|
||||
auto versionString = packageInfo->GetVersion();
|
||||
RETURN_IF_FAILED(packageKey.SetStringValue(L"DisplayVersion", versionString));
|
||||
|
||||
std::wstring packageIconString = packageInfo->GetExecutableFilePath();
|
||||
std::wstring packageIconString = m_msixRequest->GetPackageDirectoryPath() + L"\\" + packageInfo->GetRelativeExecutableFilePath();
|
||||
RETURN_IF_FAILED(packageKey.SetStringValue(L"DisplayIcon", packageIconString));
|
||||
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
|
@ -60,7 +58,7 @@ HRESULT AddRemovePrograms::ExecuteForAddRequest()
|
|||
TraceLoggingValue(uninstallCommand.c_str(), "uninstallString"),
|
||||
TraceLoggingValue(displayName.c_str(), "displayName"),
|
||||
TraceLoggingValue(directoryPath.c_str(), "installLocation"),
|
||||
TraceLoggingValue(publisherString.c_str(), "publisher"),
|
||||
TraceLoggingValue(packageInfo->GetPublisher().c_str(), "publisher"),
|
||||
TraceLoggingValue(versionString.c_str(), "displayVersion"),
|
||||
TraceLoggingValue(packageIconString.c_str(), "displayIcon"));
|
||||
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// Handles adding/removing the entry that allows an app to show up in AddRemovePrograms in the Control Panel (appwiz.cpl)
|
||||
class AddRemovePrograms : IPackageHandler
|
||||
{
|
||||
|
@ -24,3 +27,4 @@ private:
|
|||
AddRemovePrograms(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
|
||||
};
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR ComInterface::HandlerName = L"ComInterface";
|
||||
|
||||
|
@ -85,7 +86,7 @@ HRESULT ComInterface::ProcessTypeLibForAddRequest(TypeLib& typeLib)
|
|||
RegistryKey win32Key;
|
||||
RETURN_IF_FAILED(localeIdKey.CreateSubKey(win32KeyName.c_str(), KEY_WRITE, &win32Key));
|
||||
|
||||
std::wstring win32FullPath = m_msixRequest->GetFilePathMappings()->GetExecutablePath(version->win32Path, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
std::wstring win32FullPath = FilePathMappings::GetInstance().GetExecutablePath(version->win32Path, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
RETURN_IF_FAILED(win32Key.SetStringValue(L"", win32FullPath));
|
||||
}
|
||||
|
||||
|
@ -94,7 +95,7 @@ HRESULT ComInterface::ProcessTypeLibForAddRequest(TypeLib& typeLib)
|
|||
RegistryKey win64Key;
|
||||
RETURN_IF_FAILED(localeIdKey.CreateSubKey(win64KeyName.c_str(), KEY_WRITE, &win64Key));
|
||||
|
||||
std::wstring win64FullPath = m_msixRequest->GetFilePathMappings()->GetExecutablePath(version->win64Path, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
std::wstring win64FullPath = FilePathMappings::GetInstance().GetExecutablePath(version->win64Path, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
RETURN_IF_FAILED(win64Key.SetStringValue(L"", win64FullPath));
|
||||
}
|
||||
|
||||
|
@ -110,7 +111,7 @@ HRESULT ComInterface::ProcessTypeLibForAddRequest(TypeLib& typeLib)
|
|||
RegistryKey helpDirKey;
|
||||
RETURN_IF_FAILED(versionNumberKey.CreateSubKey(helpDirKeyName.c_str(), KEY_WRITE, &helpDirKey));
|
||||
|
||||
std::wstring helpDirFullPath = m_msixRequest->GetFilePathMappings()->GetExecutablePath(version->helpDirectory, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
std::wstring helpDirFullPath = FilePathMappings::GetInstance().GetExecutablePath(version->helpDirectory, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
RETURN_IF_FAILED(helpDirKey.SetStringValue(L"", helpDirFullPath));
|
||||
}
|
||||
}
|
||||
|
@ -325,4 +326,4 @@ HRESULT ComInterface::CreateHandler(MsixRequest * msixRequest, IPackageHandler *
|
|||
*instance = localInstance.release();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
|
@ -2,8 +2,11 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "RegistryKey.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
class ComInterface : IPackageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -90,3 +93,4 @@ private:
|
|||
ComInterface(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
|
||||
};
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR ComServer::HandlerName = L"ComServer";
|
||||
|
||||
|
@ -52,7 +53,7 @@ HRESULT ComServer::ProcessExeServerForAdd(ExeServer& exeServer)
|
|||
RETURN_IF_FAILED(clsidKey.CreateSubKey(exeServerClass->id.c_str(), KEY_WRITE, &classIdKey));
|
||||
RETURN_IF_FAILED(classIdKey.SetStringValue(L"", exeServerClass->displayName));
|
||||
|
||||
std::wstring executableFullPath = m_msixRequest->GetFilePathMappings()->GetExecutablePath(exeServer.executable, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
std::wstring executableFullPath = FilePathMappings::GetInstance().GetExecutablePath(exeServer.executable, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
RegistryKey localServerKey;
|
||||
RETURN_IF_FAILED(classIdKey.CreateSubKey(localServerKeyName.c_str(), KEY_WRITE, &localServerKey));
|
||||
RETURN_IF_FAILED(localServerKey.SetStringValue(L"", executableFullPath));
|
||||
|
@ -652,7 +653,7 @@ HRESULT ComServer::ParseDefaultIcon(IMsixElement * classElement, ExeServerClass
|
|||
std::wstring resourceIndex;
|
||||
RETURN_IF_FAILED(GetAttributeValueFromElement(defaultIconElement.Get(), resourceIndexAttribute, resourceIndex));
|
||||
|
||||
std::wstring resolvedPath = m_msixRequest->GetFilePathMappings()->GetExecutablePath(path, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
std::wstring resolvedPath = FilePathMappings::GetInstance().GetExecutablePath(path, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
|
||||
exeServerClass.defaultIcon = std::wstring(L"\"") + resolvedPath + std::wstring(L"\",") + resourceIndex;
|
||||
}
|
||||
|
@ -677,7 +678,7 @@ HRESULT ComServer::ParseToolboxBitmap(IMsixElement * classElement, ExeServerClas
|
|||
std::wstring resourceIndex;
|
||||
RETURN_IF_FAILED(GetAttributeValueFromElement(toolboxBitmapElement.Get(), resourceIndexAttribute, resourceIndex));
|
||||
|
||||
std::wstring resolvedPath = m_msixRequest->GetFilePathMappings()->GetExecutablePath(path, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
std::wstring resolvedPath = FilePathMappings::GetInstance().GetExecutablePath(path, m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str());
|
||||
|
||||
exeServerClass.toolboxBitmap = std::wstring(L"\"") + resolvedPath + std::wstring(L"\",") + resourceIndex;
|
||||
}
|
||||
|
@ -700,4 +701,4 @@ HRESULT ComServer::CreateHandler(MsixRequest * msixRequest, IPackageHandler ** i
|
|||
*instance = localInstance.release();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
|
@ -2,8 +2,10 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "RegistryKey.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
class ComServer : IPackageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -169,4 +171,4 @@ private:
|
|||
ComServer(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "CommandLineInterface.hpp"
|
||||
#include "Win7MSIXInstallerLogger.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "Util.hpp"
|
||||
#include "resource.h"
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
std::map<std::wstring, Option, CaseInsensitiveLess> CommandLineInterface::s_options =
|
||||
{
|
||||
{
|
||||
|
@ -40,7 +43,7 @@ std::map<std::wstring, Option, CaseInsensitiveLess> CommandLineInterface::s_opti
|
|||
Option(false, IDS_STRING_HELP_OPTION_QUIETMODE,
|
||||
[&](CommandLineInterface* commandLineInterface, const std::string&)
|
||||
{
|
||||
commandLineInterface->m_flags |= Flags::QuietUX;
|
||||
commandLineInterface->m_quietMode = true;
|
||||
return S_OK;
|
||||
})
|
||||
},
|
||||
|
@ -98,11 +101,11 @@ void CommandLineInterface::DisplayHelp()
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT CommandLineInterface::CreateRequest(MsixRequest** msixRequest)
|
||||
HRESULT CommandLineInterface::Init()
|
||||
{
|
||||
for (int i = 0; i < m_argc; i++)
|
||||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
TraceLoggingWrite(g_MsixUITraceLoggingProvider,
|
||||
"CommandLineArguments",
|
||||
TraceLoggingValue(i, "index"),
|
||||
TraceLoggingValue(m_argv[i], "arg"));
|
||||
|
@ -126,7 +129,7 @@ HRESULT CommandLineInterface::CreateRequest(MsixRequest** msixRequest)
|
|||
auto option = s_options.find(optionString);
|
||||
if (option == s_options.end())
|
||||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
TraceLoggingWrite(g_MsixUITraceLoggingProvider,
|
||||
"Unknown Argument",
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
|
||||
TraceLoggingValue(m_argv[index], "arg"));
|
||||
|
@ -146,16 +149,5 @@ HRESULT CommandLineInterface::CreateRequest(MsixRequest** msixRequest)
|
|||
++index;
|
||||
}
|
||||
|
||||
AutoPtr<MsixRequest> localRequest;
|
||||
RETURN_IF_FAILED(MsixRequest::Make(
|
||||
m_operationType,
|
||||
m_flags,
|
||||
m_packageFilePath,
|
||||
m_packageFullName,
|
||||
m_validationOptions,
|
||||
&localRequest)
|
||||
);
|
||||
|
||||
*msixRequest = localRequest.Detach();
|
||||
return S_OK;
|
||||
}
|
|
@ -2,7 +2,16 @@
|
|||
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include "MsixRequest.hpp"
|
||||
#include <IPackage.hpp>
|
||||
#include <AppxPackaging.hpp>
|
||||
enum OperationType
|
||||
{
|
||||
Undefined = 0,
|
||||
Add = 1,
|
||||
Remove = 2,
|
||||
FindPackage = 3,
|
||||
FindAllPackages = 4,
|
||||
};
|
||||
|
||||
class CommandLineInterface;
|
||||
/// Describes an option to a command that the user may specify used for the command line tool
|
||||
|
@ -50,9 +59,11 @@ public:
|
|||
|
||||
/// Displays contextual formatted help to the user used for command line tool
|
||||
void DisplayHelp();
|
||||
|
||||
HRESULT CreateRequest(_Outptr_ MsixRequest** msixRequest);
|
||||
|
||||
HRESULT Init();
|
||||
bool IsQuietMode() { return m_quietMode; }
|
||||
std::wstring GetPackageFilePathToInstall() { return m_packageFilePath; }
|
||||
std::wstring GetPackageFullName() { return m_packageFullName; }
|
||||
OperationType GetOperationType() { return m_operationType; }
|
||||
private:
|
||||
int m_argc = 0;
|
||||
char ** m_argv = nullptr;
|
||||
|
@ -62,9 +73,8 @@ private:
|
|||
|
||||
std::wstring m_packageFilePath;
|
||||
std::wstring m_packageFullName;
|
||||
bool m_quietMode;
|
||||
|
||||
MSIX_VALIDATION_OPTION m_validationOptions = MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL;
|
||||
Flags m_flags = NoFlags;
|
||||
OperationType m_operationType = OperationType::Undefined;
|
||||
|
||||
CommandLineInterface() {}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <TraceLoggingProvider.h>
|
||||
#include "ErrorHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR ErrorHandler::HandlerName = L"ErrorHandler";
|
||||
|
||||
|
@ -19,7 +20,7 @@ HRESULT ErrorHandler::ExecuteForAddRequest()
|
|||
HRESULT ErrorHandler::RemovePackage(std::wstring packageFullName)
|
||||
{
|
||||
AutoPtr<MsixRequest> removePackageRequest;
|
||||
RETURN_IF_FAILED(MsixRequest::Make(OperationType::Remove, Flags::NoFlags, std::wstring(), packageFullName,
|
||||
RETURN_IF_FAILED(MsixRequest::Make(OperationType::Remove, std::wstring(), packageFullName,
|
||||
MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &removePackageRequest));
|
||||
|
||||
const HRESULT hrCancelRequest = removePackageRequest->ProcessRequest();
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
class ErrorHandler : IPackageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -25,4 +28,5 @@ private:
|
|||
|
||||
/// Prepares and sends msixrequest to uninstall the package in case cancel button was clicked during installation
|
||||
HRESULT RemovePackage(std::wstring packageFullName);
|
||||
};
|
||||
};
|
||||
}
|
|
@ -9,9 +9,9 @@
|
|||
#include "FilePaths.hpp"
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include "InstallUI.hpp"
|
||||
#include "RegistryDevirtualizer.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR Extractor::HandlerName = L"Extractor";
|
||||
|
||||
|
@ -93,7 +93,10 @@ HRESULT Extractor::ExtractFile(IAppxFile* file)
|
|||
ComPtr<IStream> fileStream;
|
||||
RETURN_IF_FAILED(file->GetStream(&fileStream));
|
||||
ComPtr<IStream> outputStream;
|
||||
RETURN_IF_FAILED(GetOutputStream(m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath().c_str(), fileName.Get(), &outputStream));
|
||||
|
||||
auto packageDirectoryPath = m_msixRequest->GetPackageDirectoryPath();
|
||||
|
||||
RETURN_IF_FAILED(GetOutputStream(packageDirectoryPath.c_str(), fileName.Get(), &outputStream));
|
||||
RETURN_IF_FAILED(fileStream->CopyTo(outputStream.Get(), fileSizeLargeInteger, nullptr, nullptr));
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -102,6 +105,8 @@ HRESULT Extractor::ExtractFootprintFiles()
|
|||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Extracting footprint files from the package");
|
||||
|
||||
auto packageToInstall = std::dynamic_pointer_cast<Package>(m_msixRequest->GetPackageInfo());
|
||||
|
||||
for (int i = 0; i < FootprintFilesCount; i++)
|
||||
{
|
||||
|
@ -110,18 +115,21 @@ HRESULT Extractor::ExtractFootprintFiles()
|
|||
return HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
|
||||
}
|
||||
|
||||
ComPtr<IAppxFile> footprintFile;
|
||||
HRESULT hr = m_msixRequest->GetPackageInfo()->GetPackageReader()->GetFootprintFile(g_footprintFilesType[i].fileType, &footprintFile);
|
||||
if (SUCCEEDED(hr) && footprintFile.Get())
|
||||
if (packageToInstall != nullptr)
|
||||
{
|
||||
RETURN_IF_FAILED(ExtractFile(footprintFile.Get()));
|
||||
}
|
||||
else if (g_footprintFilesType[i].isRequired)
|
||||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Missing required Footprintfile",
|
||||
TraceLoggingValue(g_footprintFilesType[i].description, "File Description"));
|
||||
return hr;
|
||||
ComPtr<IAppxFile> footprintFile;
|
||||
HRESULT hr = packageToInstall->GetPackageReader()->GetFootprintFile(g_footprintFilesType[i].fileType, &footprintFile);
|
||||
if (SUCCEEDED(hr) && footprintFile.Get())
|
||||
{
|
||||
RETURN_IF_FAILED(ExtractFile(footprintFile.Get()));
|
||||
}
|
||||
else if (g_footprintFilesType[i].isRequired)
|
||||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Missing required Footprintfile",
|
||||
TraceLoggingValue(g_footprintFilesType[i].description, "File Description"));
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
|
@ -133,12 +141,19 @@ HRESULT Extractor::ExtractPayloadFiles()
|
|||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Extracting payload files from the package");
|
||||
|
||||
RETURN_IF_FAILED(m_msixRequest->GetPackageInfo()->GetPackageReader()->GetPayloadFiles(&files));
|
||||
auto packageToInstall = std::dynamic_pointer_cast<Package>(m_msixRequest->GetPackageInfo());
|
||||
if (packageToInstall == nullptr)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
RETURN_IF_FAILED(packageToInstall->GetPackageReader()->GetPayloadFiles(&files));
|
||||
|
||||
BOOL hasCurrent = FALSE;
|
||||
RETURN_IF_FAILED(files->GetHasCurrent(&hasCurrent));
|
||||
AutoPtr<UI> ui;
|
||||
|
||||
unsigned int totalNumberFiles = m_msixRequest->GetPackageInfo()->GetNumberOfPayloadFiles();
|
||||
unsigned int nbrFilesExtracted = 0;
|
||||
while (hasCurrent)
|
||||
{
|
||||
if (m_msixRequest->GetMsixResponse()->GetIsInstallCancelled())
|
||||
|
@ -160,7 +175,10 @@ HRESULT Extractor::ExtractPayloadFiles()
|
|||
}
|
||||
|
||||
RETURN_IF_FAILED(files->MoveNext(&hasCurrent));
|
||||
ui->UpdateProgressBar();
|
||||
++nbrFilesExtracted;
|
||||
|
||||
float progress = 100.0f * nbrFilesExtracted / totalNumberFiles;
|
||||
m_msixRequest->GetMsixResponse()->Update(InstallationStep::InstallationStepExtraction, progress);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -168,7 +186,7 @@ HRESULT Extractor::ExtractPayloadFiles()
|
|||
|
||||
HRESULT Extractor::CreatePackageRoot()
|
||||
{
|
||||
std::wstring packagePath = m_msixRequest->GetFilePathMappings()->GetMsix7Directory();
|
||||
std::wstring packagePath = FilePathMappings::GetInstance().GetMsix7Directory();
|
||||
if (!CreateDirectory(packagePath.c_str(), nullptr))
|
||||
{
|
||||
DWORD lastError = GetLastError();
|
||||
|
@ -178,7 +196,7 @@ HRESULT Extractor::CreatePackageRoot()
|
|||
}
|
||||
}
|
||||
|
||||
if (!CreateDirectory(m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath().c_str(), nullptr))
|
||||
if (!CreateDirectory((FilePathMappings::GetInstance().GetMsix7Directory() + m_msixRequest->GetPackageInfo()->GetPackageFullName()).c_str(), nullptr))
|
||||
{
|
||||
DWORD lastError = GetLastError();
|
||||
if (lastError != ERROR_ALREADY_EXISTS)
|
||||
|
@ -200,12 +218,12 @@ HRESULT Extractor::ExecuteForAddRequest()
|
|||
|
||||
HRESULT Extractor::RemoveVfsFiles()
|
||||
{
|
||||
std::wstring blockMapPath = m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath() + blockMapFile;
|
||||
std::wstring blockMapPath = m_msixRequest->GetPackageDirectoryPath() + blockMapFile;
|
||||
ComPtr<IStream> stream;
|
||||
RETURN_IF_FAILED(CreateStreamOnFileUTF16(blockMapPath.c_str(), true /*forRead*/, &stream));
|
||||
|
||||
ComPtr<IAppxFactory> appxFactory;
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(MyAllocate, MyFree, m_msixRequest->GetValidationOptions(), &appxFactory));
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(Win7MsixInstallerLib_MyAllocate, Win7MsixInstallerLib_MyFree, m_msixRequest->GetValidationOptions(), &appxFactory));
|
||||
|
||||
ComPtr<IAppxBlockMapReader> blockMapReader;
|
||||
RETURN_IF_FAILED(appxFactory->CreateBlockMapReader(stream.Get(), &blockMapReader));
|
||||
|
@ -260,11 +278,12 @@ HRESULT Extractor::ExecuteForRemoveRequest()
|
|||
m_msixRequest->GetPackageInfo()->ReleaseManifest();
|
||||
|
||||
std::error_code error;
|
||||
uintmax_t numRemoved = std::experimental::filesystem::remove_all(m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath(), error);
|
||||
auto packageDirectoryPath = m_msixRequest->GetPackageDirectoryPath();
|
||||
uintmax_t numRemoved = std::experimental::filesystem::remove_all(packageDirectoryPath, error);
|
||||
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Removed directory",
|
||||
TraceLoggingValue(m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath().c_str(), "PackageDirectoryPath"),
|
||||
TraceLoggingValue(packageDirectoryPath.c_str(), "PackageDirectoryPath"),
|
||||
TraceLoggingValue(error.value(), "Error"),
|
||||
TraceLoggingValue(numRemoved, "NumRemoved"));
|
||||
|
||||
|
@ -386,8 +405,8 @@ HRESULT Extractor::NeedToCopyFile(std::wstring sourceFullPath, std::wstring targ
|
|||
bool sourceFileIsUnversioned = false;
|
||||
RETURN_IF_FAILED(GetFileVersion(sourceFullPath, sourceFileVersion, sourceFileIsUnversioned));
|
||||
|
||||
std::wstring targetVersionString = ConvertVersionToString(targetFileVersion);
|
||||
std::wstring sourceVersionString = ConvertVersionToString(sourceFileVersion);
|
||||
std::wstring targetVersionString = Win7MsixInstallerLib_ConvertVersionToString(targetFileVersion);
|
||||
std::wstring sourceVersionString = Win7MsixInstallerLib_ConvertVersionToString(sourceFileVersion);
|
||||
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Target Exists, file versioning information",
|
||||
|
@ -480,7 +499,7 @@ HRESULT Extractor::RemoveVfsFile(std::wstring fileName)
|
|||
TraceLoggingValue(GetLastError(), "error"));
|
||||
}
|
||||
|
||||
GetPathParent(fullPath);
|
||||
Win7MsixInstallerLib_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
|
||||
|
@ -504,14 +523,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;
|
||||
GetPathChild(remainingFilePath); // remove the VFS directory
|
||||
Win7MsixInstallerLib_GetPathChild(remainingFilePath); // remove the VFS directory
|
||||
|
||||
std::map<std::wstring, std::wstring> map = m_msixRequest->GetFilePathMappings()->GetMap();
|
||||
std::map<std::wstring, std::wstring> map = FilePathMappings::GetInstance().GetMap();
|
||||
for (auto& pair : map)
|
||||
{
|
||||
if (remainingFilePath.find(pair.first) != std::wstring::npos)
|
||||
{
|
||||
GetPathChild(remainingFilePath); // remove the FirstDir directory.
|
||||
Win7MsixInstallerLib_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;
|
||||
|
@ -535,7 +554,7 @@ HRESULT Extractor::CopyVfsFileToLocal(std::wstring fileName)
|
|||
"CopyVfsFileToLocal",
|
||||
TraceLoggingValue(fileName.c_str(), "FileName"));
|
||||
|
||||
std::wstring sourceFullPath = m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath().c_str() + std::wstring(L"\\") + fileName;
|
||||
std::wstring sourceFullPath = m_msixRequest->GetPackageDirectoryPath() + std::wstring(L"\\") + fileName;
|
||||
|
||||
std::wstring targetFullPath;
|
||||
if (FAILED(ConvertVfsNameToFullPath(fileName, targetFullPath)))
|
||||
|
@ -550,7 +569,7 @@ HRESULT Extractor::CopyVfsFileToLocal(std::wstring fileName)
|
|||
|
||||
HRESULT Extractor::ExtractRegistry(bool remove)
|
||||
{
|
||||
std::wstring registryFilePath = m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath().c_str() + registryDatFile;
|
||||
std::wstring registryFilePath = m_msixRequest->GetPackageDirectoryPath() + registryDatFile;
|
||||
|
||||
AutoPtr<RegistryDevirtualizer> registryDevirtualizer;
|
||||
RETURN_IF_FAILED(RegistryDevirtualizer::Create(registryFilePath, m_msixRequest, ®istryDevirtualizer));
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// Extractor extracts the files and registry settings from the package to the file system and registry.
|
||||
class Extractor : IPackageHandler
|
||||
{
|
||||
|
@ -101,3 +104,4 @@ private:
|
|||
/// Removes all VFS files in the package
|
||||
HRESULT RemoveVfsFiles();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
#include <shlobj_core.h>
|
||||
#include <KnownFolders.h>
|
||||
|
||||
void GetPathChild(std::wstring &path)
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
void Win7MsixInstallerLib_GetPathChild(std::wstring &path)
|
||||
{
|
||||
while (path.front() != '\\')
|
||||
{
|
||||
|
@ -12,7 +14,7 @@ void GetPathChild(std::wstring &path)
|
|||
path.erase(0, 1);
|
||||
}
|
||||
|
||||
void GetPathParent(std::wstring &path)
|
||||
void Win7MsixInstallerLib_GetPathParent(std::wstring &path)
|
||||
{
|
||||
while (!path.empty() && path.back() != '\\')
|
||||
{
|
||||
|
@ -32,6 +34,12 @@ void GetPathParent(std::wstring &path)
|
|||
}
|
||||
}
|
||||
|
||||
FilePathMappings& FilePathMappings::GetInstance()
|
||||
{
|
||||
static FilePathMappings s_selfInstance;
|
||||
return s_selfInstance;
|
||||
}
|
||||
|
||||
std::wstring FilePathMappings::GetExecutablePath(std::wstring packageExecutablePath, PCWSTR packageFullName)
|
||||
{
|
||||
// make a local copy so we can modify in place
|
||||
|
@ -40,7 +48,7 @@ std::wstring FilePathMappings::GetExecutablePath(std::wstring packageExecutableP
|
|||
//Checks if the executable is inside the VFS
|
||||
if (executionPathWSTR.find(L"VFS") != std::wstring::npos)
|
||||
{
|
||||
GetPathChild(executionPathWSTR);
|
||||
Win7MsixInstallerLib_GetPathChild(executionPathWSTR);
|
||||
//Checks if the executable is in one of the known folders
|
||||
for (auto pair : m_map)
|
||||
{
|
||||
|
@ -49,7 +57,7 @@ std::wstring FilePathMappings::GetExecutablePath(std::wstring packageExecutableP
|
|||
//The executable exists in an unpacked directory
|
||||
std::wstring executablePath = pair.second;
|
||||
|
||||
GetPathChild(executionPathWSTR);
|
||||
Win7MsixInstallerLib_GetPathChild(executionPathWSTR);
|
||||
executablePath.push_back(L'\\');
|
||||
executablePath.append(executionPathWSTR);
|
||||
return executablePath;
|
||||
|
@ -65,7 +73,7 @@ std::wstring FilePathMappings::GetExecutablePath(std::wstring packageExecutableP
|
|||
return executablePath;
|
||||
}
|
||||
|
||||
HRESULT FilePathMappings::Initialize()
|
||||
HRESULT FilePathMappings::InitializePaths()
|
||||
{
|
||||
TextOle<WCHAR> systemX86Path;
|
||||
TextOle<WCHAR> systemPath;
|
||||
|
@ -101,7 +109,7 @@ HRESULT FilePathMappings::Initialize()
|
|||
appVSystem32SpoolPath.append(L"\\spool");
|
||||
|
||||
std::wstring systemDrive = std::wstring(windowsPath.Get());
|
||||
GetPathParent(systemDrive);
|
||||
Win7MsixInstallerLib_GetPathParent(systemDrive);
|
||||
m_map[L"AppVPackageDrive"] = systemDrive;
|
||||
m_map[L"SystemX86"] = std::wstring(systemX86Path.Get());
|
||||
m_map[L"System"] = std::wstring(systemPath.Get());
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
#include "GeneralUtil.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// FilePath Mappings maps the VFS tokens to the actual folder on disk.
|
||||
/// For instance, VFS token: Windows, actual folder: C:\windows
|
||||
class FilePathMappings
|
||||
{
|
||||
public:
|
||||
HRESULT Initialize();
|
||||
static FilePathMappings& GetInstance();
|
||||
|
||||
std::map < std::wstring, std::wstring > GetMap() { return m_map; }
|
||||
|
||||
|
@ -22,16 +23,25 @@ public:
|
|||
/// @param packageFullName - The packageFullName
|
||||
/// @return the resolved full path to the executable
|
||||
std::wstring GetExecutablePath(std::wstring packageExecutablePath, PCWSTR packageFullName);
|
||||
private:
|
||||
HRESULT GetInitializationResult() { return m_initializationResult; }
|
||||
private:
|
||||
// Disallow creating an instance of this object
|
||||
HRESULT InitializePaths();
|
||||
FilePathMappings()
|
||||
{
|
||||
m_initializationResult = InitializePaths();
|
||||
}
|
||||
private:
|
||||
std::map < std::wstring, std::wstring > m_map;
|
||||
std::wstring m_msix7Directory;
|
||||
bool m_isInitialized = false;
|
||||
HRESULT m_initializationResult = E_NOT_SET;
|
||||
};
|
||||
|
||||
}
|
||||
/// Removes the first directory from a path.
|
||||
/// @param path - A path that contains at least one parent directory
|
||||
void GetPathChild(std::wstring &path);
|
||||
void Win7MsixInstallerLib_GetPathChild(std::wstring &path);
|
||||
|
||||
/// Removes the innermost child file from a path
|
||||
/// @param path - A file path
|
||||
void GetPathParent(std::wstring &path);
|
||||
|
||||
void Win7MsixInstallerLib_GetPathParent(std::wstring &path);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR FileTypeAssociation::HandlerName = L"FileTypeAssociation";
|
||||
|
||||
|
@ -65,7 +66,7 @@ HRESULT FileTypeAssociation::ParseFtaElement(IMsixElement* ftaElement)
|
|||
Text<wchar_t> logoPath;
|
||||
RETURN_IF_FAILED(logoElement->GetText(&logoPath));
|
||||
|
||||
fta.logo = m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath() + std::wstring(L"\\") + logoPath.Get();
|
||||
fta.logo = m_msixRequest->GetPackageDirectoryPath() + std::wstring(L"\\") + logoPath.Get();
|
||||
}
|
||||
|
||||
ComPtr<IMsixElementEnumerator> verbsEnum;
|
||||
|
@ -210,7 +211,8 @@ HRESULT FileTypeAssociation::ProcessFtaForAdd(Fta& fta)
|
|||
RegistryKey commandKey;
|
||||
RETURN_IF_FAILED(openKey.CreateSubKey(commandKeyName.c_str(), KEY_WRITE, &commandKey));
|
||||
|
||||
std::wstring command = m_msixRequest->GetPackageInfo()->GetExecutableFilePath() + commandArgument;
|
||||
std::wstring executablePath = m_msixRequest->GetPackageDirectoryPath() + L"\\" + m_msixRequest->GetPackageInfo()->GetRelativeExecutableFilePath();
|
||||
std::wstring command = executablePath + commandArgument;
|
||||
RETURN_IF_FAILED(commandKey.SetStringValue(L"", command));
|
||||
|
||||
for (auto verb = fta.verbs.begin(); verb != fta.verbs.end(); ++verb)
|
||||
|
@ -221,7 +223,7 @@ HRESULT FileTypeAssociation::ProcessFtaForAdd(Fta& fta)
|
|||
RegistryKey verbCommandKey;
|
||||
RETURN_IF_FAILED(verbKey.CreateSubKey(commandKeyName.c_str(), KEY_WRITE, &verbCommandKey));
|
||||
|
||||
std::wstring verbCommand = m_msixRequest->GetPackageInfo()->GetExecutableFilePath();
|
||||
std::wstring verbCommand = executablePath;
|
||||
if (verb->parameter.c_str() != nullptr)
|
||||
{
|
||||
verbCommand += std::wstring(L" ") + verb->parameter.c_str();
|
||||
|
@ -303,7 +305,7 @@ HRESULT FileTypeAssociation::CreateHandler(MsixRequest * msixRequest, IPackageHa
|
|||
|
||||
RETURN_IF_FAILED(localInstance->m_classesKey.Open(HKEY_CLASSES_ROOT, nullptr, KEY_READ | KEY_WRITE | WRITE_DAC));
|
||||
|
||||
std::wstring registryFilePath = msixRequest->GetPackageInfo()->GetPackageDirectoryPath().c_str() + registryDatFile;
|
||||
std::wstring registryFilePath = msixRequest->GetPackageDirectoryPath() + registryDatFile;
|
||||
RETURN_IF_FAILED(RegistryDevirtualizer::Create(registryFilePath, msixRequest, &localInstance->m_registryDevirtualizer));
|
||||
|
||||
RETURN_IF_FAILED(localInstance->ParseManifest());
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
#include "IPackageHandler.hpp"
|
||||
#include "RegistryKey.hpp"
|
||||
#include "RegistryDevirtualizer.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// Data structs to be filled in from the information in the manifest
|
||||
struct Verb
|
||||
{
|
||||
|
@ -59,3 +62,4 @@ private:
|
|||
/// Creates a ProgID from the name of the fta. Simply take the package name and prepend it to the fta
|
||||
std::wstring CreateProgID(PCWSTR name);
|
||||
};
|
||||
}
|
|
@ -1,24 +1,26 @@
|
|||
#ifndef FOOTPRINTFILES_H
|
||||
#define FOOTPRINTFILES_H
|
||||
|
||||
#include "AppxPackaging.hpp"
|
||||
|
||||
// Describes the FootprintFilesType structure
|
||||
template<typename Type>
|
||||
struct FootprintFilesType
|
||||
{
|
||||
Type fileType;
|
||||
const char* description;
|
||||
bool isRequired;
|
||||
};
|
||||
|
||||
// Types of footprint files in an app package
|
||||
__declspec(selectany) FootprintFilesType<APPX_FOOTPRINT_FILE_TYPE> g_footprintFilesType[] =
|
||||
{
|
||||
{ APPX_FOOTPRINT_FILE_TYPE_MANIFEST, "manifest", true },
|
||||
{ APPX_FOOTPRINT_FILE_TYPE_BLOCKMAP, "block map", true },
|
||||
{ APPX_FOOTPRINT_FILE_TYPE_SIGNATURE, "digital signature", true },
|
||||
{ APPX_FOOTPRINT_FILE_TYPE_CODEINTEGRITY, "CI catalog", false }, // this is ONLY required if there exists 1+ PEs
|
||||
};
|
||||
const int FootprintFilesCount = ARRAYSIZE(g_footprintFilesType);
|
||||
#endif
|
||||
#ifndef FOOTPRINTFILES_H
|
||||
#define FOOTPRINTFILES_H
|
||||
|
||||
#include "AppxPackaging.hpp"
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
// Describes the FootprintFilesType structure
|
||||
template<typename Type>
|
||||
struct FootprintFilesType
|
||||
{
|
||||
Type fileType;
|
||||
const char* description;
|
||||
bool isRequired;
|
||||
};
|
||||
|
||||
// Types of footprint files in an app package
|
||||
__declspec(selectany) FootprintFilesType<APPX_FOOTPRINT_FILE_TYPE> g_footprintFilesType[] =
|
||||
{
|
||||
{ APPX_FOOTPRINT_FILE_TYPE_MANIFEST, "manifest", true },
|
||||
{ APPX_FOOTPRINT_FILE_TYPE_BLOCKMAP, "block map", true },
|
||||
{ APPX_FOOTPRINT_FILE_TYPE_SIGNATURE, "digital signature", true },
|
||||
{ APPX_FOOTPRINT_FILE_TYPE_CODEINTEGRITY, "CI catalog", false }, // this is ONLY required if there exists 1+ PEs
|
||||
};
|
||||
const int FootprintFilesCount = ARRAYSIZE(g_footprintFilesType);
|
||||
#endif
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
#pragma once
|
||||
#include "Package.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// Interface for a logical chunk of work done on an Msix request
|
||||
class IPackageHandler
|
||||
{
|
||||
|
@ -9,12 +12,14 @@ public:
|
|||
virtual HRESULT ExecuteForAddRequest() = 0;
|
||||
|
||||
virtual HRESULT ExecuteForRemoveRequest() { return S_OK; }
|
||||
virtual bool IsMandatoryForRemoveRequest() { return false; }
|
||||
virtual bool IsMandatoryForAddRequest() { return true; }
|
||||
|
||||
virtual ~IPackageHandler() {};
|
||||
};
|
||||
|
||||
/// Function responsible for creating an instance of an IPackageHandler object
|
||||
/// @param msixRequest - the msix request object to act upon
|
||||
/// Function responsible for creating an instance of an IPackageHandler object /// Function responsible for creating an instance of an IPackageHandler object
|
||||
/// @param msixRequest - the msix request object to act upon /// @return S_OK of the package.
|
||||
/// @return S_OK if CreateHandler is to not fail the deployment of the package.
|
||||
typedef HRESULT(*CreateHandler)(_In_ MsixRequest* msixRequest, _Out_ IPackageHandler** instance);
|
||||
|
||||
}
|
|
@ -8,16 +8,16 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
|
||||
#include "InstallUI.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR InstallComplete::HandlerName = L"InstallComplete";
|
||||
|
||||
HRESULT InstallComplete::ExecuteForAddRequest()
|
||||
{
|
||||
if (!m_msixRequest->GetMsixResponse()->GetIsInstallCancelled())
|
||||
auto msixResponse = m_msixRequest->GetMsixResponse();
|
||||
if (msixResponse != nullptr && !msixResponse->GetIsInstallCancelled())
|
||||
{
|
||||
AutoPtr<UI> ui = m_msixRequest->GetUI();
|
||||
ui->SendInstallCompleteMsg();
|
||||
msixResponse->Update(InstallationStep::InstallationStepCompleted, 100);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
class InstallComplete : IPackageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -17,4 +20,5 @@ private:
|
|||
|
||||
InstallComplete() {}
|
||||
InstallComplete(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
};
|
||||
};
|
||||
}
|
|
@ -11,48 +11,22 @@
|
|||
#include "resource.h"
|
||||
#include <filesystem>
|
||||
|
||||
#include "Util.hpp"
|
||||
#include "Win7MSIXInstallerLogger.hpp"
|
||||
// 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;
|
||||
#include <GdiPlus.h>
|
||||
|
||||
static const int g_width = 500; // width of window
|
||||
static const int g_heigth = 400; // height of window
|
||||
|
||||
const PCWSTR CreateAndShowUI::HandlerName = L"UI";
|
||||
|
||||
//
|
||||
// Gets the stream of a file.
|
||||
// PURPOSE: This compiles the information displayed on the UI when the user selects an msix
|
||||
//
|
||||
// Parameters:
|
||||
// package - The package reader for the app package.
|
||||
// name - Name of the file.
|
||||
// stream - The stream for the file.
|
||||
//
|
||||
HRESULT GetStreamFromFile(IAppxPackageReader* package, LPCWCHAR name, IStream** stream)
|
||||
{
|
||||
*stream = nullptr;
|
||||
ComPtr<IAppxFilesEnumerator> files;
|
||||
|
||||
RETURN_IF_FAILED(package->GetPayloadFiles(&files));
|
||||
|
||||
BOOL hasCurrent = FALSE;
|
||||
RETURN_IF_FAILED(files->GetHasCurrent(&hasCurrent));
|
||||
while (hasCurrent)
|
||||
{
|
||||
ComPtr<IAppxFile> file;
|
||||
RETURN_IF_FAILED(files->GetCurrent(&file));
|
||||
Text<WCHAR> fileName;
|
||||
file->GetName(&fileName);
|
||||
if (wcscmp(fileName.Get(), name) == 0)
|
||||
{
|
||||
RETURN_IF_FAILED(file->GetStream(stream));
|
||||
return S_OK;
|
||||
}
|
||||
RETURN_IF_FAILED(files->MoveNext(&hasCurrent));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
// hWnd: the HWND of the window to draw controls
|
||||
// windowRect: the size of the window
|
||||
|
||||
HRESULT UI::DrawPackageInfo(HWND hWnd, RECT windowRect)
|
||||
{
|
||||
|
@ -60,7 +34,7 @@ HRESULT UI::DrawPackageInfo(HWND hWnd, RECT windowRect)
|
|||
{
|
||||
auto displayText = m_installOrUpdateText + L" " + m_displayName + L"?";
|
||||
auto messageText = L"Publisher: " + m_publisherCommonName + L"\nVersion: " + m_version;
|
||||
ChangeText(hWnd, displayText, messageText, m_logoStream.Get());
|
||||
ChangeText(hWnd, displayText, messageText, m_logoStream.get());
|
||||
ChangeText(hWnd, GetStringResource(IDS_STRING_UI_INSTALL_COMPLETE), GetStringResource(IDS_STRING_UI_COMPLETION_MESSAGE));
|
||||
}
|
||||
else
|
||||
|
@ -100,96 +74,78 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_INSTALLBUTTON:
|
||||
case IDC_INSTALLBUTTON:
|
||||
{
|
||||
g_installing = true;
|
||||
DestroyWindow(g_LaunchbuttonHWnd);
|
||||
DestroyWindow(g_buttonHWnd);
|
||||
ui->CreateCancelButton(hWnd, windowRect);
|
||||
UpdateWindow(hWnd);
|
||||
ui->CreateProgressBar(hWnd, windowRect);
|
||||
ShowWindow(g_progressHWnd, SW_SHOW); //Show progress bar only when install is clicked
|
||||
ui->ButtonClicked();
|
||||
}
|
||||
break;
|
||||
case IDC_LAUNCHCHECKBOX:
|
||||
{
|
||||
if (SendMessage(GetDlgItem(hWnd, IDC_LAUNCHCHECKBOX), BM_GETCHECK, 0, 0) == BST_CHECKED)
|
||||
{
|
||||
g_installing = true;
|
||||
DestroyWindow(g_LaunchbuttonHWnd);
|
||||
DestroyWindow(g_buttonHWnd);
|
||||
ui->CreateCancelButton(hWnd, windowRect);
|
||||
UpdateWindow(hWnd);
|
||||
if (ui != NULL)
|
||||
{
|
||||
ui->CreateProgressBar(hWnd, windowRect, ui->GetNumberOfFiles());
|
||||
}
|
||||
ShowWindow(g_progressHWnd, SW_SHOW); //Show progress bar only when install is clicked
|
||||
if (ui != NULL)
|
||||
{
|
||||
ui->SetButtonClicked();
|
||||
}
|
||||
g_launchCheckBoxState = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_launchCheckBoxState = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_CANCELBUTTON:
|
||||
{
|
||||
ui->ConfirmAppCancel(hWnd);
|
||||
break;
|
||||
case IDC_LAUNCHCHECKBOX:
|
||||
{
|
||||
if (SendMessage(GetDlgItem(hWnd, IDC_LAUNCHCHECKBOX), BM_GETCHECK, 0, 0) == BST_CHECKED)
|
||||
{
|
||||
g_launchCheckBoxState = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_launchCheckBoxState = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
case IDC_LAUNCHBUTTON:
|
||||
{
|
||||
ui->LaunchInstalledApp();
|
||||
break;
|
||||
case IDC_CANCELBUTTON:
|
||||
{
|
||||
ui->ConfirmAppCancel(hWnd);
|
||||
break;
|
||||
}
|
||||
case IDC_LAUNCHBUTTON:
|
||||
{
|
||||
ui->LaunchInstalledApp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_INSTALLCOMPLETE_MSG:
|
||||
{
|
||||
g_installing = false; // installation complete, clicking on 'x' should not show the cancellation popup
|
||||
DestroyWindow(g_CancelbuttonHWnd);
|
||||
ui->CreateLaunchButton(hWnd, windowRect, 150, 60);
|
||||
ShowWindow(g_LaunchbuttonHWnd, SW_SHOW);
|
||||
UpdateWindow(hWnd);
|
||||
ShowWindow(g_progressHWnd, SW_HIDE); //hide progress bar
|
||||
ShowWindow(g_checkboxHWnd, SW_HIDE); //hide launch check box
|
||||
if (g_launchCheckBoxState)
|
||||
{
|
||||
ui->LaunchInstalledApp(); // launch app
|
||||
DestroyWindow(hWnd); // close msix app installer
|
||||
ui->CloseUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
//wait for user to click launch button or close the window
|
||||
while (true)
|
||||
{
|
||||
switch (MsgWaitForMultipleObjects(0, NULL, FALSE, INFINITE, QS_ALLINPUT))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
RECT windowRect;
|
||||
GetClientRect(hWnd, &windowRect);
|
||||
DestroyWindow(g_CancelbuttonHWnd);
|
||||
ui->CreateLaunchButton(hWnd, windowRect, 150, 60);
|
||||
UpdateWindow(hWnd);
|
||||
ShowWindow(g_progressHWnd, SW_HIDE); //hide progress bar
|
||||
ShowWindow(g_checkboxHWnd, SW_HIDE); //hide launch check box
|
||||
ShowWindow(g_LaunchbuttonHWnd, SW_SHOW);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_CTLCOLORSTATIC:
|
||||
{
|
||||
break;
|
||||
case WM_CTLCOLORSTATIC:
|
||||
{
|
||||
switch (::GetDlgCtrlID((HWND)lParam))
|
||||
{
|
||||
case IDC_LAUNCHCHECKBOX:
|
||||
{
|
||||
HBRUSH hbr = (HBRUSH)DefWindowProc(hWnd, message, wParam, lParam);
|
||||
::DeleteObject(hbr);
|
||||
SetBkMode((HDC)wParam, TRANSPARENT);
|
||||
return (LRESULT)::GetStockObject(NULL_BRUSH);
|
||||
}
|
||||
{
|
||||
case IDC_LAUNCHCHECKBOX:
|
||||
{
|
||||
HBRUSH hbr = (HBRUSH)DefWindowProc(hWnd, message, wParam, lParam);
|
||||
::DeleteObject(hbr);
|
||||
SetBkMode((HDC)wParam, TRANSPARENT);
|
||||
return (LRESULT)::GetStockObject(NULL_BRUSH);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_CLOSE:
|
||||
|
@ -224,7 +180,7 @@ void UI::ConfirmAppCancel(HWND hWnd)
|
|||
switch (cancelResult)
|
||||
{
|
||||
case IDYES:
|
||||
m_msixRequest->GetMsixResponse()->CancelRequest();
|
||||
m_msixResponse->CancelRequest();
|
||||
break;
|
||||
case IDNO:
|
||||
break;
|
||||
|
@ -233,10 +189,9 @@ void UI::ConfirmAppCancel(HWND hWnd)
|
|||
|
||||
HRESULT UI::LaunchInstalledApp()
|
||||
{
|
||||
PackageInfo* packageInfo = m_msixRequest->GetPackageInfo();
|
||||
std::wstring resolvedExecutableFullPath = packageInfo->GetExecutableFilePath();
|
||||
auto installedPackage = m_packageManager->FindPackage(m_packageInfo->GetPackageFullName());
|
||||
//check for error while launching app here
|
||||
ShellExecute(NULL, NULL, resolvedExecutableFullPath.c_str(), NULL, NULL, SW_SHOW);
|
||||
ShellExecute(NULL, NULL, installedPackage->GetFullExecutableFilePath().c_str(), NULL, NULL, SW_SHOW);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -305,129 +260,79 @@ void StartUIThread(UI* ui)
|
|||
|
||||
}
|
||||
|
||||
void UI::LoadInfo()
|
||||
HRESULT UI::ParseInfoFromPackage()
|
||||
{
|
||||
m_loadingPackageInfoCode = ParseInfoFromPackage();
|
||||
}
|
||||
|
||||
HRESULT UI::ParseInfoFromPackage()
|
||||
{
|
||||
PackageInfo* packageInfo = m_msixRequest->GetPackageInfo();
|
||||
|
||||
ComPtr<IMsixDocumentElement> domElement;
|
||||
RETURN_IF_FAILED(packageInfo->GetManifestReader()->QueryInterface(UuidOfImpl<IMsixDocumentElement>::iid, reinterpret_cast<void**>(&domElement)));
|
||||
|
||||
ComPtr<IMsixElement> element;
|
||||
RETURN_IF_FAILED(domElement->GetDocumentElement(&element));
|
||||
|
||||
// Obtain the Display Name and Logo
|
||||
ComPtr<IMsixElementEnumerator> veElementEnum;
|
||||
RETURN_IF_FAILED(element->GetElements(
|
||||
L"/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']",
|
||||
&veElementEnum));
|
||||
if (m_packageInfo == nullptr)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case InstallUIAdd:
|
||||
{
|
||||
m_packageInfo = m_packageManager->GetMsixPackageInfo(m_path);
|
||||
if (m_packageInfo == nullptr)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InstallUIRemove:
|
||||
{
|
||||
m_packageInfo = m_packageManager->FindPackage(m_path);
|
||||
if (m_packageInfo == nullptr)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain publisher name
|
||||
auto wpublisher = std::wstring(packageInfo->GetPublisher());
|
||||
m_publisherCommonName = wpublisher.substr(wpublisher.find_first_of(L"=") + 1,
|
||||
wpublisher.find_first_of(L",") - wpublisher.find_first_of(L"=") - 1);
|
||||
m_publisherCommonName = m_packageInfo->GetPublisherDisplayName();
|
||||
|
||||
// Obtain version number
|
||||
m_version = ConvertVersionToString(packageInfo->GetVersion());
|
||||
m_version = m_packageInfo->GetVersion();
|
||||
|
||||
//Obtain the number of files
|
||||
m_numberOfFiles = packageInfo->GetNumberOfPayloadFiles();
|
||||
|
||||
// Obtain logo
|
||||
BOOL hc = FALSE;
|
||||
RETURN_IF_FAILED(veElementEnum->GetHasCurrent(&hc));
|
||||
if (hc)
|
||||
{
|
||||
ComPtr<IMsixElement> visualElementsElement;
|
||||
Text<WCHAR> displayNameValue;
|
||||
RETURN_IF_FAILED(veElementEnum->GetCurrent(&visualElementsElement));
|
||||
RETURN_IF_FAILED(visualElementsElement->GetAttributeValue(L"DisplayName", &displayNameValue));
|
||||
m_displayName = std::wstring(displayNameValue.Get());
|
||||
Text<WCHAR> logo;
|
||||
RETURN_IF_FAILED(visualElementsElement->GetAttributeValue(L"Square150x150Logo", &logo));
|
||||
RETURN_IF_FAILED(GetStreamFromFile(packageInfo->GetPackageReader(), logo.Get(), &m_logoStream));
|
||||
}
|
||||
m_displayName = m_packageInfo->GetDisplayName();
|
||||
m_logoStream = std::move(m_packageInfo->GetLogo());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT UI::ShowUI()
|
||||
{
|
||||
m_loadingPackageInfoCode = ParseInfoFromPackage();
|
||||
|
||||
std::thread thread(StartUIThread, this);
|
||||
thread.detach();
|
||||
|
||||
DWORD waitResult = WaitForSingleObject(m_buttonClickedEvent, INFINITE);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CreateAndShowUI::ExecuteForAddRequest()
|
||||
{
|
||||
if (m_msixRequest->IsQuietUX())
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
AutoPtr<UI> ui;
|
||||
RETURN_IF_FAILED(UI::Make(m_msixRequest, &ui));
|
||||
ui->LoadInfo();
|
||||
|
||||
m_msixRequest->SetUI(ui.Detach());
|
||||
RETURN_IF_FAILED(m_msixRequest->GetUI()->ShowUI());
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CreateAndShowUI::CreateHandler(MsixRequest * msixRequest, IPackageHandler ** instance)
|
||||
{
|
||||
std::unique_ptr<CreateAndShowUI> localInstance(new CreateAndShowUI(msixRequest));
|
||||
if (localInstance == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
*instance = localInstance.release();
|
||||
DWORD waitResult = WaitForSingleObject(m_closeUI, INFINITE);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void UI::PreprocessRequest()
|
||||
{
|
||||
std::wstring currentPackageFamilyName = GetFamilyNameFromFullName(m_msixRequest->GetPackageInfo()->GetPackageFullName());
|
||||
for (auto& p : std::experimental::filesystem::directory_iterator(m_msixRequest->GetFilePathMappings()->GetMsix7Directory()))
|
||||
auto existingPackage = m_packageManager->FindPackageByFamilyName(m_packageInfo->GetPackageFamilyName());
|
||||
if (existingPackage != nullptr)
|
||||
{
|
||||
std::wstring installedPackageFamilyName = GetFamilyNameFromFullName(p.path().filename());
|
||||
if (CaseInsensitiveEquals(m_msixRequest->GetPackageInfo()->GetPackageFullName(), p.path().filename()))
|
||||
if (CaseInsensitiveEquals(existingPackage->GetPackageFullName(), m_packageInfo->GetPackageFullName()))
|
||||
{
|
||||
/// Same package is already installed
|
||||
ChangeInstallButtonText(GetStringResource(IDS_STRING_REINSTALLAPP)); /// change install button text to 'reinstall'
|
||||
ShowWindow(g_LaunchbuttonHWnd, SW_SHOW); /// show launch button window
|
||||
}
|
||||
else if (CaseInsensitiveEquals(currentPackageFamilyName, installedPackageFamilyName))
|
||||
else
|
||||
{
|
||||
/// Package with same family name exists and may be an update
|
||||
m_installOrUpdateText = GetStringResource(IDS_STRING_UPDATETEXT);
|
||||
m_cancelPopUpMessage = GetStringResource(IDS_STRING_CANCEL_UPDATEPOPUP);
|
||||
ChangeInstallButtonText(GetStringResource(IDS_STRING_UPDATETEXT));
|
||||
ChangeInstallButtonText(GetStringResource(IDS_STRING_UPDATETEXT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT UI::Make(MsixRequest * msixRequest, UI ** instance)
|
||||
{
|
||||
std::unique_ptr<UI> localInstance(new UI(msixRequest));
|
||||
if (localInstance == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
*instance = localInstance.release();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
BOOL UI::CreateProgressBar(HWND parentHWnd, RECT parentRect, int count)
|
||||
BOOL UI::CreateProgressBar(HWND parentHWnd, RECT parentRect)
|
||||
{
|
||||
int scrollHeight = GetSystemMetrics(SM_CYVSCROLL);
|
||||
|
||||
|
@ -448,8 +353,7 @@ BOOL UI::CreateProgressBar(HWND parentHWnd, RECT parentRect, int count)
|
|||
);
|
||||
|
||||
// Set defaults for range and increments
|
||||
SendMessage(g_progressHWnd, PBM_SETRANGE, 0, MAKELPARAM(0, count)); // set range
|
||||
SendMessage(g_progressHWnd, PBM_SETSTEP, (WPARAM)1, 0); // set increment
|
||||
SendMessage(g_progressHWnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); // set range
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -492,26 +396,26 @@ BOOL UI::InstallButton(HWND parentHWnd, RECT parentRect) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL UI::CreateCancelButton(HWND parentHWnd, RECT parentRect)
|
||||
BOOL UI::CreateCancelButton(HWND parentHWnd, RECT parentRect)
|
||||
{
|
||||
LPVOID buttonPointer = nullptr;
|
||||
g_CancelbuttonHWnd = CreateWindowEx(
|
||||
WS_EX_LEFT, // extended window style
|
||||
L"BUTTON",
|
||||
L"Cancel", // text
|
||||
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_FLAT, // style
|
||||
parentRect.right - 100 - 50, // x coord
|
||||
parentRect.bottom - 60, // y coord
|
||||
120, // width
|
||||
35, // height
|
||||
parentHWnd, // parent
|
||||
(HMENU)IDC_CANCELBUTTON, // menu
|
||||
reinterpret_cast<HINSTANCE>(GetWindowLongPtr(parentHWnd, GWLP_HINSTANCE)),
|
||||
buttonPointer); // pointer to button
|
||||
return TRUE;
|
||||
LPVOID buttonPointer = nullptr;
|
||||
g_CancelbuttonHWnd = CreateWindowEx(
|
||||
WS_EX_LEFT, // extended window style
|
||||
L"BUTTON",
|
||||
L"Cancel", // text
|
||||
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_FLAT, // style
|
||||
parentRect.right - 100 - 50, // x coord
|
||||
parentRect.bottom - 60, // y coord
|
||||
120, // width
|
||||
35, // height
|
||||
parentHWnd, // parent
|
||||
(HMENU)IDC_CANCELBUTTON, // menu
|
||||
reinterpret_cast<HINSTANCE>(GetWindowLongPtr(parentHWnd, GWLP_HINSTANCE)),
|
||||
buttonPointer); // pointer to button
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL UI::CreateLaunchButton(HWND parentHWnd, RECT parentRect, int xDiff, int yDiff)
|
||||
BOOL UI::CreateLaunchButton(HWND parentHWnd, RECT parentRect, int xDiff, int yDiff)
|
||||
{
|
||||
LPVOID buttonPointer = nullptr;
|
||||
g_LaunchbuttonHWnd = CreateWindowEx(
|
||||
|
@ -548,9 +452,9 @@ BOOL UI::ChangeText(HWND parentHWnd, std::wstring displayName, std::wstring mess
|
|||
Gdiplus::Font messageFont(L"Arial", 10);
|
||||
Gdiplus::StringFormat format;
|
||||
format.SetAlignment(Gdiplus::StringAlignmentNear);
|
||||
auto windowsTextColor = Gdiplus::Color();
|
||||
windowsTextColor.SetFromCOLORREF(GetSysColor(COLOR_WINDOWTEXT));
|
||||
Gdiplus::SolidBrush textBrush(windowsTextColor);
|
||||
auto windowsTextColor = Gdiplus::Color();
|
||||
windowsTextColor.SetFromCOLORREF(GetSysColor(COLOR_WINDOWTEXT));
|
||||
Gdiplus::SolidBrush textBrush(windowsTextColor);
|
||||
|
||||
graphics.DrawString(displayName.c_str(), -1, &displayNameFont, layoutRect, &format, &textBrush);
|
||||
layoutRect.Y += 40;
|
||||
|
@ -610,12 +514,45 @@ int UI::CreateInitWindow(HINSTANCE hInstance, int nCmdShow, const std::wstring&
|
|||
return static_cast<int>(msg.wParam);
|
||||
}
|
||||
|
||||
void UI::UpdateProgressBar()
|
||||
void UI::ButtonClicked()
|
||||
{
|
||||
SendMessage(g_progressHWnd, PBM_STEPIT, 0, 0);
|
||||
switch (m_type)
|
||||
{
|
||||
case InstallUIAdd:
|
||||
{
|
||||
m_msixResponse = m_packageManager->AddPackageAsync(m_path, DeploymentOptions::None, [this](const IMsixResponse & sender) {
|
||||
|
||||
SendMessage(g_progressHWnd, PBM_SETPOS, (WPARAM)sender.GetPercentage(), 0);
|
||||
switch (sender.GetStatus())
|
||||
{
|
||||
case InstallationStep::InstallationStepCompleted:
|
||||
{
|
||||
SendInstallCompleteMsg();
|
||||
}
|
||||
break;
|
||||
case InstallationStep::InstallationStepError:
|
||||
{
|
||||
//auto error = sender->GetTextStatus();
|
||||
|
||||
CloseUI();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UI::SendInstallCompleteMsg()
|
||||
{
|
||||
SendMessage(GetHwnd(), WM_INSTALLCOMPLETE_MSG, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
void UI::CloseUI()
|
||||
{
|
||||
DestroyWindow(GetHwnd()); // close msix app installer
|
||||
SetEvent(m_closeUI);
|
||||
}
|
|
@ -1,39 +1,49 @@
|
|||
#pragma once
|
||||
/// Install UI Header
|
||||
/// UI Functions
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "resource.h"
|
||||
|
||||
/// Child window identifiers
|
||||
#define IDC_LAUNCHCHECKBOX 101
|
||||
#define IDC_INSTALLBUTTON 102
|
||||
#define IDC_CANCELBUTTON 103
|
||||
#define IDC_LAUNCHBUTTON 104
|
||||
#define WM_INSTALLCOMPLETE_MSG (WM_APP+1)
|
||||
|
||||
/// Global variables
|
||||
static HWND g_buttonHWnd = NULL;
|
||||
static HWND g_checkboxHWnd = NULL;
|
||||
static HWND g_progressHWnd = NULL;
|
||||
static HWND g_CancelbuttonHWnd = NULL;
|
||||
static HWND g_LaunchbuttonHWnd = NULL;
|
||||
static bool g_launchCheckBoxState = true; /// launch checkbox is checked by default
|
||||
static bool g_installing = false; /// variable used to indicate that app installation is in progress
|
||||
#pragma once
|
||||
/// Install UI Header
|
||||
/// UI Functions
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include "Util.hpp"
|
||||
#include <IPackageManager.hpp>
|
||||
#include <IMsixResponse.hpp>
|
||||
#include "resource.h"
|
||||
/// Child window identifiers
|
||||
#define IDC_LAUNCHCHECKBOX 101
|
||||
#define IDC_INSTALLBUTTON 102
|
||||
#define IDC_CANCELBUTTON 103
|
||||
#define IDC_LAUNCHBUTTON 104
|
||||
#define WM_INSTALLCOMPLETE_MSG (WM_APP+1)
|
||||
|
||||
/// Global variables
|
||||
static HWND g_buttonHWnd = NULL;
|
||||
static HWND g_checkboxHWnd = NULL;
|
||||
static HWND g_progressHWnd = NULL;
|
||||
static HWND g_CancelbuttonHWnd = NULL;
|
||||
static HWND g_LaunchbuttonHWnd = NULL;
|
||||
static bool g_launchCheckBoxState = true; /// launch checkbox is checked by default
|
||||
static bool g_installing = false; /// variable used to indicate that app installation is in progress
|
||||
|
||||
|
||||
enum UIType { InstallUIAdd, InstallUIRemove};
|
||||
|
||||
class UI
|
||||
{
|
||||
public:
|
||||
HRESULT ShowUI();
|
||||
HRESULT LaunchInstalledApp();
|
||||
void ConfirmAppCancel(HWND parentHWnd);
|
||||
|
||||
static HRESULT Make(_In_ MsixRequest* msixRequest, _Out_ UI** instance);
|
||||
UI(_In_ Win7MsixInstallerLib::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);
|
||||
}
|
||||
~UI() {}
|
||||
|
||||
private:
|
||||
MsixRequest* m_msixRequest = nullptr;
|
||||
Win7MsixInstallerLib::IPackageManager* m_packageManager = nullptr;
|
||||
std::shared_ptr<Win7MsixInstallerLib::IPackage> m_packageInfo = nullptr;
|
||||
std::wstring m_path;
|
||||
std::shared_ptr<Win7MsixInstallerLib::IMsixResponse> m_msixResponse;
|
||||
|
||||
//Parent Window Hwnd
|
||||
HWND hWnd = NULL;
|
||||
|
@ -48,18 +58,14 @@ private:
|
|||
std::wstring m_cancelPopUpTitle = GetStringResource(IDS_STRING_CANCEL_POPUP_TITLE);
|
||||
std::wstring m_displayName = L"";
|
||||
std::wstring m_publisherCommonName = L"";
|
||||
ComPtr<IStream> m_logoStream;
|
||||
std::unique_ptr<IStream> m_logoStream;
|
||||
std::wstring m_version = L"";
|
||||
int m_numberOfFiles = 0;
|
||||
HRESULT m_loadingPackageInfoCode = 0;
|
||||
HANDLE m_buttonClickedEvent;
|
||||
|
||||
UI() {}
|
||||
UI(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest)
|
||||
{
|
||||
m_buttonClickedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
}
|
||||
|
||||
HRESULT m_loadingPackageInfoCode = 0;
|
||||
UIType m_type;
|
||||
|
||||
HANDLE m_closeUI;
|
||||
|
||||
HRESULT ParseInfoFromPackage();
|
||||
|
||||
/// This function sets the parent window hwnd after create window
|
||||
|
@ -91,80 +97,63 @@ public:
|
|||
/// @param windowClass - the class text of the window
|
||||
/// @param windowTitle - the window title
|
||||
int CreateInitWindow(HINSTANCE hInstance, int nCmdShow, const std::wstring& windowClass, const std::wstring& title);
|
||||
void LoadInfo();
|
||||
int GetNumberOfFiles() { return m_numberOfFiles; }
|
||||
void SetButtonClicked() { SetEvent(m_buttonClickedEvent); }
|
||||
|
||||
/// Creates the progress bar
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to add the progress bar to
|
||||
/// @param parentRect - the dimmensions of the parent window
|
||||
/// count: the number of objects to be iterated through in the progress bar
|
||||
BOOL CreateProgressBar(HWND parentHWnd, RECT parentRect, int count);
|
||||
|
||||
/// Create the lower right install button
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to add the button to
|
||||
/// @param parentRect - the specs of the parent window
|
||||
BOOL InstallButton(HWND parentHWnd, RECT parentRect);
|
||||
|
||||
void ButtonClicked();
|
||||
|
||||
/// Creates the progress bar
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to add the progress bar to
|
||||
/// @param parentRect - the dimmensions of the parent window
|
||||
BOOL CreateProgressBar(HWND parentHWnd, RECT parentRect);
|
||||
|
||||
/// Create the lower right install button
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to add the button to
|
||||
/// @param parentRect - the specs of the parent window
|
||||
BOOL InstallButton(HWND parentHWnd, RECT parentRect);
|
||||
|
||||
/// Create the launch when ready checkbox on the bottom left
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to add the checkbox to
|
||||
/// @param parentRect - the specs of the parent window
|
||||
BOOL CreateCheckbox(HWND parentHWnd, RECT parentRect);
|
||||
|
||||
/// @param parentRect - the specs of the parent window
|
||||
BOOL CreateCheckbox(HWND parentHWnd, RECT parentRect);
|
||||
|
||||
/// Create the cancel button on the bottom right corner when user clicks on install
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to add the checkbox to
|
||||
/// @param parentRect - the specs of the parent window
|
||||
BOOL CreateCancelButton(HWND parentHWnd, RECT parentRect);
|
||||
|
||||
/// @param parentRect - the specs of the parent window
|
||||
BOOL CreateCancelButton(HWND parentHWnd, RECT parentRect);
|
||||
|
||||
/// Create the launch button on the botton right after app has been installed
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to add the checkbox to
|
||||
/// @param parentRect - the specs of the parent window
|
||||
/// @param xDiff - the x coordinate difference to create the button from the parent window
|
||||
/// @param yDiff - the y coordinate difference to create the button from the parent window
|
||||
BOOL CreateLaunchButton(HWND parentHWnd, RECT parentRect, int xDiff, int yDiff);
|
||||
|
||||
/// Changes the text of the lower right 'Install' button
|
||||
/// Changes text to 'Update' in case of an update, changes text to 'Reinstall' in case app is already installed on the machine
|
||||
///
|
||||
/// @param newMessage - the message to change the button to
|
||||
BOOL ChangeInstallButtonText(const std::wstring& newMessage);
|
||||
|
||||
/// Change the text of the installation window based on the given input
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to be changed
|
||||
/// @param windowText - the text to change the window to
|
||||
/// @param parentRect - the specs of the parent window
|
||||
/// @param xDiff - the x coordinate difference to create the button from the parent window
|
||||
/// @param yDiff - the y coordinate difference to create the button from the parent window
|
||||
BOOL CreateLaunchButton(HWND parentHWnd, RECT parentRect, int xDiff, int yDiff);
|
||||
|
||||
/// Changes the text of the lower right 'Install' button
|
||||
/// Changes text to 'Update' in case of an update, changes text to 'Reinstall' in case app is already installed on the machine
|
||||
///
|
||||
/// @param newMessage - the message to change the button to
|
||||
BOOL ChangeInstallButtonText(const std::wstring& newMessage);
|
||||
|
||||
/// Change the text of the installation window based on the given input
|
||||
///
|
||||
/// @param parentHWnd - the HWND of the window to be changed
|
||||
/// @param windowText - the text to change the window to
|
||||
BOOL ChangeText(HWND parentHWnd, std::wstring displayText, std::wstring messageText, IStream* logoStream = nullptr);
|
||||
|
||||
/// Increment the progress bar one tick based on preset tick
|
||||
void UpdateProgressBar();
|
||||
|
||||
/// Sends the WM_INSTALLCOMPLETE_MSG message to the main window when app installation is complete
|
||||
/// Sends the WM_INSTALLCOMPLETE_MSG message to the main window when app installation is complete
|
||||
void SendInstallCompleteMsg();
|
||||
|
||||
// The add operation could be an update if V1 version of the package is already installed. Show appropriate UI with respect to operation type
|
||||
/// The add operation could be an update if V1 version of the package is already installed on the machine
|
||||
/// This method checks the same and sets the button and install screen UI text to 'Update'
|
||||
/// The add operation could be an update if V1 version of the package is already installed. Show appropriate UI with respect to operation type
|
||||
/// The add operation could be an update if V1 version of the package is already installed on the machine
|
||||
/// This method checks the same and sets the button and install screen UI text to 'Update'
|
||||
///
|
||||
void PreprocessRequest();
|
||||
|
||||
HRESULT ShowUI();
|
||||
|
||||
void CloseUI();
|
||||
};
|
||||
|
||||
class CreateAndShowUI : IPackageHandler
|
||||
{
|
||||
public:
|
||||
HRESULT ExecuteForAddRequest();
|
||||
|
||||
static const PCWSTR HandlerName;
|
||||
static HRESULT CreateHandler(_In_ MsixRequest* msixRequest, _Out_ IPackageHandler** instance);
|
||||
~CreateAndShowUI() {}
|
||||
private:
|
||||
MsixRequest* m_msixRequest = nullptr;
|
||||
|
||||
CreateAndShowUI() {}
|
||||
CreateAndShowUI(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "generalutil.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
#include <string>
|
||||
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include "FootprintFiles.hpp"
|
||||
#include "FilePaths.hpp"
|
||||
#include "InstallUI.hpp"
|
||||
#include <cstdio>
|
||||
#include <experimental/filesystem> // C++-standard header file name
|
||||
#include <filesystem> // Microsoft-specific implementation header file name
|
||||
|
@ -32,11 +31,13 @@
|
|||
#include "ErrorHandler.hpp"
|
||||
#include "ValidateTargetDeviceFamily.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
// 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;
|
||||
#include <GdiPlus.h>
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
struct HandlerInfo
|
||||
{
|
||||
CreateHandler create;
|
||||
|
@ -46,26 +47,24 @@ struct HandlerInfo
|
|||
|
||||
std::map<PCWSTR, HandlerInfo> AddHandlers =
|
||||
{
|
||||
//HandlerName Function to create NextHandler ErrorHandlerInfo
|
||||
{PopulatePackageInfo::HandlerName, {PopulatePackageInfo::CreateHandler, CreateAndShowUI::HandlerName, ErrorHandler::HandlerName}},
|
||||
{CreateAndShowUI::HandlerName, {CreateAndShowUI::CreateHandler, ValidateTargetDeviceFamily::HandlerName, ErrorHandler::HandlerName}},
|
||||
{ValidateTargetDeviceFamily::HandlerName, {ValidateTargetDeviceFamily::CreateHandler, ProcessPotentialUpdate::HandlerName, ErrorHandler::HandlerName}},
|
||||
{ProcessPotentialUpdate::HandlerName, {ProcessPotentialUpdate::CreateHandler, Extractor::HandlerName, ErrorHandler::HandlerName}},
|
||||
{Extractor::HandlerName, {Extractor::CreateHandler, StartMenuLink::HandlerName, ErrorHandler::HandlerName}},
|
||||
{StartMenuLink::HandlerName, {StartMenuLink::CreateHandler, AddRemovePrograms::HandlerName, ErrorHandler::HandlerName}},
|
||||
{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}},
|
||||
{FileTypeAssociation::HandlerName, {FileTypeAssociation::CreateHandler, InstallComplete::HandlerName, ErrorHandler::HandlerName}},
|
||||
{InstallComplete::HandlerName, {InstallComplete::CreateHandler, nullptr, ErrorHandler::HandlerName}},
|
||||
{ErrorHandler::HandlerName, {ErrorHandler::CreateHandler, nullptr, nullptr}},
|
||||
//HandlerName Function to create NextHandler ErrorHandlerInfo
|
||||
{PopulatePackageInfo::HandlerName, {PopulatePackageInfo::CreateHandler, ProcessPotentialUpdate::HandlerName, ErrorHandler::HandlerName}},
|
||||
{ProcessPotentialUpdate::HandlerName, {ProcessPotentialUpdate::CreateHandler, Extractor::HandlerName, ErrorHandler::HandlerName}},
|
||||
{Extractor::HandlerName, {Extractor::CreateHandler, StartMenuLink::HandlerName, ErrorHandler::HandlerName}},
|
||||
{StartMenuLink::HandlerName, {StartMenuLink::CreateHandler, AddRemovePrograms::HandlerName, ErrorHandler::HandlerName}},
|
||||
{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}},
|
||||
{FileTypeAssociation::HandlerName, {FileTypeAssociation::CreateHandler, InstallComplete::HandlerName, ErrorHandler::HandlerName}},
|
||||
{InstallComplete::HandlerName, {InstallComplete::CreateHandler, nullptr, ErrorHandler::HandlerName}},
|
||||
{ErrorHandler::HandlerName, {ErrorHandler::CreateHandler, nullptr, nullptr}},
|
||||
};
|
||||
|
||||
std::map<PCWSTR, HandlerInfo> RemoveHandlers =
|
||||
{
|
||||
//HandlerName Function to create NextHandler
|
||||
{CreateAndShowUI::HandlerName, {CreateAndShowUI::CreateHandler, StartMenuLink::HandlerName}},
|
||||
{PopulatePackageInfo::HandlerName, {PopulatePackageInfo::CreateHandler, StartMenuLink::HandlerName}},
|
||||
{StartMenuLink::HandlerName, {StartMenuLink::CreateHandler, AddRemovePrograms::HandlerName}},
|
||||
{AddRemovePrograms::HandlerName, {AddRemovePrograms::CreateHandler, Protocol::HandlerName}},
|
||||
{Protocol::HandlerName, {Protocol::CreateHandler, ComInterface::HandlerName}},
|
||||
|
@ -75,108 +74,53 @@ std::map<PCWSTR, HandlerInfo> RemoveHandlers =
|
|||
{Extractor::HandlerName, {Extractor::CreateHandler, nullptr}},
|
||||
};
|
||||
|
||||
HRESULT MsixRequest::Make(OperationType operationType, Flags flags, std::wstring packageFilePath, std::wstring packageFullName, MSIX_VALIDATION_OPTION validationOption, MsixRequest ** outInstance)
|
||||
HRESULT MsixRequest::Make(OperationType operationType, const std::wstring & packageFilePath, std::wstring packageFullName, MSIX_VALIDATION_OPTION validationOption, MsixRequest ** outInstance)
|
||||
{
|
||||
std::unique_ptr<MsixRequest> instance(new MsixRequest());
|
||||
AutoPtr<MsixRequest> instance(new MsixRequest());
|
||||
if (instance == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
instance->m_operationType = operationType;
|
||||
instance->m_flags = flags;
|
||||
instance->m_packageFilePath = packageFilePath;
|
||||
instance->m_packageFullName = packageFullName;
|
||||
instance->m_validationOptions = validationOption;
|
||||
RETURN_IF_FAILED(instance->InitializeFilePathMappings());
|
||||
RETURN_IF_FAILED(FilePathMappings::GetInstance().GetInitializationResult());
|
||||
|
||||
//Set MsixResponse
|
||||
AutoPtr<MsixResponse> localResponse;
|
||||
RETURN_IF_FAILED(MsixResponse::Make(&localResponse));
|
||||
instance->m_msixResponse = localResponse.Detach();
|
||||
instance->m_msixResponse = std::make_shared<MsixResponse>();
|
||||
|
||||
*outInstance = instance.release();
|
||||
*outInstance = instance.Detach();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT MsixRequest::InitializeFilePathMappings()
|
||||
{
|
||||
return m_filePathMappings.Initialize();
|
||||
}
|
||||
|
||||
HRESULT MsixRequest::ProcessRequest()
|
||||
{
|
||||
m_msixResponse->Update(InstallationStep::InstallationStepStarted, 0);
|
||||
|
||||
switch (m_operationType)
|
||||
{
|
||||
case OperationType::Add:
|
||||
{
|
||||
RETURN_IF_FAILED(ProcessAddRequest());
|
||||
break;
|
||||
}
|
||||
case OperationType::Remove:
|
||||
{
|
||||
RETURN_IF_FAILED(ProcessRemoveRequest());
|
||||
break;
|
||||
}
|
||||
case OperationType::FindAllPackages:
|
||||
{
|
||||
RETURN_IF_FAILED(FindAllPackages());
|
||||
break;
|
||||
}
|
||||
case OperationType::FindPackage:
|
||||
{
|
||||
RETURN_IF_FAILED(DisplayPackageInfo());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT MsixRequest::DisplayPackageInfo()
|
||||
{
|
||||
AutoPtr<IPackageHandler> handler;
|
||||
RETURN_IF_FAILED(PopulatePackageInfo::CreateHandler(this, &handler));
|
||||
HRESULT packageFoundResult = handler->ExecuteForRemoveRequest();
|
||||
|
||||
if (packageFoundResult == S_OK)
|
||||
case OperationType::Add:
|
||||
{
|
||||
std::wcout << std::endl;
|
||||
std::wcout << L"PackageFullName: " << m_packageInfo->GetPackageFullName().c_str() << std::endl;
|
||||
std::wcout << L"DisplayName: " << m_packageInfo->GetDisplayName().c_str() << std::endl;
|
||||
std::wcout << L"DirectoryPath: " << m_packageInfo->GetPackageDirectoryPath().c_str() << std::endl;
|
||||
std::wcout << std::endl;
|
||||
RETURN_IF_FAILED(ProcessAddRequest());
|
||||
break;
|
||||
}
|
||||
else
|
||||
case OperationType::Remove:
|
||||
{
|
||||
std::wcout << std::endl;
|
||||
std::wcout << L"Package not found " << std::endl;
|
||||
RETURN_IF_FAILED(ProcessRemoveRequest());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT MsixRequest::FindAllPackages()
|
||||
{
|
||||
int numPackages = 0;
|
||||
for (auto& p : std::experimental::filesystem::directory_iterator(m_filePathMappings.GetMsix7Directory()))
|
||||
{
|
||||
std::cout << p.path().filename() << std::endl;
|
||||
numPackages++;
|
||||
}
|
||||
|
||||
std::cout << numPackages << " Package(s) found" << std::endl;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT MsixRequest::ProcessAddRequest()
|
||||
{
|
||||
PCWSTR currentHandlerName = PopulatePackageInfo::HandlerName;
|
||||
|
||||
while (currentHandlerName != nullptr)
|
||||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
|
@ -185,10 +129,20 @@ HRESULT MsixRequest::ProcessAddRequest()
|
|||
|
||||
HandlerInfo currentHandler = AddHandlers[currentHandlerName];
|
||||
AutoPtr<IPackageHandler> handler;
|
||||
RETURN_IF_FAILED(currentHandler.create(this, &handler));
|
||||
HRESULT hrAddExecute = handler->ExecuteForAddRequest();
|
||||
if (FAILED(hrAddExecute))
|
||||
auto hrExecute = currentHandler.create(this, &handler);
|
||||
if (FAILED(hrExecute))
|
||||
{
|
||||
if (handler->IsMandatoryForAddRequest())
|
||||
{
|
||||
m_msixResponse->SetErrorStatus(hrExecute, L"Can't create the handler " + std::wstring(currentHandlerName));
|
||||
return hrExecute;
|
||||
}
|
||||
}
|
||||
|
||||
hrExecute = handler->ExecuteForAddRequest();
|
||||
if (FAILED(hrExecute))
|
||||
{
|
||||
m_msixResponse->SetErrorStatus(hrExecute, L"Can't execute the handler " + std::wstring(currentHandlerName));
|
||||
currentHandlerName = currentHandler.errorHandler;
|
||||
}
|
||||
else
|
||||
|
@ -202,13 +156,7 @@ HRESULT MsixRequest::ProcessAddRequest()
|
|||
|
||||
HRESULT MsixRequest::ProcessRemoveRequest()
|
||||
{
|
||||
// Run PopulatePackageInfo separately - if it fails (for instance, if the package is not found) it IS fatal.
|
||||
AutoPtr<IPackageHandler> handler;
|
||||
RETURN_IF_FAILED(PopulatePackageInfo::CreateHandler(this, &handler));
|
||||
RETURN_IF_FAILED(handler->ExecuteForRemoveRequest());
|
||||
|
||||
PCWSTR currentHandlerName = CreateAndShowUI::HandlerName;
|
||||
|
||||
PCWSTR currentHandlerName = PopulatePackageInfo::HandlerName;
|
||||
while (currentHandlerName != nullptr)
|
||||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
|
@ -217,8 +165,18 @@ HRESULT MsixRequest::ProcessRemoveRequest()
|
|||
|
||||
HandlerInfo currentHandler = RemoveHandlers[currentHandlerName];
|
||||
AutoPtr<IPackageHandler> handler;
|
||||
RETURN_IF_FAILED(currentHandler.create(this, &handler));
|
||||
HRESULT hrExecute = handler->ExecuteForRemoveRequest();
|
||||
HRESULT hrExecute = currentHandler.create(this, &handler);
|
||||
if (FAILED(hrExecute))
|
||||
{
|
||||
if (handler->IsMandatoryForAddRequest())
|
||||
{
|
||||
m_msixResponse->SetErrorStatus(hrExecute, L"Can't create the handler " + std::wstring(currentHandlerName));
|
||||
m_msixResponse->Update(InstallationStep::InstallationStepError, 0);
|
||||
return hrExecute;
|
||||
}
|
||||
}
|
||||
|
||||
hrExecute = handler->ExecuteForRemoveRequest();
|
||||
if (FAILED(hrExecute))
|
||||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
|
@ -226,6 +184,11 @@ HRESULT MsixRequest::ProcessRemoveRequest()
|
|||
TraceLoggingLevel(WINEVENT_LEVEL_WARNING),
|
||||
TraceLoggingValue(currentHandlerName, "HandlerName"),
|
||||
TraceLoggingValue(hrExecute, "HR"));
|
||||
if (handler->IsMandatoryForRemoveRequest())
|
||||
{
|
||||
m_msixResponse->SetErrorStatus(hrExecute, L"Can't execute the handler " + std::wstring(currentHandlerName));
|
||||
return hrExecute;
|
||||
}
|
||||
}
|
||||
|
||||
currentHandlerName = currentHandler.nextHandler;
|
||||
|
@ -234,12 +197,16 @@ HRESULT MsixRequest::ProcessRemoveRequest()
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void MsixRequest::SetUI(UI * ui)
|
||||
{
|
||||
m_UI = ui;
|
||||
}
|
||||
|
||||
void MsixRequest::SetPackageInfo(PackageInfo* packageInfo)
|
||||
void MsixRequest::SetPackageInfo(std::shared_ptr<PackageBase> packageInfo)
|
||||
{
|
||||
m_packageInfo = packageInfo;
|
||||
}
|
||||
|
||||
|
||||
std::wstring MsixRequest::GetPackageDirectoryPath()
|
||||
{
|
||||
if (m_packageInfo == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return FilePathMappings::GetInstance().GetMsix7Directory() + m_packageInfo->GetPackageFullName();
|
||||
}
|
|
@ -1,25 +1,16 @@
|
|||
#pragma once
|
||||
#include "PackageInfo.hpp"
|
||||
#include "Package.hpp"
|
||||
#include "FilePaths.hpp"
|
||||
#include "MsixResponse.hpp"
|
||||
class UI;
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
enum OperationType
|
||||
{
|
||||
Undefined = 0,
|
||||
Add = 1,
|
||||
Remove = 2,
|
||||
FindPackage = 3,
|
||||
FindAllPackages = 4,
|
||||
};
|
||||
|
||||
enum Flags
|
||||
{
|
||||
NoFlags = 0,
|
||||
QuietUX = 0x1,
|
||||
};
|
||||
DEFINE_ENUM_FLAG_OPERATORS(Flags);
|
||||
|
||||
/// MsixRequest represents what this instance of the executable will be doing and tracks the state of the current operation
|
||||
class MsixRequest
|
||||
{
|
||||
|
@ -28,78 +19,56 @@ private:
|
|||
std::wstring m_packageFilePath;
|
||||
std::wstring m_packageFullName;
|
||||
MSIX_VALIDATION_OPTION m_validationOptions = MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL;
|
||||
Flags m_flags = NoFlags;
|
||||
OperationType m_operationType = Add;
|
||||
FilePathMappings m_filePathMappings;
|
||||
|
||||
/// Filled by PopulatePackageInfo
|
||||
AutoPtr<PackageInfo> m_packageInfo;
|
||||
|
||||
/// Filled in by CreateAndShowUI
|
||||
AutoPtr<UI> m_UI;
|
||||
std::shared_ptr<PackageBase> m_packageInfo;
|
||||
|
||||
/// MsixResponse object populated by handlers
|
||||
AutoPtr<MsixResponse> m_msixResponse;
|
||||
std::shared_ptr<MsixResponse> m_msixResponse;
|
||||
|
||||
protected:
|
||||
MsixRequest() {}
|
||||
public:
|
||||
static HRESULT Make(OperationType operationType, Flags flags, std::wstring packageFilePath, std::wstring packageFullName, MSIX_VALIDATION_OPTION validationOption, MsixRequest** outInstance);
|
||||
static HRESULT Make(OperationType operationType, const std::wstring & packageFilePath, std::wstring packageFullName, MSIX_VALIDATION_OPTION validationOption, MsixRequest** outInstance);
|
||||
|
||||
/// The main function processes the request based on whichever operation type was requested and then
|
||||
/// going through the sequence of individual handlers.
|
||||
HRESULT ProcessRequest();
|
||||
|
||||
/// Called by PopulatePackageInfo
|
||||
void SetPackageInfo(PackageInfo* packageInfo);
|
||||
|
||||
/// Called by CreateAndShowUI
|
||||
void SetUI(UI* ui);
|
||||
|
||||
// Getters
|
||||
inline MSIX_VALIDATION_OPTION GetValidationOptions() { return m_validationOptions; }
|
||||
inline PCWSTR GetPackageFilePath() { return m_packageFilePath.c_str(); }
|
||||
inline PCWSTR GetPackageFullName() { return m_packageFullName.c_str(); }
|
||||
|
||||
inline FilePathMappings* GetFilePathMappings() { return &m_filePathMappings; }
|
||||
|
||||
/// @return can return null if called before PopulatePackageInfo.
|
||||
PackageInfo* GetPackageInfo() { return m_packageInfo; }
|
||||
|
||||
/// @return can return null if called before CreateAndShowUI or if Flags::QuietUX was passed in and there is no UI.
|
||||
UI* GetUI() { return m_UI; }
|
||||
inline bool IsQuietUX() { return (m_flags & Flags::QuietUX) == Flags::QuietUX; }
|
||||
|
||||
inline bool IsRemove()
|
||||
bool IsRemove()
|
||||
{
|
||||
return m_operationType == OperationType::Remove;
|
||||
}
|
||||
|
||||
inline bool AllowSignatureOriginUnknown()
|
||||
bool AllowSignatureOriginUnknown()
|
||||
{
|
||||
m_validationOptions = static_cast<MSIX_VALIDATION_OPTION>(m_validationOptions | MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline MSIX_VALIDATION_OPTION GetValidationOptions() { return m_validationOptions; }
|
||||
inline PCWSTR GetPackageFilePath() { return m_packageFilePath.c_str(); }
|
||||
inline PCWSTR GetPackageFullName() { return m_packageFullName.c_str(); }
|
||||
|
||||
/// Retrieves the msixResponse object
|
||||
///
|
||||
/// @return m_msixResponse object
|
||||
MsixResponse* GetMsixResponse() { return m_msixResponse; }
|
||||
std::shared_ptr<MsixResponse> GetMsixResponse() { return m_msixResponse; }
|
||||
|
||||
/// Called by PopulatePackageInfo
|
||||
void SetPackageInfo(std::shared_ptr<PackageBase> packageInfo);
|
||||
std::wstring GetPackageDirectoryPath();
|
||||
|
||||
/// @return can return null if called before PopulatePackageInfo.
|
||||
std::shared_ptr<PackageBase> GetPackageInfo() { return m_packageInfo; }
|
||||
|
||||
private:
|
||||
/// FilePath Mappings maps the VFS tokens (e.g. Windows) to the actual folder on disk (e.g. C:\windows)
|
||||
HRESULT InitializeFilePathMappings();
|
||||
|
||||
/// This handles FindAllPackages operation and finds all packages installed by the Win7MSIXInstaller
|
||||
HRESULT FindAllPackages();
|
||||
|
||||
/// This handles Add operation and proceeds through each of the AddSequenceHandlers to install the package
|
||||
HRESULT ProcessAddRequest();
|
||||
|
||||
/// This handles Remove operation and proceeds through each of the RemoveSequenceHandlers to uninstall the package
|
||||
HRESULT ProcessRemoveRequest();
|
||||
|
||||
/// This handles FindPackage operation and displays the package info for a given package.
|
||||
/// @return E_NOT_SET when the package could not be found
|
||||
HRESULT DisplayPackageInfo();
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,18 +1,36 @@
|
|||
#include "generalutil.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "MsixResponse.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
HRESULT MsixResponse::Make(MsixResponse ** outInstance)
|
||||
void MsixResponse::Update(InstallationStep status, float progress)
|
||||
{
|
||||
std::unique_ptr<MsixResponse> instance(new MsixResponse());
|
||||
if (instance == nullptr)
|
||||
if (m_percentage == progress && m_status == status)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
instance->m_hresultTextCode = NULL;
|
||||
instance->m_textStatus = NULL;
|
||||
instance->m_isInstallCancelled = false;
|
||||
*outInstance = instance.release();
|
||||
m_percentage = progress;
|
||||
m_status = status;
|
||||
if (m_callback)
|
||||
{
|
||||
m_callback(*this);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
void MsixResponse::SetCallback(std::function<void(const IMsixResponse& sender)> callback)
|
||||
{
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
void MsixResponse::SetErrorStatus(HRESULT errorCode, std::wstring errorText)
|
||||
{
|
||||
m_percentage = 0;
|
||||
m_status = InstallationStep::InstallationStepError;
|
||||
m_hresultTextCode = errorCode;
|
||||
m_textStatus = errorText;
|
||||
|
||||
if (m_callback)
|
||||
{
|
||||
m_callback(*this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include "GeneralUtil.hpp"
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include "IMsixResponse.hpp"
|
||||
|
||||
#include "GeneralUtil.hpp"
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// The response class tracks the response state of the msix deploy operation
|
||||
/// (if the operation was cancelled, progress bar updates)
|
||||
class MsixResponse
|
||||
class MsixResponse: public IMsixResponse
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -13,15 +17,21 @@ private:
|
|||
bool m_isInstallCancelled = false;
|
||||
|
||||
/// HResult to be populated by handlers in the msix response
|
||||
HRESULT m_hresultTextCode;
|
||||
HRESULT m_hresultTextCode = 0;
|
||||
|
||||
/// Detailed text status of the msix response
|
||||
PCWSTR m_textStatus;
|
||||
std::wstring m_textStatus;
|
||||
|
||||
/// Progress percentage of the msix deployment
|
||||
float m_percentage;
|
||||
|
||||
InstallationStep m_status = InstallationStepUnknown;
|
||||
|
||||
/// Callback to indicate how the progress of the installation
|
||||
std::function<void(const IMsixResponse&)> m_callback;
|
||||
|
||||
public:
|
||||
|
||||
static HRESULT Make(MsixResponse** outInstance);
|
||||
|
||||
/// Method used to return the status of the cancel button
|
||||
///
|
||||
/// @return variable indicating the state of cancel button
|
||||
|
@ -31,23 +41,16 @@ public:
|
|||
}
|
||||
|
||||
/// Method used to set the status of the cancel button if 'Cancel' is clicked
|
||||
void CancelRequest()
|
||||
virtual void CancelRequest()
|
||||
{
|
||||
m_isInstallCancelled = true;
|
||||
}
|
||||
|
||||
/// Set Hresult code as passed by handlers in the msix response(not being set currently)
|
||||
///
|
||||
/// @param hresult - hresult value passed
|
||||
inline void SetHResultTextCode(HRESULT hresult)
|
||||
{
|
||||
m_hresultTextCode = hresult;
|
||||
}
|
||||
|
||||
/// Get the Hresult value in an msix response
|
||||
///
|
||||
/// @return Hresult code as set in the response
|
||||
inline HRESULT GetHResultTextCode()
|
||||
virtual inline HRESULT GetHResultTextCode() const
|
||||
{
|
||||
return m_hresultTextCode;
|
||||
}
|
||||
|
@ -55,7 +58,7 @@ public:
|
|||
/// Sets the detailed text status in the msix response object
|
||||
///
|
||||
/// @param textStatus - the textStatus to be set
|
||||
inline void SetTextStatus(PCWSTR textStatus)
|
||||
inline void SetTextStatus(std::wstring textStatus)
|
||||
{
|
||||
m_textStatus = textStatus;
|
||||
}
|
||||
|
@ -63,8 +66,42 @@ public:
|
|||
/// Returns the detailed text status as set in the msix response object
|
||||
///
|
||||
/// @return textStatus in the msix response
|
||||
inline PCWSTR GetTextStatus()
|
||||
virtual inline std::wstring GetTextStatus() const
|
||||
{
|
||||
return m_textStatus;
|
||||
}
|
||||
};
|
||||
|
||||
/// Update response and send a callback to the UI
|
||||
///
|
||||
/// @param status - current step of the installation
|
||||
/// @param percentage - installation progresss percentage
|
||||
void Update(InstallationStep status, float percentage);
|
||||
|
||||
/// Update response to indicate an error status
|
||||
///
|
||||
/// @param errorCode - code associated to the error
|
||||
/// @param errorText - description of the error
|
||||
void SetErrorStatus(HRESULT errorCode, std::wstring errorText);
|
||||
|
||||
/// Set a callback for the UI
|
||||
///
|
||||
/// @param callback - callback called when status or percentage change
|
||||
virtual void SetCallback(std::function<void(const IMsixResponse&)> callback);
|
||||
|
||||
/// Get the installation progress percentage
|
||||
///
|
||||
/// @return the percentage (from 0 to 100)
|
||||
virtual inline float GetPercentage() const
|
||||
{
|
||||
return m_percentage;
|
||||
}
|
||||
|
||||
/// Get the installation status
|
||||
///
|
||||
/// @return the installation status
|
||||
virtual inline InstallationStep GetStatus() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,11 +1,51 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include "PackageInfo.hpp"
|
||||
#include "Package.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include <fstream>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
HRESULT PackageInfo::SetExecutableAndAppIdFromManifestElement(IMsixElement* element, PCWSTR packageFullName, MsixRequest * msixRequest)
|
||||
//
|
||||
// Gets the stream of a file.
|
||||
//
|
||||
// Parameters:
|
||||
// package - The package reader for the app package.
|
||||
// name - Name of the file.
|
||||
// stream - The stream for the file.
|
||||
//
|
||||
|
||||
HRESULT GetStreamFromFile(IAppxPackageReader* package, LPCWCHAR name, IStream** stream)
|
||||
{
|
||||
*stream = nullptr;
|
||||
|
||||
ComPtr<IAppxFilesEnumerator> files;
|
||||
RETURN_IF_FAILED(package->GetPayloadFiles(&files));
|
||||
|
||||
BOOL hasCurrent = FALSE;
|
||||
RETURN_IF_FAILED(files->GetHasCurrent(&hasCurrent));
|
||||
while (hasCurrent)
|
||||
{
|
||||
ComPtr<IAppxFile> file;
|
||||
RETURN_IF_FAILED(files->GetCurrent(&file));
|
||||
Text<WCHAR> fileName;
|
||||
file->GetName(&fileName);
|
||||
if (wcscmp(fileName.Get(), name) == 0)
|
||||
{
|
||||
RETURN_IF_FAILED(file->GetStream(stream));
|
||||
return S_OK;
|
||||
}
|
||||
RETURN_IF_FAILED(files->MoveNext(&hasCurrent));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
std::wstring PackageBase::GetVersion()
|
||||
{
|
||||
return Win7MsixInstallerLib_ConvertVersionToString(m_version);
|
||||
}
|
||||
|
||||
HRESULT PackageBase::ParseManifest(IMsixElement* element)
|
||||
{
|
||||
BOOL hc = FALSE;
|
||||
ComPtr<IMsixElementEnumerator> applicationElementEnum;
|
||||
|
@ -26,23 +66,14 @@ HRESULT PackageInfo::SetExecutableAndAppIdFromManifestElement(IMsixElement* elem
|
|||
RETURN_IF_FAILED(applicationElementEnum->GetCurrent(&applicationElement));
|
||||
|
||||
Text<wchar_t> executablePath;
|
||||
RETURN_IF_FAILED(applicationElement->GetAttributeValue(L"Executable", &executablePath));
|
||||
m_executableFilePath = msixRequest->GetFilePathMappings()->GetExecutablePath(executablePath.Get(), packageFullName);
|
||||
|
||||
Text<wchar_t> applicationId;
|
||||
RETURN_IF_FAILED(applicationElement->GetAttributeValue(L"Executable", &executablePath));
|
||||
RETURN_IF_FAILED(applicationElement->GetAttributeValue(L"Id", &applicationId));
|
||||
m_relativeExecutableFilePath = executablePath.Get();
|
||||
m_applicationId = applicationId.Get();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT PackageInfo::SetDisplayNameFromManifestElement(IMsixElement* element)
|
||||
{
|
||||
ComPtr<IMsixElementEnumerator> visualElementsEnum;
|
||||
RETURN_IF_FAILED(element->GetElements(
|
||||
L"/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']",
|
||||
&visualElementsEnum));
|
||||
BOOL hc = FALSE;
|
||||
RETURN_IF_FAILED(applicationElement->GetElements(L"*[local-name()='VisualElements']", &visualElementsEnum));
|
||||
RETURN_IF_FAILED(visualElementsEnum->GetHasCurrent(&hc));
|
||||
if (!hc)
|
||||
{
|
||||
|
@ -59,27 +90,17 @@ HRESULT PackageInfo::SetDisplayNameFromManifestElement(IMsixElement* element)
|
|||
RETURN_IF_FAILED(visualElementsElement->GetAttributeValue(L"DisplayName", &displayName));
|
||||
m_displayName = displayName.Get();
|
||||
|
||||
Text<WCHAR> logo;
|
||||
RETURN_IF_FAILED(visualElementsElement->GetAttributeValue(L"Square150x150Logo", &logo));
|
||||
m_relativeLogoPath = logo.Get();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT PackageInfo::MakeFromManifestReader(IAppxManifestReader * manifestReader, MsixRequest * msixRequest, PackageInfo ** packageInfo)
|
||||
{
|
||||
std::unique_ptr<PackageInfo> instance(new PackageInfo());
|
||||
if (instance == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
RETURN_IF_FAILED(instance->SetManifestReader(manifestReader, msixRequest));
|
||||
|
||||
*packageInfo = instance.release();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT PackageInfo::MakeFromPackageReader(IAppxPackageReader * packageReader, MsixRequest * msixRequest, PackageInfo ** packageInfo)
|
||||
HRESULT Package::MakeFromPackageReader(IAppxPackageReader * packageReader, std::shared_ptr<Package> * packageInfo)
|
||||
{
|
||||
std::unique_ptr<PackageInfo> instance(new PackageInfo());
|
||||
std::shared_ptr<Package> instance = std::make_shared<Package>();
|
||||
if (instance == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -89,7 +110,7 @@ HRESULT PackageInfo::MakeFromPackageReader(IAppxPackageReader * packageReader, M
|
|||
|
||||
ComPtr<IAppxManifestReader> manifestReader;
|
||||
RETURN_IF_FAILED(packageReader->GetManifest(&manifestReader));
|
||||
RETURN_IF_FAILED(instance->SetManifestReader(manifestReader.Get(), msixRequest));
|
||||
RETURN_IF_FAILED(instance->SetManifestReader(manifestReader.Get()));
|
||||
|
||||
// Get the number of payload files
|
||||
DWORD numberOfPayloadFiles = 0;
|
||||
|
@ -105,27 +126,32 @@ HRESULT PackageInfo::MakeFromPackageReader(IAppxPackageReader * packageReader, M
|
|||
}
|
||||
instance->m_numberOfPayloadFiles = numberOfPayloadFiles;
|
||||
|
||||
*packageInfo = instance.release();
|
||||
*packageInfo = instance;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT PackageInfo::SetManifestReader(IAppxManifestReader * manifestReader, MsixRequest * msixRequest)
|
||||
HRESULT PackageBase::SetManifestReader(IAppxManifestReader * manifestReader)
|
||||
{
|
||||
m_manifestReader = manifestReader;
|
||||
|
||||
std::wstring msix7DirectoryPath = msixRequest->GetFilePathMappings()->GetMsix7Directory();
|
||||
|
||||
// Also fill other fields that come from the manifest reader
|
||||
ComPtr<IAppxManifestPackageId> manifestId;
|
||||
RETURN_IF_FAILED(manifestReader->GetPackageId(&manifestId));
|
||||
RETURN_IF_FAILED(manifestId->GetPublisher(&m_publisher));
|
||||
|
||||
Text<WCHAR> publisher;
|
||||
RETURN_IF_FAILED(manifestId->GetPublisher(&publisher));
|
||||
m_publisher = publisher.Get();
|
||||
|
||||
m_publisherName = m_publisher.substr(m_publisher.find_first_of(L"=") + 1,
|
||||
m_publisher.find_first_of(L",") - m_publisher.find_first_of(L"=") - 1);
|
||||
|
||||
RETURN_IF_FAILED(manifestId->GetVersion(&m_version));
|
||||
|
||||
Text<WCHAR> packageFullName;
|
||||
RETURN_IF_FAILED(manifestId->GetPackageFullName(&packageFullName));
|
||||
m_packageFullName = packageFullName.Get();
|
||||
m_packageDirectoryPath = msix7DirectoryPath + packageFullName.Get();
|
||||
m_packageFamilyName = Win7MsixInstallerLib_GetFamilyNameFromFullName(m_packageFullName);
|
||||
|
||||
ComPtr<IMsixDocumentElement> domElement;
|
||||
RETURN_IF_FAILED(manifestReader->QueryInterface(UuidOfImpl<IMsixDocumentElement>::iid, reinterpret_cast<void**>(&domElement)));
|
||||
|
@ -133,9 +159,7 @@ HRESULT PackageInfo::SetManifestReader(IAppxManifestReader * manifestReader, Msi
|
|||
ComPtr<IMsixElement> element;
|
||||
RETURN_IF_FAILED(domElement->GetDocumentElement(&element));
|
||||
|
||||
RETURN_IF_FAILED(SetExecutableAndAppIdFromManifestElement(element.Get(), packageFullName.Get(), msixRequest));
|
||||
|
||||
RETURN_IF_FAILED(SetDisplayNameFromManifestElement(element.Get()));
|
||||
RETURN_IF_FAILED(ParseManifest(element.Get()));
|
||||
|
||||
Text<WCHAR> packageFamilyName;
|
||||
RETURN_IF_FAILED(manifestId->GetPackageFamilyName(&packageFamilyName));
|
||||
|
@ -143,5 +167,48 @@ HRESULT PackageInfo::SetManifestReader(IAppxManifestReader * manifestReader, Msi
|
|||
{
|
||||
m_appUserModelId = std::wstring(packageFamilyName.Get()) + L"!" + m_applicationId;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
std::unique_ptr<IStream> Package::GetLogo()
|
||||
{
|
||||
if (m_packageReader.Get() == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IStream * logoStream;
|
||||
if (GetStreamFromFile(m_packageReader.Get(), m_relativeLogoPath.data(), &logoStream) == S_OK)
|
||||
{
|
||||
return std::unique_ptr<IStream>(logoStream);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<IStream> InstalledPackage::GetLogo()
|
||||
{
|
||||
auto iconPath = m_packageDirectoryPath + m_relativeLogoPath;
|
||||
IStream* stream;
|
||||
if (SUCCEEDED(CreateStreamOnFileUTF16(iconPath.c_str(), true, &stream)))
|
||||
{
|
||||
return std::unique_ptr<IStream>(stream);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
HRESULT InstalledPackage::MakeFromManifestReader(const std::wstring & directoryPath, IAppxManifestReader * manifestReader, std::shared_ptr<InstalledPackage> * packageInfo)
|
||||
{
|
||||
std::shared_ptr<InstalledPackage> instance = std::make_shared<InstalledPackage>();
|
||||
if (instance == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
RETURN_IF_FAILED(instance->SetManifestReader(manifestReader));
|
||||
instance->m_packageDirectoryPath = directoryPath + L"\\";
|
||||
|
||||
*packageInfo = instance;
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
#pragma once
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "AppxPackaging.hpp"
|
||||
#include "MSIXWindows.hpp"
|
||||
#include "IPackage.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
|
||||
class PackageBase
|
||||
{
|
||||
protected:
|
||||
std::wstring m_packageFullName;
|
||||
std::wstring m_packageFamilyName;
|
||||
std::wstring m_relativeExecutableFilePath;
|
||||
std::wstring m_displayName;
|
||||
std::wstring m_appUserModelId;
|
||||
std::wstring m_applicationId;
|
||||
unsigned long long m_version = 0;
|
||||
std::wstring m_publisher;
|
||||
std::wstring m_publisherName;
|
||||
std::wstring m_relativeLogoPath;
|
||||
|
||||
ComPtr<IAppxManifestReader> m_manifestReader;
|
||||
unsigned int m_numberOfPayloadFiles = 0;
|
||||
public:
|
||||
std::wstring GetPackageFullName() { return m_packageFullName; }
|
||||
std::wstring GetPackageFamilyName() { return m_packageFamilyName; }
|
||||
std::wstring GetRelativeExecutableFilePath() { return m_relativeExecutableFilePath; }
|
||||
std::wstring GetDisplayName() { return m_displayName; }
|
||||
std::wstring GetId() { return m_appUserModelId; }
|
||||
unsigned long long GetVersionNumber() { return m_version; }
|
||||
std::wstring GetVersion();
|
||||
std::wstring GetPublisher() { return m_publisher; }
|
||||
std::wstring GetPublisherDisplayName() { return m_publisherName; }
|
||||
|
||||
protected:
|
||||
PackageBase() {}
|
||||
/// Sets the manifest reader, and other fields derived from the manifest
|
||||
/// Specifically, packageFullName, packageDirectoryPath, executableFilePath, displayname, version and publisher.
|
||||
///
|
||||
/// @param manifestReader - manifestReader to set
|
||||
HRESULT SetManifestReader(IAppxManifestReader* manifestReader);
|
||||
/// Parse the manifest file
|
||||
///
|
||||
/// @param element - the root node of the manifest file
|
||||
HRESULT ParseManifest(IMsixElement * element);
|
||||
public:
|
||||
virtual ~PackageBase()
|
||||
{
|
||||
ReleaseManifest();
|
||||
}
|
||||
unsigned int GetNumberOfPayloadFiles() { return m_numberOfPayloadFiles; }
|
||||
|
||||
// Getters
|
||||
IAppxManifestReader * GetManifestReader() { return m_manifestReader.Get(); }
|
||||
/// This is meant only to be called when deleting the manifest file; the reader needs to first be released so it can be deleted
|
||||
void ReleaseManifest() {
|
||||
m_manifestReader.Release();
|
||||
}
|
||||
};
|
||||
|
||||
class Package : public PackageBase, public IPackage
|
||||
{
|
||||
public:
|
||||
std::wstring GetPackageFullName() { return m_packageFullName; }
|
||||
std::wstring GetPackageFamilyName() { return m_packageFamilyName; }
|
||||
std::wstring GetRelativeExecutableFilePath() { return m_relativeExecutableFilePath; }
|
||||
std::wstring GetDisplayName() { return m_displayName; }
|
||||
std::wstring GetId() { return m_appUserModelId; }
|
||||
unsigned long long GetVersionNumber() { return m_version; }
|
||||
std::wstring GetVersion() { return PackageBase::GetVersion(); }
|
||||
std::wstring GetPublisher() { return m_publisher; }
|
||||
std::wstring GetPublisherDisplayName() { return m_publisherName; }
|
||||
std::unique_ptr<IStream> GetLogo();
|
||||
IAppxPackageReader * GetPackageReader() { return m_packageReader.Get(); }
|
||||
|
||||
/// Create a Package using the package reader. This is intended for Add scenarios where
|
||||
/// the actual .msix package file is given.
|
||||
static HRESULT MakeFromPackageReader(IAppxPackageReader* packageReader, std::shared_ptr<Package>* packageInfo);
|
||||
|
||||
virtual ~Package()
|
||||
{
|
||||
m_packageReader.Release();
|
||||
}
|
||||
Package() : PackageBase(), IPackage(){}
|
||||
|
||||
private:
|
||||
/// PackageReader and payloadFiles are available on Add, but not Remove because it's created off the original package itself which is no longer available once it's been installed.
|
||||
ComPtr<IAppxPackageReader> m_packageReader;
|
||||
};
|
||||
|
||||
class InstalledPackage : public PackageBase, public IInstalledPackage
|
||||
{
|
||||
public:
|
||||
std::wstring GetPackageFullName() { return m_packageFullName; }
|
||||
std::wstring GetPackageFamilyName() { return m_packageFamilyName; }
|
||||
std::wstring GetRelativeExecutableFilePath() { return m_relativeExecutableFilePath; }
|
||||
std::wstring GetDisplayName() { return m_displayName; }
|
||||
std::wstring GetId() { return m_appUserModelId; }
|
||||
unsigned long long GetVersionNumber() { return m_version; }
|
||||
std::wstring GetVersion() { return PackageBase::GetVersion(); }
|
||||
std::wstring GetPublisher() { return m_publisher; }
|
||||
std::wstring GetPublisherDisplayName() { return m_publisherName; }
|
||||
std::unique_ptr<IStream> GetLogo();
|
||||
|
||||
virtual std::wstring GetFullExecutableFilePath()
|
||||
{
|
||||
return m_packageDirectoryPath + m_relativeExecutableFilePath;
|
||||
}
|
||||
virtual std::wstring GetInstalledLocation()
|
||||
{
|
||||
return m_packageDirectoryPath;
|
||||
}
|
||||
|
||||
/// Create a InstalledPackage using the manifest reader and directory path. This is intended for Remove scenarios where
|
||||
/// the actual .msix package file is no longer accessible.
|
||||
static HRESULT MakeFromManifestReader(const std::wstring & directoryPath, IAppxManifestReader* manifestReader, std::shared_ptr<InstalledPackage>* packageInfo);
|
||||
InstalledPackage() :PackageBase(), IInstalledPackage() {}
|
||||
private:
|
||||
std::wstring m_packageDirectoryPath;
|
||||
};
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
#pragma once
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "AppxPackaging.hpp"
|
||||
#include "MSIXWindows.hpp"
|
||||
|
||||
class MsixRequest;
|
||||
|
||||
class PackageInfo
|
||||
{
|
||||
private:
|
||||
ComPtr<IAppxManifestReader> m_manifestReader;
|
||||
std::wstring m_packageFullName;
|
||||
std::wstring m_packageDirectoryPath;
|
||||
std::wstring m_executableFilePath;
|
||||
std::wstring m_displayName;
|
||||
std::wstring m_appUserModelId;
|
||||
std::wstring m_applicationId;
|
||||
UINT64 m_version = 0;
|
||||
Text<WCHAR> m_publisher;
|
||||
|
||||
/// PackageReader and payloadFiles are available on Add, but not Remove because it's created off the original package itself which is no longer available once it's been installed.
|
||||
ComPtr<IAppxPackageReader> m_packageReader;
|
||||
DWORD m_numberOfPayloadFiles = 0;
|
||||
|
||||
/// Sets the manifest reader, and other fields derived from the manifest
|
||||
/// Specifically, packageFullName, packageDirectoryPath, executableFilePath, displayname, version and publisher.
|
||||
///
|
||||
/// @param manifestReader - manifestReader to set
|
||||
/// @param msix7DirectoryPath - the root msix7 directory path, which is the parent directory of the package directory.
|
||||
HRESULT SetManifestReader(IAppxManifestReader* manifestReader, MsixRequest * msixRequest);
|
||||
|
||||
/// Sets the executable path and app ID by reading it from the manifest element
|
||||
HRESULT SetExecutableAndAppIdFromManifestElement(IMsixElement * element, PCWSTR packageFullName, MsixRequest * msixRequest);
|
||||
|
||||
/// Sets the display name by reading it from the manifest element
|
||||
HRESULT SetDisplayNameFromManifestElement(IMsixElement * element);
|
||||
|
||||
/// Sets the application model user id from the manifest reader
|
||||
HRESULT SetApplicationUserModelIdFromManifestElement(IAppxManifestReader* manifestReader);
|
||||
|
||||
public:
|
||||
/// Create a PackageInfo using the manifest reader and directory path. This is intended for Remove scenarios where
|
||||
/// the actual .msix package file is no longer accessible.
|
||||
static HRESULT MakeFromManifestReader(IAppxManifestReader* manifestReader, MsixRequest * msixRequest, PackageInfo** packageInfo);
|
||||
|
||||
/// Create a PackageInfo using the package reader. This is intended for Add scenarios where
|
||||
/// the actual .msix package file is given.
|
||||
static HRESULT MakeFromPackageReader(IAppxPackageReader* packageReader, MsixRequest * msixRequest, PackageInfo** packageInfo);
|
||||
|
||||
/// When made from manifest reader, it won't have PackageReader available.
|
||||
bool HasPackageReader() { return (m_packageReader.Get() != nullptr); };
|
||||
IAppxPackageReader * GetPackageReader() { return m_packageReader.Get(); }
|
||||
DWORD GetNumberOfPayloadFiles() { return m_numberOfPayloadFiles; }
|
||||
|
||||
// Getters
|
||||
IAppxManifestReader * GetManifestReader() { return m_manifestReader.Get(); }
|
||||
std::wstring GetPackageFullName() { return m_packageFullName; }
|
||||
std::wstring GetPackageDirectoryPath() { return m_packageDirectoryPath; }
|
||||
std::wstring GetExecutableFilePath() { return m_executableFilePath; }
|
||||
std::wstring GetDisplayName() { return m_displayName; }
|
||||
std::wstring GetAppModelUserId() { return m_appUserModelId; }
|
||||
UINT64 GetVersion() { return m_version; }
|
||||
PCWSTR GetPublisher() { return m_publisher.Get(); }
|
||||
|
||||
/// This is meant only to be called when deleting the manifest file; the reader needs to first be released so it can be deleted
|
||||
void ReleaseManifest() { m_manifestReader.Release(); }
|
||||
};
|
||||
|
||||
|
|
@ -2,75 +2,95 @@
|
|||
|
||||
#include "PopulatePackageInfo.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "FilePaths.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include <experimental/filesystem> // C++-standard header file name
|
||||
#include "Constants.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR PopulatePackageInfo::HandlerName = L"PopulatePackageInfo";
|
||||
|
||||
HRESULT PopulatePackageInfo::CreatePackageReader()
|
||||
HRESULT PopulatePackageInfo::GetPackageInfoFromPackage(const std::wstring & packageFilePath, MSIX_VALIDATION_OPTION validationOption, std::shared_ptr<Package> * packageInfo)
|
||||
{
|
||||
ComPtr<IStream> inputStream;
|
||||
RETURN_IF_FAILED(CreateStreamOnFileUTF16(m_msixRequest->GetPackageFilePath(), /*forRead */ true, &inputStream));
|
||||
RETURN_IF_FAILED(CreateStreamOnFileUTF16(packageFilePath.c_str(), /*forRead */ true, &inputStream));
|
||||
|
||||
// On Win32 platforms CoCreateAppxFactory defaults to CoTaskMemAlloc/CoTaskMemFree
|
||||
// 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(MyAllocate, MyFree, m_msixRequest->GetValidationOptions(), &appxFactory));
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(Win7MsixInstallerLib_MyAllocate, Win7MsixInstallerLib_MyFree, validationOption, &appxFactory));
|
||||
|
||||
// Create a new package reader using the factory.
|
||||
ComPtr<IAppxPackageReader> packageReader;
|
||||
RETURN_IF_FAILED(appxFactory->CreatePackageReader(inputStream.Get(), &packageReader));
|
||||
|
||||
AutoPtr<PackageInfo> packageInfo;
|
||||
RETURN_IF_FAILED(PackageInfo::MakeFromPackageReader(packageReader.Get(), m_msixRequest, &packageInfo));
|
||||
m_msixRequest->SetPackageInfo(packageInfo.Detach());
|
||||
RETURN_IF_FAILED(Package::MakeFromPackageReader(packageReader.Get(), packageInfo));
|
||||
packageReader.Release();
|
||||
inputStream.Release();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT PopulatePackageInfo::GetPackageInfoFromManifest(const std::wstring & directoryPath, MSIX_VALIDATION_OPTION validationOption, std::shared_ptr<InstalledPackage> * packageInfo)
|
||||
{
|
||||
std::wstring manifestPath = directoryPath + manifestFile;
|
||||
|
||||
// On Win32 platforms CoCreateAppxFactory defaults to CoTaskMemAlloc/CoTaskMemFree
|
||||
// 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<IStream> inputStream;
|
||||
RETURN_IF_FAILED(CreateStreamOnFileUTF16(manifestPath.c_str(), /*forRead*/ true, &inputStream));
|
||||
|
||||
// Create a new package reader using the factory.
|
||||
ComPtr<IAppxFactory> appxFactory;
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(Win7MsixInstallerLib_MyAllocate, Win7MsixInstallerLib_MyFree, validationOption, &appxFactory));
|
||||
|
||||
ComPtr<IAppxManifestReader> manifestReader;
|
||||
RETURN_IF_FAILED(appxFactory->CreateManifestReader(inputStream.Get(), &manifestReader));
|
||||
|
||||
RETURN_IF_FAILED(InstalledPackage::MakeFromManifestReader(directoryPath, manifestReader.Get(), packageInfo));
|
||||
manifestReader.Release();
|
||||
inputStream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT PopulatePackageInfo::ExecuteForAddRequest()
|
||||
{
|
||||
RETURN_IF_FAILED(CreatePackageReader());
|
||||
|
||||
std::shared_ptr<Package> packageInfo;
|
||||
RETURN_IF_FAILED(PopulatePackageInfo::GetPackageInfoFromPackage(m_msixRequest->GetPackageFilePath(), m_msixRequest->GetValidationOptions(), &packageInfo));
|
||||
|
||||
if (packageInfo == nullptr)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
m_msixRequest->SetPackageInfo(packageInfo);
|
||||
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"PackageInfo",
|
||||
TraceLoggingValue(m_msixRequest->GetPackageInfo()->GetPackageFullName().c_str(), "PackageFullName"),
|
||||
TraceLoggingValue(m_msixRequest->GetPackageInfo()->GetNumberOfPayloadFiles(), "NumberOfPayloadFiles"),
|
||||
TraceLoggingValue(m_msixRequest->GetPackageInfo()->GetExecutableFilePath().c_str(), "ExecutableFilePath"),
|
||||
TraceLoggingValue(m_msixRequest->GetPackageInfo()->GetDisplayName().c_str(), "DisplayName"));
|
||||
TraceLoggingValue(packageInfo->GetPackageFullName().c_str(), "PackageFullName"),
|
||||
TraceLoggingValue(packageInfo->GetNumberOfPayloadFiles(), "NumberOfPayloadFiles"),
|
||||
TraceLoggingValue(m_msixRequest->GetPackageDirectoryPath().c_str(), "ExecutableFilePath"),
|
||||
TraceLoggingValue(packageInfo->GetDisplayName().c_str(), "DisplayName"));
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT PopulatePackageInfo::ExecuteForRemoveRequest()
|
||||
{
|
||||
std::wstring packageDirectoryPath = m_msixRequest->GetFilePathMappings()->GetMsix7Directory() + m_msixRequest->GetPackageFullName();
|
||||
std::experimental::filesystem::path directory = packageDirectoryPath;
|
||||
if (!std::experimental::filesystem::exists(directory))
|
||||
auto packageDirectoryPath = FilePathMappings::GetInstance().GetMsix7Directory() + m_msixRequest->GetPackageFullName();
|
||||
|
||||
std::shared_ptr<InstalledPackage> package;
|
||||
RETURN_IF_FAILED(GetPackageInfoFromManifest(packageDirectoryPath, MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN, &package));
|
||||
|
||||
if (package == nullptr)
|
||||
{
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Could not find package directory",
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
|
||||
TraceLoggingValue(m_msixRequest->GetPackageFullName(), "PackageFullName"),
|
||||
TraceLoggingValue(directory.c_str(), "PackageDirectoryPath"));
|
||||
return E_NOT_SET;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
std::wstring manifestPath = packageDirectoryPath + manifestFile;
|
||||
ComPtr<IStream> stream;
|
||||
RETURN_IF_FAILED(CreateStreamOnFileUTF16(manifestPath.c_str(), true /*forRead*/, &stream));
|
||||
|
||||
ComPtr<IAppxFactory> appxFactory;
|
||||
RETURN_IF_FAILED(CoCreateAppxFactoryWithHeap(MyAllocate, MyFree, m_msixRequest->GetValidationOptions(), &appxFactory));
|
||||
|
||||
ComPtr<IAppxManifestReader> manifestReader;
|
||||
RETURN_IF_FAILED(appxFactory->CreateManifestReader(stream.Get(), &manifestReader));
|
||||
|
||||
AutoPtr<PackageInfo> packageInfo;
|
||||
RETURN_IF_FAILED(PackageInfo::MakeFromManifestReader(manifestReader.Get(), m_msixRequest, &packageInfo));
|
||||
m_msixRequest->SetPackageInfo(packageInfo.Detach());
|
||||
m_msixRequest->SetPackageInfo(package);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -85,4 +105,4 @@ HRESULT PopulatePackageInfo::CreateHandler(MsixRequest * msixRequest, IPackageHa
|
|||
*instance = localInstance.release();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "Package.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
class PopulatePackageInfo : IPackageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -15,14 +18,18 @@ public:
|
|||
/// @return E_NOT_SET when the package cannot be found
|
||||
HRESULT ExecuteForRemoveRequest();
|
||||
|
||||
bool IsMandatoryForRemoveRequest() { return true; }
|
||||
|
||||
static const PCWSTR HandlerName;
|
||||
static HRESULT CreateHandler(_In_ MsixRequest* msixRequest, _Out_ IPackageHandler** instance);
|
||||
~PopulatePackageInfo() {}
|
||||
|
||||
static HRESULT GetPackageInfoFromManifest(const std::wstring & directoryPath, MSIX_VALIDATION_OPTION validationOption, std::shared_ptr<InstalledPackage> * packageInfo);
|
||||
static HRESULT GetPackageInfoFromPackage(const std::wstring & packageFilePath, MSIX_VALIDATION_OPTION validationOption, std::shared_ptr<Package> * packageInfo);
|
||||
private:
|
||||
MsixRequest* m_msixRequest = nullptr;
|
||||
|
||||
PopulatePackageInfo() {}
|
||||
PopulatePackageInfo(_In_ MsixRequest* msixRequest) : m_msixRequest(msixRequest) {}
|
||||
|
||||
HRESULT CreatePackageReader();
|
||||
};
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#include "ProcessPotentialUpdate.hpp"
|
||||
#include <filesystem>
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
const PCWSTR ProcessPotentialUpdate::HandlerName = L"ProcessPotentialUpdate";
|
||||
|
||||
HRESULT ProcessPotentialUpdate::ExecuteForAddRequest()
|
||||
|
@ -9,13 +10,13 @@ HRESULT ProcessPotentialUpdate::ExecuteForAddRequest()
|
|||
/// This is currently good enough for our requirements; it leverages existing removal codepaths.
|
||||
/// An alternate, more complicated design would have each handler to expose a new Update verb (e.g. ExecuteForUpdate that takes in the old package)
|
||||
/// and each handler would have the opportunity to reason between the old and new packages to perform more efficient updating.
|
||||
std::wstring currentPackageFamilyName = GetFamilyNameFromFullName(m_msixRequest->GetPackageInfo()->GetPackageFullName());
|
||||
std::wstring currentPackageFamilyName = m_msixRequest->GetPackageInfo()->GetPackageFamilyName();
|
||||
|
||||
for (auto& p : std::experimental::filesystem::directory_iterator(m_msixRequest->GetFilePathMappings()->GetMsix7Directory()))
|
||||
for (auto& p : std::experimental::filesystem::directory_iterator(FilePathMappings::GetInstance().GetMsix7Directory()))
|
||||
{
|
||||
std::wstring installedPackageFamilyName = GetFamilyNameFromFullName(p.path().filename());
|
||||
if (CaseInsensitiveEquals(currentPackageFamilyName, installedPackageFamilyName)
|
||||
&& !CaseInsensitiveEquals(m_msixRequest->GetPackageInfo()->GetPackageFullName(), p.path().filename()))
|
||||
std::wstring installedPackageFamilyName = Win7MsixInstallerLib_GetFamilyNameFromFullName(p.path().filename());
|
||||
if (Win7MsixInstallerLib_CaseInsensitiveEquals(currentPackageFamilyName, installedPackageFamilyName)
|
||||
&& !Win7MsixInstallerLib_CaseInsensitiveEquals(m_msixRequest->GetPackageInfo()->GetPackageFullName(), p.path().filename()))
|
||||
{
|
||||
RETURN_IF_FAILED(RemovePackage(p.path().filename()));
|
||||
return S_OK;
|
||||
|
@ -34,7 +35,7 @@ HRESULT ProcessPotentialUpdate::RemovePackage(std::wstring packageFullName)
|
|||
TraceLoggingValue(packageFullName.c_str(), "PackageToBeRemoved"));
|
||||
|
||||
AutoPtr<MsixRequest> localRequest;
|
||||
RETURN_IF_FAILED(MsixRequest::Make(OperationType::Remove, Flags::NoFlags, std::wstring(), packageFullName, MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &localRequest));
|
||||
RETURN_IF_FAILED(MsixRequest::Make(OperationType::Remove, std::wstring(), packageFullName, MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &localRequest));
|
||||
|
||||
const HRESULT hrProcessRequest = localRequest->ProcessRequest();
|
||||
if (FAILED(hrProcessRequest))
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// Determines if the incoming add request is actually an update to an existing package.
|
||||
/// If it is, it'll remove the outdated package
|
||||
class ProcessPotentialUpdate : IPackageHandler
|
||||
|
@ -24,3 +27,4 @@ private:
|
|||
/// Synchronously removes the outdated package before allowing the current request to proceed
|
||||
HRESULT RemovePackage(std::wstring packageFullName);
|
||||
};
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR Protocol::HandlerName = L"Protocol";
|
||||
|
||||
|
@ -42,7 +43,7 @@ HRESULT Protocol::ParseProtocolElement(IMsixElement* protocolElement)
|
|||
Text<wchar_t> logoPath;
|
||||
RETURN_IF_FAILED(logoElement->GetText(&logoPath));
|
||||
|
||||
protocol.logo = m_msixRequest->GetPackageInfo()->GetPackageDirectoryPath() + std::wstring(L"\\") + logoPath.Get();
|
||||
protocol.logo = m_msixRequest->GetPackageDirectoryPath() + std::wstring(L"\\") + logoPath.Get();
|
||||
}
|
||||
|
||||
ComPtr<IMsixElementEnumerator> displayNameEnum;
|
||||
|
@ -148,7 +149,7 @@ HRESULT Protocol::ProcessProtocolForAdd(ProtocolData& protocol)
|
|||
RegistryKey commandKey;
|
||||
RETURN_IF_FAILED(openKey.CreateSubKey(commandKeyName.c_str(), KEY_WRITE, &commandKey));
|
||||
|
||||
std::wstring command = m_msixRequest->GetPackageInfo()->GetExecutableFilePath();
|
||||
std::wstring command = m_msixRequest->GetPackageDirectoryPath() + L"\\" + m_msixRequest->GetPackageInfo()->GetRelativeExecutableFilePath();
|
||||
if (protocol.parameters.c_str() != nullptr)
|
||||
{
|
||||
command += std::wstring(L" ") + protocol.parameters;
|
||||
|
@ -188,7 +189,7 @@ bool Protocol::IsCurrentlyAssociatedWithPackage(PCWSTR name)
|
|||
return false;
|
||||
}
|
||||
|
||||
std::wstring executablePath = m_msixRequest->GetPackageInfo()->GetExecutableFilePath();
|
||||
std::wstring executablePath = m_msixRequest->GetPackageDirectoryPath() + L"\\" + m_msixRequest->GetPackageInfo()->GetRelativeExecutableFilePath();
|
||||
std::wstring currentlyAssociatedExe;
|
||||
if (SUCCEEDED(protocolExeKey.GetStringValue(L"", currentlyAssociatedExe)))
|
||||
{
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
#include "IPackageHandler.hpp"
|
||||
#include "RegistryKey.hpp"
|
||||
#include <vector>
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
|
||||
/// Data structs to be filled in from the information in the manifest
|
||||
struct ProtocolData
|
||||
|
@ -55,4 +59,4 @@ private:
|
|||
/// @param name - the name of the protocol
|
||||
bool IsCurrentlyAssociatedWithPackage(PCWSTR name);
|
||||
};
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
#include "FilePaths.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include <vector>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
struct VirtualRegistryMapping
|
||||
{
|
||||
|
@ -212,7 +213,7 @@ HRESULT RegistryDevirtualizer::DetokenizeData(std::wstring& data)
|
|||
// get the contents of what's in between the braces, i.e. [{token}]
|
||||
std::wstring token = data.substr(beginToken + 2, (endToken - beginToken - 2)); // +2 to skip over [{ characters, -2 to omit }] characters
|
||||
|
||||
std::map<std::wstring, std::wstring> map = m_msixRequest->GetFilePathMappings()->GetMap();
|
||||
std::map<std::wstring, std::wstring> map = FilePathMappings::GetInstance().GetMap();
|
||||
for (auto& pair : map)
|
||||
{
|
||||
if (token.find(pair.first) != std::wstring::npos)
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
#include "MsixRequest.hpp"
|
||||
#include "RegistryKey.hpp"
|
||||
#include <vector>
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// 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"
|
||||
/// The information stored in Registry.dat is referred to here as "virtual registry" or "virtualized registry"
|
||||
|
@ -86,3 +89,4 @@ private:
|
|||
RegistryKey m_rootKey;
|
||||
bool m_hiveFileNameExists = false;
|
||||
};
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#include "RegistryKey.hpp"
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
HRESULT RegistryKey::Open(
|
||||
_In_ const HKEY hkey,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "GeneralUtil.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// Encapsulates and lifetimes the HKEY used by the RegOpenKey et al APIs.
|
||||
class RegistryKey
|
||||
{
|
||||
|
@ -155,4 +156,5 @@ public:
|
|||
protected:
|
||||
std::wstring m_path;
|
||||
HKEY m_hkey = nullptr;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
#include "StartMenuLink.hpp"
|
||||
#include "GeneralUtil.hpp"
|
||||
#include <TraceLoggingProvider.h>
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
const PCWSTR StartMenuLink::HandlerName = L"StartMenuLink";
|
||||
|
||||
|
@ -50,12 +51,12 @@ HRESULT StartMenuLink::ExecuteForAddRequest()
|
|||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
|
||||
}
|
||||
PackageInfo* packageInfo = m_msixRequest->GetPackageInfo();
|
||||
auto packageInfo = m_msixRequest->GetPackageInfo();
|
||||
|
||||
std::wstring filePath = m_msixRequest->GetFilePathMappings()->GetMap()[L"Common Programs"] + L"\\" + packageInfo->GetDisplayName() + L".lnk";
|
||||
std::wstring filePath = FilePathMappings::GetInstance().GetMap()[L"Common Programs"] + L"\\" + packageInfo->GetDisplayName() + L".lnk";
|
||||
|
||||
std::wstring resolvedExecutableFullPath = packageInfo->GetExecutableFilePath();
|
||||
std::wstring appUserModelId = m_msixRequest->GetPackageInfo()->GetAppModelUserId();
|
||||
std::wstring resolvedExecutableFullPath = m_msixRequest->GetPackageDirectoryPath() + L"\\" + packageInfo->GetRelativeExecutableFilePath();
|
||||
std::wstring appUserModelId = m_msixRequest->GetPackageInfo()->GetId();
|
||||
RETURN_IF_FAILED(CreateLink(resolvedExecutableFullPath.c_str(), filePath.c_str(), L"", appUserModelId.c_str()));
|
||||
|
||||
return S_OK;
|
||||
|
@ -63,9 +64,9 @@ HRESULT StartMenuLink::ExecuteForAddRequest()
|
|||
|
||||
HRESULT StartMenuLink::ExecuteForRemoveRequest()
|
||||
{
|
||||
PackageInfo* packageInfo = m_msixRequest->GetPackageInfo();
|
||||
auto packageInfo = m_msixRequest->GetPackageInfo();
|
||||
|
||||
std::wstring filePath = m_msixRequest->GetFilePathMappings()->GetMap()[L"Common Programs"] + L"\\" + packageInfo->GetDisplayName() + L".lnk";
|
||||
std::wstring filePath = FilePathMappings::GetInstance().GetMap()[L"Common Programs"] + L"\\" + packageInfo->GetDisplayName() + L".lnk";
|
||||
|
||||
RETURN_IF_FAILED(DeleteFile(filePath.c_str()));
|
||||
return S_OK;
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "IPackageHandler.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib
|
||||
{
|
||||
/// Handles adding/removing the shortcut in the start menu to launch the application
|
||||
class StartMenuLink : IPackageHandler
|
||||
{
|
||||
|
@ -31,3 +34,4 @@ private:
|
|||
/// @param appUserModelId- Application User Model ID, needed to display toasts.
|
||||
HRESULT CreateLink(PCWSTR targetFilePath, PCWSTR linkFilePath, PCWSTR description, PCWSTR appUserModelId = NULL);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#include "Util.hpp"
|
||||
#include <string>
|
||||
#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);
|
||||
|
||||
WCHAR buffer[MAX_PATH] = L"";
|
||||
int loadStringRet = LoadStringW(instance, resourceId, buffer, ARRAYSIZE(buffer));
|
||||
if (loadStringRet <= 0)
|
||||
{
|
||||
return std::wstring(L"Failed to load string resource");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
|
@ -1,29 +1,8 @@
|
|||
#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
|
||||
///
|
||||
|
@ -36,32 +15,19 @@ std::string utf16_to_utf8(const std::wstring& utf16string);
|
|||
/// @param utf8string - A utf8 string
|
||||
/// @return utf16 string
|
||||
std::wstring utf8_to_utf16(const std::string& utf8string);
|
||||
|
||||
/// 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 ConvertVersionToString(UINT64 version);
|
||||
|
||||
|
||||
/// 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);
|
||||
|
||||
/// 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);
|
||||
|
||||
/// 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);
|
||||
bool CaseInsensitiveEquals(const std::wstring& left, const std::wstring& right);
|
||||
|
||||
//
|
||||
// A designated memory allocator
|
|
@ -6,38 +6,23 @@
|
|||
#include <CommCtrl.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <iomanip>
|
||||
|
||||
#include "GeneralUtil.hpp"
|
||||
#include "FilePaths.hpp"
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include "InstallUI.hpp"
|
||||
#include "CommandLineInterface.hpp"
|
||||
#include "Win7MSIXInstallerLogger.hpp"
|
||||
#include "Util.hpp"
|
||||
#include "resource.h"
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
// 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));
|
||||
#include <Win7MSIXInstallerActions.hpp>
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
// Register the provider
|
||||
TraceLoggingRegister(g_MsixTraceLoggingProvider);
|
||||
TraceLoggingRegister(g_MsixUITraceLoggingProvider);
|
||||
|
||||
HRESULT hrCoInitialize = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
if (FAILED(hrCoInitialize))
|
||||
|
@ -48,20 +33,86 @@ int main(int argc, char * argv[])
|
|||
|
||||
CommandLineInterface cli(argc, argv);
|
||||
|
||||
AutoPtr<MsixRequest> msixRequest;
|
||||
const HRESULT hrCreateRequest = cli.CreateRequest(&msixRequest);
|
||||
const HRESULT hrCreateRequest = cli.Init();
|
||||
if (SUCCEEDED(hrCreateRequest))
|
||||
{
|
||||
const HRESULT hrProcessRequest = msixRequest->ProcessRequest();
|
||||
if (FAILED(hrProcessRequest))
|
||||
switch (cli.GetOperationType())
|
||||
{
|
||||
case OperationType::Add:
|
||||
{
|
||||
AutoPtr<Win7MsixInstallerLib::IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(Win7MsixInstallerLib_CreatePackageManager(&packageManager));
|
||||
|
||||
std::wcout << GetStringResource(IDS_STRING_FAILED_REQUEST) << " " << std::hex << hrProcessRequest << std::endl;
|
||||
TraceLoggingWrite(g_MsixTraceLoggingProvider,
|
||||
"Failed to process request",
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
|
||||
TraceLoggingValue(hrProcessRequest, "HR"));
|
||||
return 1;
|
||||
if (cli.IsQuietMode())
|
||||
{
|
||||
auto res = packageManager->AddPackage(cli.GetPackageFilePathToInstall(), DeploymentOptions::None);
|
||||
if (FAILED(res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
auto ui = new UI(packageManager, cli.GetPackageFilePathToInstall(), UIType::InstallUIAdd);
|
||||
ui->ShowUI();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OperationType::Remove:
|
||||
{
|
||||
AutoPtr<Win7MsixInstallerLib::IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(Win7MsixInstallerLib_CreatePackageManager(&packageManager));
|
||||
|
||||
auto packageFullName = cli.GetPackageFullName();
|
||||
auto res = packageManager->RemovePackage(packageFullName);
|
||||
if (FAILED(res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OperationType::FindPackage:
|
||||
{
|
||||
AutoPtr<Win7MsixInstallerLib::IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(Win7MsixInstallerLib_CreatePackageManager(&packageManager));
|
||||
|
||||
shared_ptr<Win7MsixInstallerLib::IInstalledPackage> packageInfo = packageManager->FindPackage(cli.GetPackageFullName());
|
||||
if (packageInfo == NULL)
|
||||
{
|
||||
std::wcout << std::endl;
|
||||
std::wcout << L"No packages found" << std::endl;
|
||||
std::wcout << std::endl;
|
||||
}
|
||||
else {
|
||||
std::wcout << std::endl;
|
||||
std::wcout << L"PackageFullName: " << packageInfo->GetPackageFullName().c_str() << std::endl;
|
||||
std::wcout << L"DisplayName: " << packageInfo->GetDisplayName().c_str() << std::endl;
|
||||
|
||||
std::wcout << L"DirectoryPath: " << packageInfo->GetInstalledLocation().c_str() << std::endl;
|
||||
std::wcout << std::endl;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
case OperationType::FindAllPackages:
|
||||
{
|
||||
AutoPtr<Win7MsixInstallerLib::IPackageManager> packageManager;
|
||||
RETURN_IF_FAILED(Win7MsixInstallerLib_CreatePackageManager(&packageManager));
|
||||
|
||||
auto packages = packageManager->FindPackages();
|
||||
|
||||
unsigned int numPackages = 0;
|
||||
for (auto& package : *packages)
|
||||
{
|
||||
std::wcout << package->GetPackageFullName() << std::endl;
|
||||
numPackages++;
|
||||
}
|
||||
|
||||
std::cout << numPackages << " Packages found" << std::endl;
|
||||
return S_OK;
|
||||
}
|
||||
default:
|
||||
return E_NOT_SET;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -69,10 +120,9 @@ int main(int argc, char * argv[])
|
|||
cli.DisplayHelp();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Stop TraceLogging and unregister the provider
|
||||
TraceLoggingUnregister(g_MsixTraceLoggingProvider);
|
||||
TraceLoggingUnregister(g_MsixUITraceLoggingProvider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,16 +90,16 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\Win7MsixInstallerLib\inc;..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>..\Debug;..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
|
@ -113,20 +113,24 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\Win7MsixInstallerLib\inc;..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>..\x64\Debug;..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>
|
||||
</Command>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -138,7 +142,7 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\Win7MsixInstallerLib\inc;..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
@ -146,10 +150,10 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>..\Release;..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
|
@ -165,7 +169,7 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\Win7MsixInstallerLib\inc;..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
@ -173,10 +177,10 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>..\x64\Release;..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
|
@ -186,57 +190,18 @@
|
|||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AddRemovePrograms.hpp" />
|
||||
<ClInclude Include="ComInterface.hpp" />
|
||||
<ClInclude Include="ComServer.hpp" />
|
||||
<ClInclude Include="Constants.hpp" />
|
||||
<ClInclude Include="ErrorHandler.hpp" />
|
||||
<ClInclude Include="MsixResponse.hpp" />
|
||||
<ClInclude Include="Extractor.hpp" />
|
||||
<ClInclude Include="FileTypeAssociation.hpp" />
|
||||
<ClInclude Include="FootprintFiles.hpp" />
|
||||
<ClInclude Include="GeneralUtil.hpp" />
|
||||
<ClInclude Include="FilePaths.hpp" />
|
||||
<ClInclude Include="Util.hpp" />
|
||||
<ClInclude Include="CommandLineInterface.hpp" />
|
||||
<ClInclude Include="InstallComplete.hpp" />
|
||||
<ClInclude Include="PopulatePackageInfo.hpp" />
|
||||
<ClInclude Include="PackageInfo.hpp" />
|
||||
<ClInclude Include="IPackageHandler.hpp" />
|
||||
<ClInclude Include="MsixRequest.hpp" />
|
||||
<ClInclude Include="InstallUI.hpp" />
|
||||
<ClInclude Include="..\..\..\.vs\src\msix\AppxPackaging.hpp" />
|
||||
<ClInclude Include="..\..\..\.vs\src\msix\MSIXWindows.hpp" />
|
||||
<ClInclude Include="ProcessPotentialUpdate.hpp" />
|
||||
<ClInclude Include="Protocol.hpp" />
|
||||
<ClInclude Include="RegistryDevirtualizer.hpp" />
|
||||
<ClInclude Include="RegistryKey.hpp" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="StartMenuLink.hpp" />
|
||||
<ClInclude Include="ValidateTargetDeviceFamily.hpp" />
|
||||
<ClInclude Include="Win7MSIXInstallerLogger.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ComInterface.cpp" />
|
||||
<ClCompile Include="ComServer.cpp" />
|
||||
<ClCompile Include="ErrorHandler.cpp" />
|
||||
<ClCompile Include="Extractor.cpp" />
|
||||
<ClCompile Include="FilePaths.cpp" />
|
||||
<ClCompile Include="FileTypeAssociation.cpp" />
|
||||
<ClCompile Include="GeneralUtil.cpp" />
|
||||
<ClCompile Include="InstallComplete.cpp" />
|
||||
<ClCompile Include="Util.cpp" />
|
||||
<ClCompile Include="InstallUI.cpp" />
|
||||
<ClCompile Include="MsixResponse.cpp" />
|
||||
<ClCompile Include="PackageInfo.cpp" />
|
||||
<ClCompile Include="ProcessPotentialUpdate.cpp" />
|
||||
<ClCompile Include="Protocol.cpp" />
|
||||
<ClCompile Include="RegistryDevirtualizer.cpp" />
|
||||
<ClCompile Include="RegistryKey.cpp" />
|
||||
<ClCompile Include="CommandLineInterface.cpp" />
|
||||
<ClCompile Include="MsixRequest.cpp" />
|
||||
<ClCompile Include="PopulatePackageInfo.cpp" />
|
||||
<ClCompile Include="AddRemovePrograms.cpp" />
|
||||
<ClCompile Include="StartMenuLink.cpp" />
|
||||
<ClCompile Include="ValidateTargetDeviceFamily.cpp" />
|
||||
<ClCompile Include="Win7MSIXInstaller.cpp" />
|
||||
<ClCompile Include="Win7MSIXInstallerLogger.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Win7MSIXInstaller.rc" />
|
||||
|
|
|
@ -18,64 +18,13 @@
|
|||
<ClInclude Include="CommandLineInterface.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MsixRequest.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IPackageHandler.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PackageInfo.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PopulatePackageInfo.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StartMenuLink.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AddRemovePrograms.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileTypeAssociation.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Protocol.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RegistryDevirtualizer.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RegistryKey.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Extractor.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FilePaths.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FootprintFiles.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GeneralUtil.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InstallUI.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Constants.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\.vs\src\msix\AppxPackaging.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\.vs\src\msix\MSIXWindows.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InstallComplete.hpp">
|
||||
<ClInclude Include="Win7MSIXInstallerLogger.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ComInterface.hpp">
|
||||
|
@ -84,13 +33,7 @@
|
|||
<ClInclude Include="ComServer.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MsixResponse.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ErrorHandler.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ProcessPotentialUpdate.hpp">
|
||||
<ClInclude Include="Util.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ValidateTargetDeviceFamily.hpp">
|
||||
|
@ -98,52 +41,16 @@
|
|||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Win7MSIXInstaller.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneralUtil.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Extractor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FilePaths.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="InstallUI.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MsixRequest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CommandLineInterface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PopulatePackageInfo.cpp">
|
||||
<ClCompile Include="Win7MSIXInstallerLogger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StartMenuLink.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AddRemovePrograms.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileTypeAssociation.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Protocol.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RegistryDevirtualizer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RegistryKey.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PackageInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="InstallComplete.cpp">
|
||||
<ClCompile Include="Win7MSIXInstaller.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ComInterface.cpp">
|
||||
|
@ -152,13 +59,7 @@
|
|||
<ClCompile Include="ComServer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MsixResponse.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ErrorHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ProcessPotentialUpdate.cpp">
|
||||
<ClCompile Include="Util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ValidateTargetDeviceFamily.cpp">
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#include "Win7MSIXInstallerLogger.hpp"
|
||||
// Define the GUID to use in TraceLoggingProviderRegister
|
||||
// {035426d5-d599-48e0-868d-c59f15901637}
|
||||
// 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 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));
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <TraceLoggingProvider.h>
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_MsixUITraceLoggingProvider);
|
||||
|
||||
|
||||
// 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_MsixUITraceLoggingProvider, \
|
||||
"RETURN_IF_FAILED", \
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_ERROR), \
|
||||
TraceLoggingValue(#a, "Code"), \
|
||||
TraceLoggingHResult(__hr, "HR"), \
|
||||
TraceLoggingUInt32(__LINE__, "Line"), \
|
||||
TraceLoggingValue(__FILENAME__, "Filename")); \
|
||||
return __hr; \
|
||||
} \
|
||||
}
|
|
@ -1,24 +1,30 @@
|
|||
#include "GeneralUtil.hpp"
|
||||
#include <string>
|
||||
#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 ConvertVersionToString(UINT64 version)
|
||||
#include "GeneralUtil.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)
|
||||
{
|
||||
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"."
|
||||
|
@ -26,32 +32,16 @@ std::wstring ConvertVersionToString(UINT64 version)
|
|||
+ std::to_wstring((version) & 0xFFFF);
|
||||
}
|
||||
|
||||
std::wstring GetStringResource(UINT resourceId)
|
||||
{
|
||||
HMODULE instance = GetModuleHandle(nullptr);
|
||||
|
||||
WCHAR buffer[MAX_PATH] = L"";
|
||||
int loadStringRet = LoadStringW(instance, resourceId, buffer, ARRAYSIZE(buffer));
|
||||
if (loadStringRet <= 0)
|
||||
{
|
||||
return std::wstring(L"Failed to load string resource");
|
||||
}
|
||||
|
||||
std::wstring stringResource(buffer);
|
||||
|
||||
return stringResource;
|
||||
}
|
||||
|
||||
std::wstring GetFamilyNameFromFullName(const std::wstring& fullName)
|
||||
std::wstring Win7MsixInstallerLib_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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -62,13 +52,13 @@ HRESULT GetAttributeValueFromElement(IMsixElement * element, const std::wstring
|
|||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
std::wstring GuidFromManifestId(std::wstring id)
|
||||
{
|
||||
return L"{" + id + L"}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::wstring GuidFromManifestId(std::wstring id)
|
||||
{
|
||||
return L"{" + id + L"}";
|
||||
}
|
||||
|
||||
HRESULT FileExists(std::wstring file, _Out_ bool &exists)
|
||||
{
|
||||
DWORD fileAttributes = GetFileAttributesW(file.c_str());
|
|
@ -0,0 +1,242 @@
|
|||
#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
|
||||
{
|
||||
//
|
||||
// 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) { Win7MsixInstallerLib_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);
|
|
@ -0,0 +1,163 @@
|
|||
#include "PackageManager.hpp"
|
||||
#include "MsixRequest.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "PopulatePackageInfo.hpp"
|
||||
#include <experimental/filesystem>
|
||||
#include <thread>
|
||||
|
||||
using namespace std;
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
PackageManager::PackageManager()
|
||||
{
|
||||
}
|
||||
|
||||
shared_ptr<IMsixResponse> PackageManager::AddPackageAsync(const wstring & packageFilePath, DeploymentOptions options, function<void(const IMsixResponse&)> callback)
|
||||
{
|
||||
MsixRequest * impl;
|
||||
auto res = (MsixRequest::Make(OperationType::Add, packageFilePath, L"", MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &impl));
|
||||
if (FAILED(res))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
impl->GetMsixResponse()->SetCallback(callback);
|
||||
}
|
||||
|
||||
auto t = thread([&impl]() {
|
||||
impl->ProcessRequest();
|
||||
delete impl;
|
||||
impl = nullptr;
|
||||
});
|
||||
t.detach();
|
||||
return impl->GetMsixResponse();
|
||||
}
|
||||
|
||||
HRESULT PackageManager::AddPackage(const wstring & packageFilePath, DeploymentOptions options)
|
||||
{
|
||||
AutoPtr<MsixRequest> impl;
|
||||
auto res = (MsixRequest::Make(OperationType::Add, packageFilePath, L"", MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &impl));
|
||||
if (FAILED(res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return impl->ProcessRequest();
|
||||
}
|
||||
|
||||
shared_ptr<IMsixResponse> PackageManager::RemovePackageAsync(const wstring & packageFullName, function<void(const IMsixResponse&)> callback)
|
||||
{
|
||||
MsixRequest* impl;
|
||||
auto res = (MsixRequest::Make(OperationType::Remove, L"", packageFullName, MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &impl));
|
||||
if (FAILED(res))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
impl->GetMsixResponse()->SetCallback(callback);
|
||||
}
|
||||
|
||||
thread t([&impl]() {
|
||||
impl->ProcessRequest();
|
||||
impl = nullptr;
|
||||
});
|
||||
t.detach();
|
||||
return impl->GetMsixResponse();
|
||||
}
|
||||
|
||||
HRESULT PackageManager::RemovePackage(const wstring & packageFullName)
|
||||
{
|
||||
AutoPtr<MsixRequest> impl;
|
||||
auto res = (MsixRequest::Make(OperationType::Remove, L"", packageFullName, MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &impl));
|
||||
if (FAILED(res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return impl->ProcessRequest();
|
||||
}
|
||||
shared_ptr<IInstalledPackage> PackageManager::GetPackageInfo(const wstring & msix7Directory, const wstring & directoryPath)
|
||||
{
|
||||
std::shared_ptr<InstalledPackage> packageInfo;
|
||||
auto res = PopulatePackageInfo::GetPackageInfoFromManifest(directoryPath.c_str(), MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &packageInfo);
|
||||
if (FAILED(res))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return std::dynamic_pointer_cast<IInstalledPackage>(packageInfo);
|
||||
}
|
||||
|
||||
shared_ptr<IInstalledPackage> PackageManager::FindPackage(const wstring & packageFullName)
|
||||
{
|
||||
auto filemapping = FilePathMappings::GetInstance();
|
||||
auto res = filemapping.GetInitializationResult();
|
||||
if (FAILED(res))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
wstring msix7Directory = filemapping.GetMsix7Directory();
|
||||
wstring packageDirectoryPath = msix7Directory + packageFullName;
|
||||
auto package = GetPackageInfo(msix7Directory, packageDirectoryPath);
|
||||
return package;
|
||||
}
|
||||
|
||||
shared_ptr<IInstalledPackage> PackageManager::FindPackageByFamilyName(const wstring & packageFamilyName)
|
||||
{
|
||||
auto filemapping = FilePathMappings::GetInstance();
|
||||
auto res = filemapping.GetInitializationResult();
|
||||
if (FAILED(res))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
auto msix7Directory = filemapping.GetMsix7Directory();
|
||||
for (auto& p : experimental::filesystem::directory_iterator(msix7Directory))
|
||||
{
|
||||
|
||||
auto installedAppFamilyName = Win7MsixInstallerLib_GetFamilyNameFromFullName(p.path().filename());
|
||||
if (Win7MsixInstallerLib_CaseInsensitiveEquals(installedAppFamilyName, packageFamilyName))
|
||||
{
|
||||
return GetPackageInfo(msix7Directory, p.path());
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unique_ptr<vector<shared_ptr<IInstalledPackage>>> PackageManager::FindPackages()
|
||||
{
|
||||
auto packages = std::make_unique<std::vector<shared_ptr<IInstalledPackage>>>();
|
||||
auto filemapping = FilePathMappings::GetInstance();
|
||||
auto res = filemapping.GetInitializationResult();
|
||||
if (FAILED(res))
|
||||
{
|
||||
return packages;
|
||||
}
|
||||
auto msix7Directory = filemapping.GetMsix7Directory();
|
||||
for (auto& p : experimental::filesystem::directory_iterator(msix7Directory))
|
||||
{
|
||||
auto packageInfo = GetPackageInfo(msix7Directory, p.path());
|
||||
if (packageInfo != nullptr)
|
||||
{
|
||||
packages->push_back(packageInfo);
|
||||
}
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
shared_ptr<IPackage> PackageManager::GetMsixPackageInfo(const wstring & msixFullPath)
|
||||
{
|
||||
auto filemapping = FilePathMappings::GetInstance();
|
||||
auto res = filemapping.GetInitializationResult();
|
||||
if (FAILED(res))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
shared_ptr<Package> packageInfo;
|
||||
res = PopulatePackageInfo::GetPackageInfoFromPackage(msixFullPath.c_str(), MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL, &packageInfo);
|
||||
if (FAILED(res))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return dynamic_pointer_cast<IPackage>(packageInfo);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include "inc/IPackageManager.hpp"
|
||||
#include "inc/IPackage.hpp"
|
||||
|
||||
namespace Win7MsixInstallerLib {
|
||||
|
||||
class PackageManager :
|
||||
public IPackageManager
|
||||
{
|
||||
public:
|
||||
PackageManager();
|
||||
std::shared_ptr<IMsixResponse> AddPackageAsync(const std::wstring & packageFilePath, DeploymentOptions options, std::function<void(const IMsixResponse&)> callback = nullptr) override;
|
||||
HRESULT AddPackage(const std::wstring & packageFilePath, DeploymentOptions options) override;
|
||||
std::shared_ptr<IMsixResponse> RemovePackageAsync(const std::wstring & packageFullName, std::function<void(const IMsixResponse&)> callback = nullptr) override;
|
||||
HRESULT RemovePackage(const std::wstring & packageFullName) override;
|
||||
std::shared_ptr<IInstalledPackage> FindPackage(const std::wstring & packageFullName) override;
|
||||
std::shared_ptr<IInstalledPackage> FindPackageByFamilyName(const std::wstring & packageFamilyName) override;
|
||||
std::unique_ptr<std::vector<std::shared_ptr<IInstalledPackage>>> FindPackages() override;
|
||||
std::shared_ptr<IPackage> GetMsixPackageInfo(const std::wstring & msixFullPath) override;
|
||||
private:
|
||||
std::shared_ptr<IInstalledPackage> GetPackageInfo(const std::wstring & msix7Directory, const std::wstring & directoryPath);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include "Win7MSIXInstallerActions.hpp"
|
||||
#include "PackageManager.hpp"
|
||||
|
||||
using namespace Win7MsixInstallerLib;
|
||||
|
||||
HRESULT Win7MsixInstallerLib_CreatePackageManager(Win7MsixInstallerLib::IPackageManager** packageManager)
|
||||
{
|
||||
*packageManager = new PackageManager();
|
||||
return S_OK;
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{46BE19BD-72E0-4452-9919-33A1F8A5F064}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Win7MSIXInstaller</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Win7MSIXInstallerLib</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>No</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>No</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>No</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>No</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>Win7MsixInstallerLib_EXPORTS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>.;..\Win7MSIXInstaller;inc;..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>Version.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "$(ProjectDir)MSIXPackaging\x86\Debug\msix.*" "$(OutDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>Win7MsixInstallerLib_EXPORTS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>.;..\Win7MSIXInstaller;inc;..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>Version.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>Win7MsixInstallerLib_EXPORTS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>.;..\Win7MSIXInstaller;inc;..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>Version.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "$(ProjectDir)MSIXPackaging\x86\msix.dll" "$(OutDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>Win7MsixInstallerLib_EXPORTS;WIN32;NDEBUG;_CONSOLE;WIN7MSIXINSTALLER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>.;..\Win7MSIXInstaller;inc;..\..\..\.vs\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\..\..\.vs\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>comctl32.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>Version.lib;msix.lib;msi.lib;comctl32.lib;gdiplus.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D "..\..\..\.vs\bin\msix.dll" "$(OutDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\Win7MSIXInstaller\AddRemovePrograms.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\ComInterface.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\ComServer.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\Constants.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\ErrorHandler.hpp" />
|
||||
<ClInclude Include="inc\IMsixResponse.hpp" />
|
||||
<ClInclude Include="inc\DeploymentOptions.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\Extractor.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\FileTypeAssociation.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\FootprintFiles.hpp" />
|
||||
<ClInclude Include="inc\IPackageManager.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\InstallComplete.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\MsixRequest.hpp" />
|
||||
<ClInclude Include="GeneralUtil.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\FilePaths.hpp" />
|
||||
<ClInclude Include="inc\IPackage.hpp" />
|
||||
<ClInclude Include="inc\Win7MSIXInstallerActions.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\IPackageHandler.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\MsixResponse.hpp" />
|
||||
<ClInclude Include="PackageManager.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\Package.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\PopulatePackageInfo.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\ProcessPotentialUpdate.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\Protocol.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\RegistryDevirtualizer.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\RegistryKey.hpp" />
|
||||
<ClInclude Include="..\Win7MSIXInstaller\StartMenuLink.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\Win7MSIXInstaller\ComInterface.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\ComServer.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\ErrorHandler.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\Extractor.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\FilePaths.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\FileTypeAssociation.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\InstallComplete.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\MsixRequest.cpp" />
|
||||
<ClCompile Include="GeneralUtil.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\MsixResponse.cpp" />
|
||||
<ClCompile Include="PackageManager.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\Package.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\PopulatePackageInfo.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\ProcessPotentialUpdate.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\Protocol.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\RegistryDevirtualizer.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\RegistryKey.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\AddRemovePrograms.cpp" />
|
||||
<ClCompile Include="..\Win7MSIXInstaller\StartMenuLink.cpp" />
|
||||
<ClCompile Include="Win7MSIXInstallerActions.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
enum DeploymentOptions
|
||||
{
|
||||
None = 0,
|
||||
//ForceUpdateFromAnyVersion = 262144
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
#include <functional>
|
||||
#include <windows.h>
|
||||
|
||||
namespace Win7MsixInstallerLib {
|
||||
|
||||
enum InstallationStep {
|
||||
InstallationStepUnknown,
|
||||
InstallationStepStarted,
|
||||
InstallationStepGetPackageInformation,
|
||||
InstallationStepExtraction,
|
||||
InstallationStepCompleted,
|
||||
InstallationStepError,
|
||||
//can be extend for future scenarios.
|
||||
};
|
||||
|
||||
class IMsixResponse
|
||||
{
|
||||
public:
|
||||
virtual void SetCallback(std::function<void(const IMsixResponse &)> callback) = 0;
|
||||
virtual inline float GetPercentage() const = 0;
|
||||
virtual inline InstallationStep GetStatus() const = 0;
|
||||
virtual inline HRESULT GetHResultTextCode() const = 0;
|
||||
virtual inline std::wstring GetTextStatus() const = 0;
|
||||
virtual inline void CancelRequest() = 0;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
#include <Windows.h>
|
||||
namespace Win7MsixInstallerLib {
|
||||
|
||||
class IPackage {
|
||||
public:
|
||||
virtual unsigned long long GetVersionNumber() = 0;
|
||||
virtual std::wstring GetVersion() = 0;
|
||||
virtual std::wstring GetPublisherDisplayName() = 0;
|
||||
virtual std::wstring GetPackageFullName() = 0;
|
||||
virtual std::wstring GetPackageFamilyName() = 0;
|
||||
virtual std::wstring GetDisplayName() = 0;
|
||||
virtual std::wstring GetId() = 0;
|
||||
virtual std::unique_ptr<IStream> GetLogo() = 0;
|
||||
virtual ~IPackage() {}
|
||||
|
||||
protected:
|
||||
IPackage() {}
|
||||
};
|
||||
|
||||
class IInstalledPackage : public IPackage
|
||||
{
|
||||
public:
|
||||
virtual std::wstring GetFullExecutableFilePath() = 0;
|
||||
virtual std::wstring GetInstalledLocation() = 0;
|
||||
virtual ~IInstalledPackage() {}
|
||||
protected:
|
||||
IInstalledPackage() {}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include "IMsixResponse.hpp"
|
||||
#include "IPackage.hpp"
|
||||
#include "DeploymentOptions.hpp"
|
||||
|
||||
|
||||
namespace Win7MsixInstallerLib {
|
||||
class IPackageManager
|
||||
{
|
||||
public:
|
||||
virtual std::shared_ptr<IMsixResponse> AddPackageAsync(const std::wstring & packageFilePath, DeploymentOptions options, std::function<void(const IMsixResponse&)> callback = nullptr) = 0;
|
||||
virtual HRESULT AddPackage(const std::wstring & packageFilePath, DeploymentOptions options) = 0;
|
||||
virtual std::shared_ptr<IMsixResponse> RemovePackageAsync(const std::wstring & packageFullName, std::function<void(const IMsixResponse&)> callback = nullptr) = 0;
|
||||
virtual HRESULT RemovePackage(const std::wstring & packageFullName) = 0;
|
||||
virtual std::shared_ptr<IInstalledPackage> FindPackage(const std::wstring & packageFamilyName) = 0;
|
||||
virtual std::shared_ptr<IInstalledPackage> FindPackageByFamilyName(const std::wstring & packageFamilyName) = 0;
|
||||
virtual std::unique_ptr<std::vector<std::shared_ptr<IInstalledPackage>>> FindPackages() = 0;
|
||||
virtual std::shared_ptr<IPackage> GetMsixPackageInfo(const std::wstring & msixFullPath) = 0;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "IPackageManager.hpp"
|
||||
|
||||
extern "C" HRESULT Win7MsixInstallerLib_CreatePackageManager(Win7MsixInstallerLib::IPackageManager** packageManager);
|
|
@ -426,7 +426,7 @@ namespace MSIX
|
|||
return IsAuthenticodeTrustedChain(certChainContext.get());
|
||||
}
|
||||
|
||||
static bool GetPublisherName(/*in*/byte* signatureBuffer, /*in*/ ULONG cbSignatureBuffer, /*inout*/ std::string& publisher)
|
||||
static bool GetPublisherDisplayName(/*in*/byte* signatureBuffer, /*in*/ ULONG cbSignatureBuffer, /*inout*/ std::string& publisher)
|
||||
{
|
||||
unique_cert_context certificateContext(GetCertContext(signatureBuffer, cbSignatureBuffer, true));
|
||||
if (certificateContext.get() == NULL)
|
||||
|
@ -606,7 +606,7 @@ namespace MSIX
|
|||
"Unknown signature origin");
|
||||
|
||||
ThrowErrorIfNot(Error::SignatureInvalid,
|
||||
GetPublisherName(p7s, p7sSize, publisher) == true,
|
||||
GetPublisherDisplayName(p7s, p7sSize, publisher) == true,
|
||||
"Could not retrieve publisher name");
|
||||
|
||||
return true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче