mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-29 04:09:35 +03:00
CPack/WiX: Add support for perUser install scope
This allows one to create installers that install to `AppDataLocal` and do not require admin privileges to execute. Fixes: #24939
This commit is contained in:
+40
-12
@@ -408,8 +408,9 @@ Windows using WiX.
|
||||
In 32-bit builds the token will expand empty while in 64-bit builds
|
||||
it will expand to ``64``.
|
||||
|
||||
When unset generated installers will default installing to
|
||||
``ProgramFiles<64>Folder``.
|
||||
When unset generated installers will install to
|
||||
``LocalAppDataFolder`` if :variable:`CPACK_WIX_INSTALL_SCOPE` is ``perUser``,
|
||||
and to ``ProgramFiles<64>Folder`` otherwise.
|
||||
|
||||
.. variable:: CPACK_WIX_ROOT
|
||||
|
||||
@@ -451,7 +452,7 @@ Windows using WiX.
|
||||
.. versionadded:: 3.29
|
||||
|
||||
This variable can be optionally set to specify the ``InstallScope``
|
||||
of the installer:
|
||||
of the installer (see https://docs.firegiant.com/wix3/xsd/wix/package/):
|
||||
|
||||
``perMachine``
|
||||
Create an installer that installs for all users and requires
|
||||
@@ -461,7 +462,20 @@ Windows using WiX.
|
||||
This is the default. See policy :policy:`CMP0172`.
|
||||
|
||||
``perUser``
|
||||
Not yet supported. This is reserved for future use.
|
||||
Create an installer that installs only for the current user
|
||||
and does not require administrative privileges. Start menu entries created
|
||||
by the installer are visible only to the current user.
|
||||
|
||||
To enable per-user installation, the installer has to generate some
|
||||
additional registry entries to serve as "key paths" for installed
|
||||
components (see https://learn.microsoft.com/en-us/windows/win32/msi/ice38).
|
||||
These registry entries are created under ``HKEY_CURRENT_USER``, using the
|
||||
path specified by the :variable:`CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH`
|
||||
variable.
|
||||
|
||||
.. versionchanged:: 4.3
|
||||
|
||||
Before CMake 4.3, this value was reserved for future use and not supported.
|
||||
|
||||
``NONE``
|
||||
Create an installer without any ``InstallScope`` attribute.
|
||||
@@ -477,16 +491,30 @@ Windows using WiX.
|
||||
but the start menu entry and uninstaller registration are created only
|
||||
for the current user.
|
||||
|
||||
.. warning::
|
||||
.. warning::
|
||||
Installations performed by installers created with different
|
||||
``InstallScope`` values cannot be cleanly updated or replaced by each other.
|
||||
For example, to transition a project's installers from ``NONE`` to
|
||||
``perMachine``, or from ``perMachine`` to ``perUser``, the latter installer
|
||||
should be distributed with instructions to first manually uninstall
|
||||
any older version.
|
||||
|
||||
An installation performed by an installer created without any
|
||||
``InstallScope`` cannot be cleanly updated or replaced by an
|
||||
installer with an ``InstallScope``. In order to transition
|
||||
a project's installers from ``NONE`` to ``perMachine``, the
|
||||
latter installer should be distributed with instructions to
|
||||
first manually uninstall any older version.
|
||||
.. variable:: CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH
|
||||
|
||||
See https://docs.firegiant.com/wix3/xsd/wix/package/
|
||||
.. versionadded:: 4.3
|
||||
|
||||
This variable determines the registry path under ``HKEY_CURRENT_USER``
|
||||
where the installer will create registry entries to serve as "key paths"
|
||||
for components if :variable:`CPACK_WIX_INSTALL_SCOPE` is set to ``perUser``.
|
||||
|
||||
Use forward slashes (``/``) as path separators to avoid issues with escapes;
|
||||
they will be converted to backslashes (``\``) by the WIX generator.
|
||||
|
||||
Default value is ``Software/<Vendor>/<PackageName>/Components``,
|
||||
where ``<Vendor>`` is taken from :variable:`CPACK_PACKAGE_VENDOR`,
|
||||
and ``<PackageName>`` is taken from :variable:`CPACK_PACKAGE_NAME`.
|
||||
|
||||
Example: ``Software/MyCompany/MyProduct/Components``
|
||||
|
||||
.. variable:: CPACK_WIX_CAB_PER_COMPONENT
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
cpack-wix-perUser
|
||||
-----------------
|
||||
|
||||
* The :cpack_gen:`CPack WIX Generator` now supports per-user installers
|
||||
by setting :variable:`CPACK_WIX_INSTALL_SCOPE` to ``perUser``.
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "cmWIXDirectoriesSourceWriter.h"
|
||||
#include "cmWIXFeaturesSourceWriter.h"
|
||||
#include "cmWIXFilesSourceWriter.h"
|
||||
#include "cmWIXInstallScope.h"
|
||||
#include "cmWIXRichTextFormatWriter.h"
|
||||
#include "cmWIXSourceWriter.h"
|
||||
|
||||
@@ -545,9 +546,20 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
|
||||
|
||||
this->WixSources.push_back(directoryDefinitionsFilename);
|
||||
|
||||
cmWIXInstallScope installScope = GetInstallScope();
|
||||
|
||||
std::string componentKeysRegistryPath =
|
||||
GetOption("CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH");
|
||||
if (componentKeysRegistryPath.empty()) {
|
||||
componentKeysRegistryPath =
|
||||
cmStrCat("Software\\", GetOption("CPACK_PACKAGE_VENDOR"), "\\",
|
||||
GetOption("CPACK_PACKAGE_NAME"), "\\Components");
|
||||
}
|
||||
cmSystemTools::ReplaceString(componentKeysRegistryPath, "/", "\\");
|
||||
|
||||
cmWIXDirectoriesSourceWriter directoryDefinitions(
|
||||
this->WixVersion, this->Logger, directoryDefinitionsFilename,
|
||||
this->ComponentGuidType);
|
||||
this->ComponentGuidType, installScope, componentKeysRegistryPath);
|
||||
InjectXmlNamespaces(directoryDefinitions);
|
||||
directoryDefinitions.BeginElement("Fragment");
|
||||
|
||||
@@ -565,15 +577,18 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
|
||||
auto installationPrefixDirectory =
|
||||
directoryDefinitions.BeginInstallationPrefixDirectory(GetRootFolderId(),
|
||||
installRoot);
|
||||
cm::optional<std::string> removeFolderComponentId =
|
||||
directoryDefinitions.EmitRemoveFolderComponentOnUserInstall(
|
||||
"INSTALL_ROOT");
|
||||
|
||||
std::string fileDefinitionsFilename =
|
||||
cmStrCat(this->CPackTopLevel, "/files.wxs");
|
||||
|
||||
this->WixSources.push_back(fileDefinitionsFilename);
|
||||
|
||||
cmWIXFilesSourceWriter fileDefinitions(this->WixVersion, this->Logger,
|
||||
fileDefinitionsFilename,
|
||||
this->ComponentGuidType);
|
||||
cmWIXFilesSourceWriter fileDefinitions(
|
||||
this->WixVersion, this->Logger, fileDefinitionsFilename,
|
||||
this->ComponentGuidType, installScope, componentKeysRegistryPath);
|
||||
InjectXmlNamespaces(fileDefinitions);
|
||||
|
||||
fileDefinitions.BeginElement("Fragment");
|
||||
@@ -622,6 +637,10 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
|
||||
*package, GetOption("CPACK_WIX_UPGRADE_GUID"));
|
||||
}
|
||||
|
||||
if (removeFolderComponentId.has_value()) {
|
||||
featureDefinitions.EmitComponentRef(*removeFolderComponentId);
|
||||
}
|
||||
|
||||
if (!CreateFeatureHierarchy(featureDefinitions)) {
|
||||
return false;
|
||||
}
|
||||
@@ -728,6 +747,8 @@ std::string cmCPackWIXGenerator::GetRootFolderId() const
|
||||
cmValue rootFolderId = GetOption("CPACK_WIX_ROOT_FOLDER_ID");
|
||||
if (rootFolderId) {
|
||||
result = *rootFolderId;
|
||||
} else if (GetInstallScope() == cmWIXInstallScope::PER_USER) {
|
||||
result = "LocalAppDataFolder";
|
||||
} else if (this->WixVersion >= 4) {
|
||||
result = "ProgramFiles6432Folder";
|
||||
} else {
|
||||
@@ -1083,6 +1104,13 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
|
||||
directoryDefinitions.AddAttribute("Name", fileName);
|
||||
this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);
|
||||
|
||||
cm::optional<std::string> removeFolderComponentId =
|
||||
directoryDefinitions.EmitRemoveFolderComponentOnUserInstall(
|
||||
subDirectoryId);
|
||||
if (removeFolderComponentId.has_value()) {
|
||||
featureDefinitions.EmitComponentRef(*removeFolderComponentId);
|
||||
}
|
||||
|
||||
AddDirectoryAndFileDefinitions(fullPath, subDirectoryId,
|
||||
directoryDefinitions, fileDefinitions,
|
||||
featureDefinitions, packageExecutables,
|
||||
@@ -1374,3 +1402,24 @@ void cmCPackWIXGenerator::InjectXmlNamespaces(cmWIXSourceWriter& sourceWriter)
|
||||
ns.second);
|
||||
}
|
||||
}
|
||||
|
||||
cmWIXInstallScope cmCPackWIXGenerator::GetInstallScope() const
|
||||
{
|
||||
cmValue value = this->GetOption("CPACK_WIX_INSTALL_SCOPE");
|
||||
|
||||
if (value == "perUser"_s) {
|
||||
return cmWIXInstallScope::PER_USER;
|
||||
}
|
||||
if (value == "perMachine"_s) {
|
||||
return cmWIXInstallScope::PER_MACHINE;
|
||||
}
|
||||
if (value == "NONE"_s) {
|
||||
return cmWIXInstallScope::NONE;
|
||||
}
|
||||
|
||||
cmCPackLogger(
|
||||
cmCPackLog::LOG_ERROR,
|
||||
"Invalid CPACK_WIX_INSTALL_SCOPE value, defaulting to perMachine: "
|
||||
<< (value ? *value : "") << std::endl);
|
||||
return cmWIXInstallScope::PER_MACHINE;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "cmCPackGenerator.h"
|
||||
#include "cmWIXInstallScope.h"
|
||||
#include "cmWIXPatch.h"
|
||||
#include "cmWIXShortcut.h"
|
||||
|
||||
@@ -159,6 +160,8 @@ private:
|
||||
|
||||
void InjectXmlNamespaces(cmWIXSourceWriter& sourceWriter);
|
||||
|
||||
cmWIXInstallScope GetInstallScope() const;
|
||||
|
||||
std::vector<std::string> WixSources;
|
||||
id_map_t PathToIdMap;
|
||||
ambiguity_map_t IdAmbiguityCounter;
|
||||
|
||||
@@ -6,9 +6,24 @@
|
||||
|
||||
cmWIXDirectoriesSourceWriter::cmWIXDirectoriesSourceWriter(
|
||||
unsigned long wixVersion, cmCPackLog* logger, std::string const& filename,
|
||||
GuidType componentGuidType)
|
||||
GuidType componentGuidType, cmWIXInstallScope installScope,
|
||||
std::string componentKeysRegistryPath)
|
||||
: cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType)
|
||||
, ComponentKeysRegistryPath(std::move(componentKeysRegistryPath))
|
||||
{
|
||||
switch (installScope) {
|
||||
case cmWIXInstallScope::PER_USER:
|
||||
this->PerUserInstall = true;
|
||||
break;
|
||||
case cmWIXInstallScope::PER_MACHINE:
|
||||
case cmWIXInstallScope::NONE:
|
||||
this->PerUserInstall = false;
|
||||
break;
|
||||
default:
|
||||
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||||
"Unhandled install scope value, this is a CPack Bug.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder(
|
||||
@@ -47,6 +62,43 @@ void cmWIXDirectoriesSourceWriter::EmitStartupFolder()
|
||||
EndElement_StandardDirectory();
|
||||
}
|
||||
|
||||
cm::optional<std::string>
|
||||
cmWIXDirectoriesSourceWriter::EmitRemoveFolderComponentOnUserInstall(
|
||||
std::string const& directoryId)
|
||||
{
|
||||
if (!this->PerUserInstall) {
|
||||
return {};
|
||||
}
|
||||
|
||||
BeginElement("Component");
|
||||
|
||||
std::string componentId = directoryId + "_RemoveFolderComponent";
|
||||
AddAttribute("Id", componentId);
|
||||
AddAttribute("Guid", CreateGuidFromComponentId(componentId));
|
||||
|
||||
BeginElement("RemoveFolder");
|
||||
AddAttribute("Id", directoryId + "_RemoveFolder");
|
||||
AddAttribute("Directory", directoryId);
|
||||
AddAttribute("On", "uninstall");
|
||||
EndElement("RemoveFolder");
|
||||
|
||||
// Need a keyPath for the component
|
||||
BeginElement("RegistryValue");
|
||||
|
||||
AddAttribute("Root", "HKCU");
|
||||
AddAttribute("Key", this->ComponentKeysRegistryPath);
|
||||
AddAttribute("Name", componentId);
|
||||
AddAttribute("Type", "string");
|
||||
AddAttribute("Value", "1");
|
||||
AddAttribute("KeyPath", "yes");
|
||||
|
||||
EndElement("RegistryValue");
|
||||
|
||||
EndElement("Component");
|
||||
|
||||
return componentId;
|
||||
}
|
||||
|
||||
cmWIXDirectoriesSourceWriter::InstallationPrefixDirectory
|
||||
cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
|
||||
std::string const& programFilesFolderId,
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmCPackGenerator.h"
|
||||
#include "cmWIXInstallScope.h"
|
||||
#include "cmWIXSourceWriter.h"
|
||||
|
||||
/** \class cmWIXDirectoriesSourceWriter
|
||||
@@ -15,7 +18,9 @@ class cmWIXDirectoriesSourceWriter : public cmWIXSourceWriter
|
||||
public:
|
||||
cmWIXDirectoriesSourceWriter(unsigned long wixVersion, cmCPackLog* logger,
|
||||
std::string const& filename,
|
||||
GuidType componentGuidType);
|
||||
GuidType componentGuidType,
|
||||
cmWIXInstallScope installScope,
|
||||
std::string componentKeysRegistryPath);
|
||||
|
||||
void EmitStartMenuFolder(std::string const& startMenuFolder);
|
||||
|
||||
@@ -23,6 +28,9 @@ public:
|
||||
|
||||
void EmitStartupFolder();
|
||||
|
||||
cm::optional<std::string> EmitRemoveFolderComponentOnUserInstall(
|
||||
std::string const& directoryId);
|
||||
|
||||
struct InstallationPrefixDirectory
|
||||
{
|
||||
bool HasStandardDirectory = false;
|
||||
@@ -35,4 +43,8 @@ public:
|
||||
|
||||
void EndInstallationPrefixDirectory(
|
||||
InstallationPrefixDirectory installationPrefixDirectory);
|
||||
|
||||
private:
|
||||
bool PerUserInstall = false;
|
||||
std::string ComponentKeysRegistryPath;
|
||||
};
|
||||
|
||||
@@ -19,12 +19,26 @@
|
||||
# include "cmsys/Encoding.hxx"
|
||||
#endif
|
||||
|
||||
cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(unsigned long wixVersion,
|
||||
cmCPackLog* logger,
|
||||
std::string const& filename,
|
||||
GuidType componentGuidType)
|
||||
cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(
|
||||
unsigned long wixVersion, cmCPackLog* logger, std::string const& filename,
|
||||
GuidType componentGuidType, cmWIXInstallScope installScope,
|
||||
std::string componentKeysRegistryPath)
|
||||
: cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType)
|
||||
, ComponentKeysRegistryPath(std::move(componentKeysRegistryPath))
|
||||
{
|
||||
switch (installScope) {
|
||||
case cmWIXInstallScope::PER_USER:
|
||||
this->PerUserInstall = true;
|
||||
break;
|
||||
case cmWIXInstallScope::PER_MACHINE:
|
||||
case cmWIXInstallScope::NONE:
|
||||
this->PerUserInstall = false;
|
||||
break;
|
||||
default:
|
||||
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||||
"Unhandled install scope value, this is a CPack Bug.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cmWIXFilesSourceWriter::EmitShortcut(std::string const& id,
|
||||
@@ -127,7 +141,11 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
|
||||
std::string componentId = std::string("CM_C") + id;
|
||||
std::string fileId = std::string("CM_F") + id;
|
||||
|
||||
std::string guid = CreateGuidFromComponentId(componentId);
|
||||
// Wix doesn't support automatic GUIDs for components which have both
|
||||
// registry entries and files.
|
||||
std::string guid = this->PerUserInstall
|
||||
? CreateCmakeGeneratedGuidFromComponentId(componentId)
|
||||
: CreateGuidFromComponentId(componentId);
|
||||
|
||||
BeginElement("DirectoryRef");
|
||||
AddAttribute("Id", directoryId);
|
||||
@@ -150,6 +168,22 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
|
||||
}
|
||||
|
||||
patch.ApplyFragment(componentId, *this);
|
||||
|
||||
if (this->PerUserInstall) {
|
||||
// For perUser installs, MSI requires using a registry entry as the key
|
||||
// path for components.
|
||||
BeginElement("RegistryValue");
|
||||
|
||||
AddAttribute("Root", "HKCU");
|
||||
AddAttribute("Key", this->ComponentKeysRegistryPath);
|
||||
AddAttribute("Name", fileId);
|
||||
AddAttribute("Type", "string");
|
||||
AddAttribute("Value", "1");
|
||||
AddAttribute("KeyPath", "yes");
|
||||
|
||||
EndElement("RegistryValue");
|
||||
}
|
||||
|
||||
BeginElement("File");
|
||||
AddAttribute("Id", fileId);
|
||||
|
||||
@@ -164,7 +198,9 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
|
||||
#endif
|
||||
AddAttribute("Source", sourcePath);
|
||||
|
||||
AddAttribute("KeyPath", "yes");
|
||||
if (!this->PerUserInstall) {
|
||||
AddAttribute("KeyPath", "yes");
|
||||
}
|
||||
|
||||
mode_t fileMode = 0;
|
||||
cmSystemTools::GetPermissions(filePath.c_str(), fileMode);
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "cmCPackGenerator.h"
|
||||
#include "cmWIXInstallScope.h"
|
||||
#include "cmWIXPatch.h"
|
||||
#include "cmWIXShortcut.h"
|
||||
#include "cmWIXSourceWriter.h"
|
||||
@@ -15,7 +18,9 @@ class cmWIXFilesSourceWriter : public cmWIXSourceWriter
|
||||
public:
|
||||
cmWIXFilesSourceWriter(unsigned long wixVersion, cmCPackLog* logger,
|
||||
std::string const& filename,
|
||||
GuidType componentGuidType);
|
||||
GuidType componentGuidType,
|
||||
cmWIXInstallScope installScope,
|
||||
std::string componentKeysRegistryPath);
|
||||
|
||||
void EmitShortcut(std::string const& id, cmWIXShortcut const& shortcut,
|
||||
std::string const& shortcutPrefix, size_t shortcutIndex);
|
||||
@@ -37,4 +42,8 @@ public:
|
||||
std::string const& filePath, cmWIXPatch& patch,
|
||||
cmInstalledFile const* installedFile,
|
||||
int diskId);
|
||||
|
||||
private:
|
||||
bool PerUserInstall = false;
|
||||
std::string ComponentKeysRegistryPath;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
enum class cmWIXInstallScope
|
||||
{
|
||||
NONE,
|
||||
PER_MACHINE,
|
||||
PER_USER
|
||||
};
|
||||
@@ -159,15 +159,21 @@ std::string cmWIXSourceWriter::CreateGuidFromComponentId(
|
||||
{
|
||||
std::string guid = "*";
|
||||
if (this->ComponentGuidType == CMAKE_GENERATED_GUID) {
|
||||
cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
|
||||
std::string md5 = hasher.HashString(componentId);
|
||||
cmUuid uuid;
|
||||
std::vector<unsigned char> ns;
|
||||
guid = uuid.FromMd5(ns, md5);
|
||||
guid = CreateCmakeGeneratedGuidFromComponentId(componentId);
|
||||
}
|
||||
return guid;
|
||||
}
|
||||
|
||||
std::string cmWIXSourceWriter::CreateCmakeGeneratedGuidFromComponentId(
|
||||
std::string const& componentId)
|
||||
{
|
||||
cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
|
||||
std::string md5 = hasher.HashString(componentId);
|
||||
cmUuid uuid;
|
||||
std::vector<unsigned char> ns;
|
||||
return uuid.FromMd5(ns, md5);
|
||||
}
|
||||
|
||||
void cmWIXSourceWriter::WriteXMLDeclaration()
|
||||
{
|
||||
File << R"(<?xml version="1.0" encoding="UTF-8"?>)" << std::endl;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#include "cmCPackLog.h"
|
||||
@@ -52,6 +54,12 @@ public:
|
||||
|
||||
std::string CreateGuidFromComponentId(std::string const& componentId);
|
||||
|
||||
// In most cases CreateGuidFromComponentId should be used instead, since it
|
||||
// takes ComponentGuidType into consideration. This function always generates
|
||||
// an explicit GUID.
|
||||
static std::string CreateCmakeGeneratedGuidFromComponentId(
|
||||
std::string const& componentId);
|
||||
|
||||
static std::string EscapeAttributeValue(std::string const& value);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
include(${RunCMake_SOURCE_DIR}/cpack-check-common.cmake)
|
||||
@@ -0,0 +1,40 @@
|
||||
-- MyLib-1\.0\.0-(win64|windows-arm64)\.msi
|
||||
Component: 'INSTALL_ROOT_RemoveFolderComponent' 'INSTALL_ROOT'
|
||||
Component: 'CM_DP_applications\.bin_RemoveFolderComponent' 'CM_DP_applications\.bin'
|
||||
Component: 'CM_DP_applications2\.bin_RemoveFolderComponent' 'CM_DP_applications2\.bin'
|
||||
Component: 'CM_DP_extras\.extras_RemoveFolderComponent' 'CM_DP_extras\.extras'
|
||||
Component: 'CM_DP_extras\.extras\.empty_RemoveFolderComponent' 'CM_DP_extras\.extras\.empty'
|
||||
Component: 'CM_DP_headers\.include_RemoveFolderComponent' 'CM_DP_headers\.include'
|
||||
Component: 'CM_DP_libraries\.lib_RemoveFolderComponent' 'CM_DP_libraries\.lib'
|
||||
Component: 'CM_CP_applications\.bin\.my_libapp\.exe' 'CM_DP_applications\.bin'
|
||||
Component: 'CM_SHORTCUT_applications' 'PROGRAM_MENU_FOLDER'
|
||||
Component: 'CM_SHORTCUT_DESKTOP_applications' 'DesktopFolder'
|
||||
Component: 'CM_CP_applications2\.bin\.my_other_app\.exe' 'CM_DP_applications2\.bin'
|
||||
Component: 'CM_SHORTCUT_applications2' 'PROGRAM_MENU_FOLDER'
|
||||
Component: 'CM_SHORTCUT_DESKTOP_applications2' 'DesktopFolder'
|
||||
Component: 'CM_C_EMPTY_CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras\.empty'
|
||||
Component: 'CM_CP_headers\.include\.file_with_spaces\.h' 'CM_DP_headers\.include'
|
||||
Component: 'CM_CP_headers\.include\.mylib\.h' 'CM_DP_headers\.include'
|
||||
Component: 'CM_CP_libraries\.lib\.mylib\.lib' 'CM_DP_libraries\.lib'
|
||||
Directory: 'INSTALL_ROOT' 'LocalAppDataFolder' '[^']*\|CPack Component Example'
|
||||
Directory: 'CM_DP_applications\.bin' 'INSTALL_ROOT' 'bin'
|
||||
Directory: 'CM_DP_applications2\.bin' 'INSTALL_ROOT' 'bin'
|
||||
Directory: 'CM_DP_extras\.extras' 'INSTALL_ROOT' 'extras'
|
||||
Directory: 'CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras' 'empty'
|
||||
Directory: 'CM_DP_headers\.include' 'INSTALL_ROOT' 'include'
|
||||
Directory: 'CM_DP_libraries\.lib' 'INSTALL_ROOT' 'lib'
|
||||
Directory: 'PROGRAM_MENU_FOLDER' 'ProgramMenuFolder' 'MyLib'
|
||||
Directory: 'DesktopFolder' 'TARGETDIR' 'Desktop'
|
||||
Directory: 'LocalAppDataFolder' 'TARGETDIR' '\.'
|
||||
Directory: 'TARGETDIR' '' 'SourceDir'
|
||||
Directory: 'ProgramMenuFolder' 'TARGETDIR' '\.'
|
||||
File: 'CM_FP_applications\.bin\.my_libapp\.exe' 'CM_CP_applications\.bin\.my_libapp\.exe' '[^']*\|my-libapp\.exe'
|
||||
File: 'CM_FP_applications2\.bin\.my_other_app\.exe' 'CM_CP_applications2\.bin\.my_other_app\.exe' '[^']*\|my-other-app\.exe'
|
||||
File: 'CM_FP_headers\.include\.file_with_spaces\.h' 'CM_CP_headers\.include\.file_with_spaces\.h' '[^']*\|file with spaces\.h'
|
||||
File: 'CM_FP_headers\.include\.mylib\.h' 'CM_CP_headers\.include\.mylib\.h' 'mylib\.h'
|
||||
File: 'CM_FP_libraries\.lib\.mylib\.lib' 'CM_CP_libraries\.lib\.mylib\.lib' 'mylib\.lib'
|
||||
Shortcut: 'CM_SP_applications\.bin\.my_libapp\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_applications'
|
||||
Shortcut: 'CM_DSP_applications\.bin\.my_libapp\.exe' 'DesktopFolder' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications'
|
||||
Shortcut: 'CM_SP_applications2\.bin\.my_other_app\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_applications2'
|
||||
Shortcut: 'CM_DSP_applications2\.bin\.my_other_app\.exe' 'DesktopFolder' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications2'
|
||||
--
|
||||
@@ -0,0 +1 @@
|
||||
include(${RunCMake_SOURCE_DIR}/cpack-check-common.cmake)
|
||||
@@ -0,0 +1,13 @@
|
||||
CPack: Create package using WIX
|
||||
CPack: Install projects
|
||||
CPack: - Install project: CPackWiXGenerator \[Release\]
|
||||
CPack: - Install component: applications
|
||||
CPack: - Install component: applications2
|
||||
CPack: - Install component: empty1
|
||||
CPack: - Install component: empty2
|
||||
CPack: - Install component: extras
|
||||
CPack: - Install component: headers
|
||||
CPack: - Install component: libraries
|
||||
CPack: Create package
|
||||
CPack: - package: [^
|
||||
]*/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-build/MyLib-1\.0\.0-(win64|windows-arm64)\.msi generated\.
|
||||
@@ -0,0 +1,40 @@
|
||||
-- MyLib-1\.0\.0-(win64|windows-arm64)\.msi
|
||||
Component: 'INSTALL_ROOT_RemoveFolderComponent' 'INSTALL_ROOT'
|
||||
Component: 'CM_DP_applications\.bin_RemoveFolderComponent' 'CM_DP_applications\.bin'
|
||||
Component: 'CM_CP_applications\.bin\.my_libapp\.exe' 'CM_DP_applications\.bin'
|
||||
Component: 'CM_SHORTCUT_applications' 'PROGRAM_MENU_FOLDER'
|
||||
Component: 'CM_SHORTCUT_DESKTOP_applications' 'DesktopFolder'
|
||||
Component: 'CM_DP_applications2\.bin_RemoveFolderComponent' 'CM_DP_applications2\.bin'
|
||||
Component: 'CM_CP_applications2\.bin\.my_other_app\.exe' 'CM_DP_applications2\.bin'
|
||||
Component: 'CM_SHORTCUT_applications2' 'PROGRAM_MENU_FOLDER'
|
||||
Component: 'CM_SHORTCUT_DESKTOP_applications2' 'DesktopFolder'
|
||||
Component: 'CM_DP_extras\.extras_RemoveFolderComponent' 'CM_DP_extras\.extras'
|
||||
Component: 'CM_DP_extras\.extras\.empty_RemoveFolderComponent' 'CM_DP_extras\.extras\.empty'
|
||||
Component: 'CM_C_EMPTY_CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras\.empty'
|
||||
Component: 'CM_DP_headers\.include_RemoveFolderComponent' 'CM_DP_headers\.include'
|
||||
Component: 'CM_CP_headers\.include\.file_with_spaces\.h' 'CM_DP_headers\.include'
|
||||
Component: 'CM_CP_headers\.include\.mylib\.h' 'CM_DP_headers\.include'
|
||||
Component: 'CM_DP_libraries\.lib_RemoveFolderComponent' 'CM_DP_libraries\.lib'
|
||||
Component: 'CM_CP_libraries\.lib\.mylib\.lib' 'CM_DP_libraries\.lib'
|
||||
Directory: 'INSTALL_ROOT' 'LocalAppDataFolder' '[^']*\|CPack Component Example'
|
||||
Directory: 'CM_DP_applications\.bin' 'INSTALL_ROOT' 'bin'
|
||||
Directory: 'CM_DP_applications2\.bin' 'INSTALL_ROOT' 'bin'
|
||||
Directory: 'CM_DP_extras\.extras' 'INSTALL_ROOT' 'extras'
|
||||
Directory: 'CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras' 'empty'
|
||||
Directory: 'CM_DP_headers\.include' 'INSTALL_ROOT' 'include'
|
||||
Directory: 'CM_DP_libraries\.lib' 'INSTALL_ROOT' 'lib'
|
||||
Directory: 'PROGRAM_MENU_FOLDER' 'ProgramMenuFolder' 'MyLib'
|
||||
Directory: 'DesktopFolder' 'TARGETDIR' 'Desktop'
|
||||
Directory: 'LocalAppDataFolder' 'TARGETDIR' 'LocalApp'
|
||||
Directory: 'ProgramMenuFolder' 'TARGETDIR' 'PMenu'
|
||||
Directory: 'TARGETDIR' '' 'SourceDir'
|
||||
File: 'CM_FP_applications\.bin\.my_libapp\.exe' 'CM_CP_applications\.bin\.my_libapp\.exe' '[^']*\|my-libapp\.exe'
|
||||
File: 'CM_FP_applications2\.bin\.my_other_app\.exe' 'CM_CP_applications2\.bin\.my_other_app\.exe' '[^']*\|my-other-app\.exe'
|
||||
File: 'CM_FP_headers\.include\.file_with_spaces\.h' 'CM_CP_headers\.include\.file_with_spaces\.h' '[^']*\|file with spaces\.h'
|
||||
File: 'CM_FP_headers\.include\.mylib\.h' 'CM_CP_headers\.include\.mylib\.h' 'mylib\.h'
|
||||
File: 'CM_FP_libraries\.lib\.mylib\.lib' 'CM_CP_libraries\.lib\.mylib\.lib' 'mylib\.lib'
|
||||
Shortcut: 'CM_SP_applications\.bin\.my_libapp\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_applications'
|
||||
Shortcut: 'CM_DSP_applications\.bin\.my_libapp\.exe' 'DesktopFolder' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications'
|
||||
Shortcut: 'CM_SP_applications2\.bin\.my_other_app\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_applications2'
|
||||
Shortcut: 'CM_DSP_applications2\.bin\.my_other_app\.exe' 'DesktopFolder' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications2'
|
||||
--
|
||||
@@ -11,14 +11,21 @@ function(run_cpack_wix v)
|
||||
run_cpack(${v}-AppWiX SAMPLE AppWiX BUILD)
|
||||
endfunction()
|
||||
|
||||
function(run_cpack_wix_peruser v)
|
||||
set(RunCMake_TEST_OPTIONS -DCPACK_WIX_VERSION=${v} -DCPACK_WIX_INSTALL_SCOPE=perUser)
|
||||
run_cpack(${v}-AppWiX-perUser SAMPLE AppWiX BUILD)
|
||||
endfunction()
|
||||
|
||||
if(CMake_TEST_CPACK_WIX3)
|
||||
set(ENV{PATH} "${CMake_TEST_CPACK_WIX3};${env_PATH}")
|
||||
run_cpack_wix(3)
|
||||
run_cpack_wix_peruser(3)
|
||||
endif()
|
||||
|
||||
if(CMake_TEST_CPACK_WIX4)
|
||||
set(ENV{PATH} "${CMake_TEST_CPACK_WIX4};${env_PATH}")
|
||||
set(ENV{WIX_EXTENSIONS} "${CMake_TEST_CPACK_WIX4}")
|
||||
run_cpack_wix(4)
|
||||
run_cpack_wix_peruser(4)
|
||||
unset(ENV{WIX_EXTENSIONS})
|
||||
endif()
|
||||
|
||||
Reference in New Issue
Block a user