parent
33eaf2e05c
commit
ed257e39d0
7
res/msi/.gitignore
vendored
7
res/msi/.gitignore
vendored
@ -2,3 +2,10 @@
|
||||
|
||||
**/bin
|
||||
**/obj
|
||||
|
||||
x64
|
||||
packages
|
||||
|
||||
CustomActions/x64
|
||||
CustomActions/*.user
|
||||
CustomActions/*.filters
|
||||
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup useLegacyV2RuntimeActivationPolicy="true">
|
||||
<!--
|
||||
Use supportedRuntime tags to explicitly specify the version(s) of the .NET Framework runtime that
|
||||
the custom action should run on. If no versions are specified, the chosen version of the runtime
|
||||
will be the "best" match to what WixToolset.Dtf.CustomAction.dll was built against.
|
||||
|
||||
WARNING: leaving the version unspecified is dangerous as it introduces a risk of compatibility
|
||||
problems with future versions of the .NET Framework runtime. It is highly recommended that you specify
|
||||
only the version(s) of the .NET Framework runtime that you have tested against.
|
||||
|
||||
For more information https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/startup/startup-element
|
||||
-->
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
</configuration>
|
@ -1,56 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using WixToolset.Dtf.WindowsInstaller;
|
||||
|
||||
namespace CustomActions
|
||||
{
|
||||
public class CustomActions
|
||||
{
|
||||
[CustomAction]
|
||||
public static ActionResult CustomActionHello(Session session)
|
||||
{
|
||||
try
|
||||
{
|
||||
session.Log("================= Example CustomAction Hello");
|
||||
return ActionResult.Success;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
session.Log("An error occurred: " + e.Message);
|
||||
return ActionResult.Failure;
|
||||
}
|
||||
}
|
||||
|
||||
[CustomAction]
|
||||
public static ActionResult RunCommandAsSystem(Session session)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessStartInfo psi = new ProcessStartInfo
|
||||
{
|
||||
|
||||
FileName = "cmd.exe",
|
||||
Arguments = "/c " + session["CMD"],
|
||||
UseShellExecute = false,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
Verb = "runas"
|
||||
};
|
||||
|
||||
using (Process process = Process.Start(psi))
|
||||
{
|
||||
process.WaitForExit();
|
||||
}
|
||||
|
||||
return ActionResult.Success;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
session.Log("An error occurred: " + e.Message);
|
||||
return ActionResult.Failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
63
res/msi/CustomActions/CustomActions.cpp
Normal file
63
res/msi/CustomActions/CustomActions.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
// CustomAction.cpp : Defines the entry point for the custom action.
|
||||
#include "pch.h"
|
||||
#include <shellapi.h>
|
||||
|
||||
UINT __stdcall CustomActionHello(
|
||||
__in MSIHANDLE hInstall
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
DWORD er = ERROR_SUCCESS;
|
||||
|
||||
hr = WcaInitialize(hInstall, "CustomActionHello");
|
||||
ExitOnFailure(hr, "Failed to initialize");
|
||||
|
||||
WcaLog(LOGMSG_STANDARD, "Initialized.");
|
||||
|
||||
// TODO: Add your custom action code here.
|
||||
WcaLog(LOGMSG_STANDARD, "================= Example CustomAction Hello");
|
||||
|
||||
LExit:
|
||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||
return WcaFinalize(er);
|
||||
}
|
||||
|
||||
UINT __stdcall RemoveInstallFolder(
|
||||
__in MSIHANDLE hInstall
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
DWORD er = ERROR_SUCCESS;
|
||||
|
||||
int nResult = 0;
|
||||
wchar_t szCustomActionData[256] = { 0 };
|
||||
DWORD cchCustomActionData = sizeof(szCustomActionData) / sizeof(szCustomActionData[0]);
|
||||
|
||||
hr = WcaInitialize(hInstall, "RemoveInstallFolder");
|
||||
ExitOnFailure(hr, "Failed to initialize");
|
||||
|
||||
MsiGetPropertyW(hInstall, L"InstallFolder", szCustomActionData, &cchCustomActionData);
|
||||
|
||||
WcaLog(LOGMSG_STANDARD, "================= Remove Install Folder: %ls", szCustomActionData);
|
||||
|
||||
SHFILEOPSTRUCTW fileOp;
|
||||
ZeroMemory(&fileOp, sizeof(SHFILEOPSTRUCT));
|
||||
|
||||
fileOp.wFunc = FO_DELETE;
|
||||
fileOp.pFrom = szCustomActionData;
|
||||
fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
|
||||
|
||||
nResult = SHFileOperationW(&fileOp);
|
||||
if (nResult == 0)
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "The directory \"%ls\" has been deleted.", szCustomActionData);
|
||||
}
|
||||
else
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "The directory \"%ls\" has not been deleted, error code: 0X%02X.", szCustomActionData, nResult);
|
||||
}
|
||||
|
||||
LExit:
|
||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||
return WcaFinalize(er);
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<Configurations>Release</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="CustomAction.config" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="WixToolset.Dtf.CustomAction" Version="4.0.5" />
|
||||
<PackageReference Include="WixToolset.Dtf.WindowsInstaller" Version="4.0.5" />
|
||||
</ItemGroup>
|
||||
</Project>
|
5
res/msi/CustomActions/CustomActions.def
Normal file
5
res/msi/CustomActions/CustomActions.def
Normal file
@ -0,0 +1,5 @@
|
||||
LIBRARY "CustomActions"
|
||||
|
||||
EXPORTS
|
||||
CustomActionHello
|
||||
RemoveInstallFolder
|
80
res/msi/CustomActions/CustomActions.vcxproj
Normal file
80
res/msi/CustomActions/CustomActions.vcxproj
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\WixToolset.WcaUtil.4.0.5\build\WixToolset.WcaUtil.props" Condition="Exists('..\packages\WixToolset.WcaUtil.4.0.5\build\WixToolset.WcaUtil.props')" />
|
||||
<Import Project="..\packages\WixToolset.DUtil.4.0.5\build\WixToolset.DUtil.props" Condition="Exists('..\packages\WixToolset.DUtil.4.0.5\build\WixToolset.DUtil.props')" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{87e7c13b-ae0e-4048-95cf-4523d510a3cd}</ProjectGuid>
|
||||
<RootNamespace>CustomActions</RootNamespace>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<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)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;EXAMPLECADLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>msi.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CustomActions.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CustomActions.def" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\WixToolset.DUtil.4.0.5\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\WixToolset.DUtil.4.0.5\build\WixToolset.DUtil.props'))" />
|
||||
<Error Condition="!Exists('..\packages\WixToolset.WcaUtil.4.0.5\build\WixToolset.WcaUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\WixToolset.WcaUtil.4.0.5\build\WixToolset.WcaUtil.props'))" />
|
||||
</Target>
|
||||
</Project>
|
26
res/msi/CustomActions/dllmain.cpp
Normal file
26
res/msi/CustomActions/dllmain.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||
#include "pch.h"
|
||||
|
||||
BOOL APIENTRY DllMain(
|
||||
__in HMODULE hModule,
|
||||
__in DWORD ulReasonForCall,
|
||||
__in LPVOID
|
||||
)
|
||||
{
|
||||
switch (ulReasonForCall)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
WcaGlobalInitialize(hModule);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
WcaGlobalFinalize();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
10
res/msi/CustomActions/framework.h
Normal file
10
res/msi/CustomActions/framework.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
#include <msiquery.h>
|
||||
|
||||
// WiX Header Files:
|
||||
#include <wcautil.h>
|
5
res/msi/CustomActions/packages.config
Normal file
5
res/msi/CustomActions/packages.config
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="WixToolset.DUtil" version="4.0.5" targetFramework="native" />
|
||||
<package id="WixToolset.WcaUtil" version="4.0.5" targetFramework="native" />
|
||||
</packages>
|
5
res/msi/CustomActions/pch.cpp
Normal file
5
res/msi/CustomActions/pch.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
// pch.cpp: source file corresponding to the pre-compiled header
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
13
res/msi/CustomActions/pch.h
Normal file
13
res/msi/CustomActions/pch.h
Normal file
@ -0,0 +1,13 @@
|
||||
// pch.h: This is a precompiled header file.
|
||||
// Files listed below are compiled only once, improving build performance for future builds.
|
||||
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
||||
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
||||
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// add headers that you want to pre-compile here
|
||||
#include "framework.h"
|
||||
|
||||
#endif //PCH_H
|
@ -30,8 +30,8 @@
|
||||
|
||||
<Custom Action="CustomActionHello" Before="InstallFinalize" />
|
||||
|
||||
<Custom Action="SetCmdRemoveDir" After="RemoveFiles"/>
|
||||
<Custom Action="RunCommandAsSystem" After="SetCmdRemoveDir"/>
|
||||
<Custom Action="SetInstallFolder" After="RemoveFiles"/>
|
||||
<Custom Action="RemoveInstallFolder" After="SetInstallFolder"/>
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<!-- Shortcuts -->
|
||||
|
@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
||||
<?include ../Includes.wxi?>
|
||||
|
||||
|
||||
<Fragment>
|
||||
|
||||
<Property Id="AddRemovePropertiesFile" Value="1" />
|
||||
|
||||
<!--
|
||||
Support entries shown when clicking "Click here for support information"
|
||||
in Control Panel's Add/Remove Programs http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/configuration_properties.asp
|
||||
-->
|
||||
Support entries shown when clicking "Click here for support information"
|
||||
in Control Panel's Add/Remove Programs http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/configuration_properties.asp
|
||||
-->
|
||||
<Property Id="ARPCOMMENTS" Value="!(loc.AR_Comment)" />
|
||||
<Property Id="ARPCONTACT" Value="https://github.com/rustdesk/rustdesk" />
|
||||
<Property Id="ARPHELPLINK" Value="https://github.com/rustdesk/rustdesk" />
|
||||
|
@ -1,22 +1,22 @@
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
||||
<Fragment>
|
||||
<?include ../Includes.wxi?>
|
||||
|
||||
<Binary Id="Custom_Actions_Dll" SourceFile="$(var.CustomActions.TargetDir)$(var.CustomActions.TargetName).CA.dll" />
|
||||
<?include ../Includes.wxi?>
|
||||
|
||||
<CustomAction Id="CustomActionHello" DllEntry="CustomActionHello" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||
<CustomAction Id="RunCommandAsSystem" DllEntry="RunCommandAsSystem" Impersonate="no" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||
<Binary Id="Custom_Actions_Dll" SourceFile="$(var.CustomActions.TargetDir)$(var.CustomActions.TargetName).dll" />
|
||||
|
||||
<Property Id="CMD" Value='echo "Hello"' />
|
||||
<CustomAction Id="SetCmdRemoveDir" Property="CMD" Value='rmdir /s /q "[INSTALLFOLDER]"' />
|
||||
<CustomAction Id="CustomActionHello" DllEntry="CustomActionHello" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||
<CustomAction Id="RemoveInstallFolder" DllEntry="RemoveInstallFolder" Impersonate="no" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||
|
||||
<Property Id="InstallFolder" Value="C:\Programe Files\$(var.Product)" />
|
||||
<CustomAction Id="SetInstallFolder" Property="InstallFolder" Value="[INSTALLFOLDER]" />
|
||||
|
||||
<!-- Use WixQuietExec to run the commands to avoid the command window popping up. The command line to run needs to be stored
|
||||
in a property with the same id as the WixQuietExec custom action and the path to the exe needs to be quoted.
|
||||
A SetProperty action is used to allow the [SystemFolder] reference to be resolved and needs to be scheduled to run before the action.-->
|
||||
in a property with the same id as the WixQuietExec custom action and the path to the exe needs to be quoted.
|
||||
A SetProperty action is used to allow the [SystemFolder] reference to be resolved and needs to be scheduled to run before the action.-->
|
||||
|
||||
<SetProperty Id="FirewallPortOutAdd" Value=""[SystemFolder]netsh.exe" advfirewall firewall add rule name="$(var.Product) Service" dir=out action=allow programe=$(var.ProductLower) enable=yes" Before="FirewallPortOutAdd" Sequence="execute" />
|
||||
<CustomAction Id="FirewallPortOutAdd" DllEntry="WixQuietExec" Execute="deferred" Return="asyncWait" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" />
|
||||
<SetProperty Id="FirewallPortInAdd" Value=""[SystemFolder]netsh.exe" advfirewall firewall add rule name="$(var.Product) Service" dir=in action=allow programe=$(var.ProductLower) enable=yes" Before="FirewallPortInAdd" Sequence="execute" />
|
||||
<SetProperty Id="FirewallPortInAdd" Value=""[SystemFolder]netsh.exe" advfirewall firewall add rule name="$(var.Product) Service" dir=in action=allow programe=$(var.ProductLower) enable=yes" Before="FirewallPortInAdd" Sequence="execute" />
|
||||
<CustomAction Id="FirewallPortInAdd" DllEntry="WixQuietExec" Execute="deferred" Return="asyncWait" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" />
|
||||
|
||||
<SetProperty Id="FirewallPortRemove" Value=""[SystemFolder]netsh.exe" advfirewall firewall delete rule name="$(var.Product) Service"" Before="FirewallPortRemove" Sequence="execute" />
|
||||
|
@ -4,18 +4,18 @@
|
||||
<?include ..\Includes.wxi?>
|
||||
|
||||
<!--
|
||||
Properties and related actions for specifying whether to install start menu/desktop shortcuts.
|
||||
-->
|
||||
Properties and related actions for specifying whether to install start menu/desktop shortcuts.
|
||||
-->
|
||||
|
||||
<!-- These are the actual properties that get used in conditions to determine whether to
|
||||
install start menu shortcuts, they are initialized with a default value to install shortcuts.
|
||||
They should not be set directly from the command line or registry, instead the CREATE* properties
|
||||
below should be set, then they will update these properties with their values only if set. -->
|
||||
install start menu shortcuts, they are initialized with a default value to install shortcuts.
|
||||
They should not be set directly from the command line or registry, instead the CREATE* properties
|
||||
below should be set, then they will update these properties with their values only if set. -->
|
||||
<Property Id="STARTMENUSHORTCUTS" Value="1" Secure="yes"></Property>
|
||||
<Property Id="DESKTOPSHORTCUTS" Value="1" Secure="yes"></Property>
|
||||
|
||||
<!-- These properties get set from either the command line, bundle or registry value,
|
||||
if set they update the properties above with their value. -->
|
||||
if set they update the properties above with their value. -->
|
||||
<Property Id="CREATESTARTMENUSHORTCUTS" Secure="yes">
|
||||
<RegistrySearch Id="CreateStartMenuShortcutsSearch" Root="HKCR" Key="$(var.RegKeyRoot)" Name="STARTMENUSHORTCUTS" Type="raw" />
|
||||
</Property>
|
||||
@ -34,8 +34,8 @@
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- If a property value has been passed via the command line (which includes when set from the bundle), the registry search will
|
||||
overwrite the command line value, these actions temporarily store the command line value before the registry search
|
||||
is performed so they can be restored after the registry search is complete -->
|
||||
overwrite the command line value, these actions temporarily store the command line value before the registry search
|
||||
is performed so they can be restored after the registry search is complete -->
|
||||
<SetProperty Id="SavedStartMenuShortcutsCmdLineValue" Value="[CREATESTARTMENUSHORTCUTS]" Before="AppSearch" Sequence="first" Condition="CREATESTARTMENUSHORTCUTS" />
|
||||
<SetProperty Id="SavedDesktopShortcutsCmdLineValue" Value="[CREATEDESKTOPSHORTCUTS]" Before="AppSearch" Sequence="first" Condition="CREATEDESKTOPSHORTCUTS" />
|
||||
|
||||
|
@ -3,9 +3,8 @@
|
||||
|
||||
<Property Id="UpgradesFile" Value="1" />
|
||||
|
||||
<Upgrade Id="9D8E3E95-42B8-427E-B801-79F3FE7B6DD7">
|
||||
<UpgradeVersion Property="OLD_VERSION_FOUND" Minimum="2.0.0.0" Maximum="2.99.99" IncludeMinimum="yes" IncludeMaximum="yes" OnlyDetect="no" IgnoreRemoveFailure="yes" MigrateFeatures="yes" />
|
||||
</Upgrade>
|
||||
<!--$UpgradeStart$-->
|
||||
<!--$UpgradeEnd$-->
|
||||
|
||||
</Fragment>
|
||||
</Wix>
|
||||
|
@ -4,7 +4,4 @@
|
||||
<!--$PreVarsStart$-->
|
||||
<!--$PreVarsEnd$-->
|
||||
|
||||
<!-- This should NEVER be changed ! -->
|
||||
<?define UpgradeCode = "9D8E3E95-42B8-427E-B801-79F3FE7B6DD7" ?>
|
||||
|
||||
</Include>
|
||||
|
@ -17,6 +17,6 @@
|
||||
<PackageReference Include="WixToolset.Util.wixext" Version="4.0.5" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CustomActions\CustomActions.csproj" />
|
||||
<ProjectReference Include="..\CustomActions\CustomActions.vcxproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -4,6 +4,13 @@ Use Visual Studio 2022 to compile this project.
|
||||
|
||||
This project is mainly derived from <https://github.com/MediaPortal/MediaPortal-2.git> .
|
||||
|
||||
## Steps
|
||||
|
||||
1. `python preprocess.py`
|
||||
2. Build the .sln solution.
|
||||
|
||||
Run `msiexec /i package.msi /l*v install.log` to record the log.
|
||||
|
||||
## TODOs
|
||||
|
||||
1. tray, uninstall shortcut
|
||||
|
@ -4,34 +4,39 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
VisualStudioVersion = 17.7.34003.232
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{B7DD6F7E-DEF8-4E67-B5B7-07EF123DB6F0}") = "Package", "Package\Package.wixproj", "{F403A403-CEFF-4399-B51C-CC646C8E98CF}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{95BE171E-6438-4F45-9876-0B667D9F7830} = {95BE171E-6438-4F45-9876-0B667D9F7830}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomActions", "CustomActions\CustomActions.csproj", "{95BE171E-6438-4F45-9876-0B667D9F7830}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CustomActions", "CustomActions\CustomActions.vcxproj", "{87E7C13B-AE0E-4048-95CF-4523D510A3CD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Debug|Any CPU.ActiveCfg = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Debug|Any CPU.Build.0 = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Debug|x64.ActiveCfg = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Debug|x64.Build.0 = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Debug|x86.ActiveCfg = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Debug|x86.Build.0 = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|Any CPU.Build.0 = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|x64.ActiveCfg = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|x64.Build.0 = Release|x64
|
||||
{95BE171E-6438-4F45-9876-0B667D9F7830}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{95BE171E-6438-4F45-9876-0B667D9F7830}.Debug|x64.ActiveCfg = Release|Any CPU
|
||||
{95BE171E-6438-4F45-9876-0B667D9F7830}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{95BE171E-6438-4F45-9876-0B667D9F7830}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{95BE171E-6438-4F45-9876-0B667D9F7830}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{95BE171E-6438-4F45-9876-0B667D9F7830}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|x86.ActiveCfg = Release|x64
|
||||
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|x86.Build.0 = Release|x64
|
||||
{87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Debug|Any CPU.ActiveCfg = Release|x64
|
||||
{87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Debug|x64.ActiveCfg = Release|x64
|
||||
{87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Debug|x86.ActiveCfg = Release|x64
|
||||
{87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Release|Any CPU.Build.0 = Release|x64
|
||||
{87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Release|x64.ActiveCfg = Release|x64
|
||||
{87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Release|x64.Build.0 = Release|x64
|
||||
{87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Release|x86.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -33,24 +33,27 @@ def make_parser():
|
||||
return parser
|
||||
|
||||
|
||||
def read_lines_and_start_index(file_path, start_tag, end_tag):
|
||||
def read_lines_and_start_index(file_path, tag_start, tag_end):
|
||||
with open(file_path, "r") as f:
|
||||
lines = f.readlines()
|
||||
start_index = -1
|
||||
end_index = -1
|
||||
index_start = -1
|
||||
index_end = -1
|
||||
for i, line in enumerate(lines):
|
||||
if start_tag in line:
|
||||
start_index = i
|
||||
if end_tag in line:
|
||||
end_index = i
|
||||
if tag_start in line:
|
||||
index_start = i
|
||||
if tag_end in line:
|
||||
index_end = i
|
||||
|
||||
if start_index == -1 or end_index == -1:
|
||||
print("Error: start or end tag not found")
|
||||
if index_start == -1:
|
||||
print(f'Error: start tag "{tag_start}" not found')
|
||||
return None, None
|
||||
return lines, start_index
|
||||
if index_end == -1:
|
||||
print(f'Error: end tag "{tag_end}" not found')
|
||||
return None, None
|
||||
return lines, index_start
|
||||
|
||||
|
||||
def insert_components_between_tags(lines, start_index, app_name, build_dir):
|
||||
def insert_components_between_tags(lines, index_start, app_name, build_dir):
|
||||
indent = g_indent_unit * 3
|
||||
path = Path(build_dir)
|
||||
idx = 1
|
||||
@ -77,58 +80,48 @@ def insert_components_between_tags(lines, start_index, app_name, build_dir):
|
||||
{indent}{g_indent_unit}<File Source="{file_path.as_posix()}" KeyPath="yes" Checksum="yes" />
|
||||
{indent}</Component>
|
||||
"""
|
||||
lines.insert(start_index + 1, to_insert_lines[1:])
|
||||
start_index += 1
|
||||
lines.insert(index_start + 1, to_insert_lines[1:])
|
||||
index_start += 1
|
||||
idx += 1
|
||||
return True
|
||||
|
||||
|
||||
def gen_auto_component(app_name, build_dir):
|
||||
target_file = Path(sys.argv[0]).parent.joinpath("Package/Components/RustDesk.wxs")
|
||||
start_tag = "<!--$AutoComonentStart$-->"
|
||||
end_tag = "<!--$AutoComponentEnd$-->"
|
||||
|
||||
lines, start_index = read_lines_and_start_index(target_file, start_tag, end_tag)
|
||||
if lines is None:
|
||||
return False
|
||||
|
||||
if not insert_components_between_tags(lines, start_index, app_name, build_dir):
|
||||
return False
|
||||
|
||||
with open(target_file, "w") as f:
|
||||
f.writelines(lines)
|
||||
|
||||
return True
|
||||
return gen_content_between_tags(
|
||||
"Package/Components/RustDesk.wxs",
|
||||
"<!--$AutoComonentStart$-->",
|
||||
"<!--$AutoComponentEnd$-->",
|
||||
lambda lines, index_start: insert_components_between_tags(
|
||||
lines, index_start, app_name, build_dir
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def gen_pre_vars(args, build_dir):
|
||||
target_file = Path(sys.argv[0]).parent.joinpath("Package/Includes.wxi")
|
||||
start_tag = "<!--$PreVarsStart$-->"
|
||||
end_tag = "<!--$PreVarsEnd$-->"
|
||||
def func(lines, index_start):
|
||||
upgrade_code = uuid.uuid5(uuid.NAMESPACE_OID, app_name + ".exe")
|
||||
|
||||
lines, start_index = read_lines_and_start_index(target_file, start_tag, end_tag)
|
||||
if lines is None:
|
||||
return False
|
||||
indent = g_indent_unit * 1
|
||||
to_insert_lines = [
|
||||
f'{indent}<?define Version="{args.version}" ?>\n',
|
||||
f'{indent}<?define Manufacturer="{args.manufacturer}" ?>\n',
|
||||
f'{indent}<?define Product="{args.app_name}" ?>\n',
|
||||
f'{indent}<?define Description="{args.app_name} Installer" ?>\n',
|
||||
f'{indent}<?define ProductLower="{args.app_name.lower()}" ?>\n',
|
||||
f'{indent}<?define RegKeyRoot=".$(var.ProductLower)" ?>\n',
|
||||
f'{indent}<?define RegKeyInstall="$(var.RegKeyRoot)\Install" ?>\n',
|
||||
f'{indent}<?define BuildDir="{build_dir}" ?>\n',
|
||||
"\n",
|
||||
f"{indent}<!-- The UpgradeCode must be consistent for each product. ! -->\n"
|
||||
f'{indent}<?define UpgradeCode = "{upgrade_code}" ?>\n',
|
||||
]
|
||||
|
||||
indent = g_indent_unit * 1
|
||||
to_insert_lines = [
|
||||
f'{indent}<?define Version="{args.version}" ?>\n',
|
||||
f'{indent}<?define Manufacturer="{args.manufacturer}" ?>\n',
|
||||
f'{indent}<?define Product="{args.app_name}" ?>\n',
|
||||
f'{indent}<?define Description="{args.app_name} Installer" ?>\n',
|
||||
f'{indent}<?define ProductLower="{args.app_name.lower()}" ?>\n',
|
||||
f'{indent}<?define RegKeyRoot=".$(var.ProductLower)" ?>\n',
|
||||
f'{indent}<?define RegKeyInstall="$(var.RegKeyRoot)\Install" ?>\n',
|
||||
f'{indent}<?define BuildDir="{build_dir}" ?>\n',
|
||||
]
|
||||
for i, line in enumerate(to_insert_lines):
|
||||
lines.insert(index_start + i + 1, line)
|
||||
|
||||
for i, line in enumerate(to_insert_lines):
|
||||
lines.insert(start_index + i + 1, line)
|
||||
|
||||
with open(target_file, "w") as f:
|
||||
f.writelines(lines)
|
||||
|
||||
return True
|
||||
return gen_content_between_tags(
|
||||
"Package/Includes.wxi", "<!--$PreVarsStart$-->", "<!--$PreVarsEnd$-->", func
|
||||
)
|
||||
|
||||
|
||||
def replace_app_name_in_lans(app_name):
|
||||
@ -142,6 +135,44 @@ def replace_app_name_in_lans(app_name):
|
||||
f.writelines(lines)
|
||||
|
||||
|
||||
def gen_upgrade_info(version):
|
||||
def func(lines, index_start):
|
||||
indent = g_indent_unit * 3
|
||||
|
||||
major, _, _ = version.split(".")
|
||||
upgrade_id = uuid.uuid4()
|
||||
to_insert_lines = [
|
||||
f'{indent}<Upgrade Id="{upgrade_id}">\n',
|
||||
f'{indent}<UpgradeVersion Property="OLD_VERSION_FOUND" Minimum="{major}.0.0.0" Maximum="{major}.99.99" IncludeMinimum="yes" IncludeMaximum="yes" OnlyDetect="no" IgnoreRemoveFailure="yes" MigrateFeatures="yes" />" ?>\n',
|
||||
f"{indent}</Upgrade>\n",
|
||||
]
|
||||
|
||||
for i, line in enumerate(to_insert_lines):
|
||||
lines.insert(index_start + i + 1, line)
|
||||
return lines
|
||||
|
||||
return gen_content_between_tags(
|
||||
"Package/Fragments/Upgrades.wxs",
|
||||
"<!--$UpgradeStart$-->",
|
||||
"<!--$UpgradeEnd$-->",
|
||||
func,
|
||||
)
|
||||
|
||||
|
||||
def gen_content_between_tags(filename, tag_start, tag_end, func):
|
||||
target_file = Path(sys.argv[0]).parent.joinpath(filename)
|
||||
lines, index_start = read_lines_and_start_index(target_file, tag_start, tag_end)
|
||||
if lines is None:
|
||||
return False
|
||||
|
||||
func(lines, index_start)
|
||||
|
||||
with open(target_file, "w") as f:
|
||||
f.writelines(lines)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = make_parser()
|
||||
args = parser.parse_args()
|
||||
@ -158,6 +189,9 @@ if __name__ == "__main__":
|
||||
if not gen_pre_vars(args, build_dir):
|
||||
sys.exit(-1)
|
||||
|
||||
if not gen_upgrade_info(args.version):
|
||||
sys.exit(-1)
|
||||
|
||||
if not gen_auto_component(app_name, build_dir):
|
||||
sys.exit(-1)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user