Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2024-04-03 14:27:35 +08:00 committed by GitHub
parent 33eaf2e05c
commit ed257e39d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 349 additions and 181 deletions

7
res/msi/.gitignore vendored
View File

@ -2,3 +2,10 @@
**/bin **/bin
**/obj **/obj
x64
packages
CustomActions/x64
CustomActions/*.user
CustomActions/*.filters

View File

@ -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>

View File

@ -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;
}
}
}
}

View 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);
}

View File

@ -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>

View File

@ -0,0 +1,5 @@
LIBRARY "CustomActions"
EXPORTS
CustomActionHello
RemoveInstallFolder

View 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>

View 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;
}

View 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>

View 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>

View 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.

View 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

View File

@ -30,8 +30,8 @@
<Custom Action="CustomActionHello" Before="InstallFinalize" /> <Custom Action="CustomActionHello" Before="InstallFinalize" />
<Custom Action="SetCmdRemoveDir" After="RemoveFiles"/> <Custom Action="SetInstallFolder" After="RemoveFiles"/>
<Custom Action="RunCommandAsSystem" After="SetCmdRemoveDir"/> <Custom Action="RemoveInstallFolder" After="SetInstallFolder"/>
</InstallExecuteSequence> </InstallExecuteSequence>
<!-- Shortcuts --> <!-- Shortcuts -->

View File

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include ../Includes.wxi?> <?include ../Includes.wxi?>
<Fragment> <Fragment>
<Property Id="AddRemovePropertiesFile" Value="1" /> <Property Id="AddRemovePropertiesFile" Value="1" />
<!-- <!--
Support entries shown when clicking "Click here for support information" 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 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="ARPCOMMENTS" Value="!(loc.AR_Comment)" />
<Property Id="ARPCONTACT" Value="https://github.com/rustdesk/rustdesk" /> <Property Id="ARPCONTACT" Value="https://github.com/rustdesk/rustdesk" />
<Property Id="ARPHELPLINK" Value="https://github.com/rustdesk/rustdesk" /> <Property Id="ARPHELPLINK" Value="https://github.com/rustdesk/rustdesk" />

View File

@ -1,22 +1,22 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment> <Fragment>
<?include ../Includes.wxi?> <?include ../Includes.wxi?>
<Binary Id="Custom_Actions_Dll" SourceFile="$(var.CustomActions.TargetDir)$(var.CustomActions.TargetName).CA.dll" />
<CustomAction Id="CustomActionHello" DllEntry="CustomActionHello" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/> <Binary Id="Custom_Actions_Dll" SourceFile="$(var.CustomActions.TargetDir)$(var.CustomActions.TargetName).dll" />
<CustomAction Id="RunCommandAsSystem" DllEntry="RunCommandAsSystem" Impersonate="no" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
<Property Id="CMD" Value='echo "Hello"' /> <CustomAction Id="CustomActionHello" DllEntry="CustomActionHello" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
<CustomAction Id="SetCmdRemoveDir" Property="CMD" Value='rmdir /s /q "[INSTALLFOLDER]"' /> <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 <!-- 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. 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.--> 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="&quot;[SystemFolder]netsh.exe&quot; advfirewall firewall add rule name=&quot;$(var.Product) Service&quot; dir=out action=allow programe=$(var.ProductLower) enable=yes" Before="FirewallPortOutAdd" Sequence="execute" /> <SetProperty Id="FirewallPortOutAdd" Value="&quot;[SystemFolder]netsh.exe&quot; advfirewall firewall add rule name=&quot;$(var.Product) Service&quot; 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)" /> <CustomAction Id="FirewallPortOutAdd" DllEntry="WixQuietExec" Execute="deferred" Return="asyncWait" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" />
<SetProperty Id="FirewallPortInAdd" Value="&quot;[SystemFolder]netsh.exe&quot; advfirewall firewall add rule name=&quot;$(var.Product) Service&quot; dir=in action=allow programe=$(var.ProductLower) enable=yes" Before="FirewallPortInAdd" Sequence="execute" /> <SetProperty Id="FirewallPortInAdd" Value="&quot;[SystemFolder]netsh.exe&quot; advfirewall firewall add rule name=&quot;$(var.Product) Service&quot; 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)" /> <CustomAction Id="FirewallPortInAdd" DllEntry="WixQuietExec" Execute="deferred" Return="asyncWait" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" />
<SetProperty Id="FirewallPortRemove" Value="&quot;[SystemFolder]netsh.exe&quot; advfirewall firewall delete rule name=&quot;$(var.Product) Service&quot;" Before="FirewallPortRemove" Sequence="execute" /> <SetProperty Id="FirewallPortRemove" Value="&quot;[SystemFolder]netsh.exe&quot; advfirewall firewall delete rule name=&quot;$(var.Product) Service&quot;" Before="FirewallPortRemove" Sequence="execute" />

View File

@ -4,18 +4,18 @@
<?include ..\Includes.wxi?> <?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 <!-- 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. 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 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. --> 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="STARTMENUSHORTCUTS" Value="1" Secure="yes"></Property>
<Property Id="DESKTOPSHORTCUTS" 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, <!-- 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"> <Property Id="CREATESTARTMENUSHORTCUTS" Secure="yes">
<RegistrySearch Id="CreateStartMenuShortcutsSearch" Root="HKCR" Key="$(var.RegKeyRoot)" Name="STARTMENUSHORTCUTS" Type="raw" /> <RegistrySearch Id="CreateStartMenuShortcutsSearch" Root="HKCR" Key="$(var.RegKeyRoot)" Name="STARTMENUSHORTCUTS" Type="raw" />
</Property> </Property>
@ -34,8 +34,8 @@
</DirectoryRef> </DirectoryRef>
<!-- If a property value has been passed via the command line (which includes when set from the bundle), the registry search will <!-- 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 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 --> 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="SavedStartMenuShortcutsCmdLineValue" Value="[CREATESTARTMENUSHORTCUTS]" Before="AppSearch" Sequence="first" Condition="CREATESTARTMENUSHORTCUTS" />
<SetProperty Id="SavedDesktopShortcutsCmdLineValue" Value="[CREATEDESKTOPSHORTCUTS]" Before="AppSearch" Sequence="first" Condition="CREATEDESKTOPSHORTCUTS" /> <SetProperty Id="SavedDesktopShortcutsCmdLineValue" Value="[CREATEDESKTOPSHORTCUTS]" Before="AppSearch" Sequence="first" Condition="CREATEDESKTOPSHORTCUTS" />

View File

@ -3,9 +3,8 @@
<Property Id="UpgradesFile" Value="1" /> <Property Id="UpgradesFile" Value="1" />
<Upgrade Id="9D8E3E95-42B8-427E-B801-79F3FE7B6DD7"> <!--$UpgradeStart$-->
<UpgradeVersion Property="OLD_VERSION_FOUND" Minimum="2.0.0.0" Maximum="2.99.99" IncludeMinimum="yes" IncludeMaximum="yes" OnlyDetect="no" IgnoreRemoveFailure="yes" MigrateFeatures="yes" /> <!--$UpgradeEnd$-->
</Upgrade>
</Fragment> </Fragment>
</Wix> </Wix>

View File

@ -4,7 +4,4 @@
<!--$PreVarsStart$--> <!--$PreVarsStart$-->
<!--$PreVarsEnd$--> <!--$PreVarsEnd$-->
<!-- This should NEVER be changed ! -->
<?define UpgradeCode = "9D8E3E95-42B8-427E-B801-79F3FE7B6DD7" ?>
</Include> </Include>

View File

@ -17,6 +17,6 @@
<PackageReference Include="WixToolset.Util.wixext" Version="4.0.5" /> <PackageReference Include="WixToolset.Util.wixext" Version="4.0.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\CustomActions\CustomActions.csproj" /> <ProjectReference Include="..\CustomActions\CustomActions.vcxproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -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> . 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 ## TODOs
1. tray, uninstall shortcut 1. tray, uninstall shortcut

View File

@ -4,34 +4,39 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 17.7.34003.232 VisualStudioVersion = 17.7.34003.232
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{B7DD6F7E-DEF8-4E67-B5B7-07EF123DB6F0}") = "Package", "Package\Package.wixproj", "{F403A403-CEFF-4399-B51C-CC646C8E98CF}" 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 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 EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64 Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Debug|Any CPU.ActiveCfg = Release|x64 {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|Any CPU.Build.0 = Release|x64
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Debug|x64.ActiveCfg = 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|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.ActiveCfg = Release|x64
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|Any CPU.Build.0 = 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.ActiveCfg = Release|x64
{F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|x64.Build.0 = 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 {F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|x86.ActiveCfg = Release|x64
{95BE171E-6438-4F45-9876-0B667D9F7830}.Debug|x64.ActiveCfg = Release|Any CPU {F403A403-CEFF-4399-B51C-CC646C8E98CF}.Release|x86.Build.0 = Release|x64
{95BE171E-6438-4F45-9876-0B667D9F7830}.Release|Any CPU.ActiveCfg = Release|Any CPU {87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Debug|Any CPU.ActiveCfg = Release|x64
{95BE171E-6438-4F45-9876-0B667D9F7830}.Release|Any CPU.Build.0 = Release|Any CPU {87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Debug|x64.ActiveCfg = Release|x64
{95BE171E-6438-4F45-9876-0B667D9F7830}.Release|x64.ActiveCfg = Release|Any CPU {87E7C13B-AE0E-4048-95CF-4523D510A3CD}.Debug|x86.ActiveCfg = Release|x64
{95BE171E-6438-4F45-9876-0B667D9F7830}.Release|x64.Build.0 = Release|Any CPU {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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -33,24 +33,27 @@ def make_parser():
return 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: with open(file_path, "r") as f:
lines = f.readlines() lines = f.readlines()
start_index = -1 index_start = -1
end_index = -1 index_end = -1
for i, line in enumerate(lines): for i, line in enumerate(lines):
if start_tag in line: if tag_start in line:
start_index = i index_start = i
if end_tag in line: if tag_end in line:
end_index = i index_end = i
if start_index == -1 or end_index == -1: if index_start == -1:
print("Error: start or end tag not found") print(f'Error: start tag "{tag_start}" not found')
return None, None 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 indent = g_indent_unit * 3
path = Path(build_dir) path = Path(build_dir)
idx = 1 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}{g_indent_unit}<File Source="{file_path.as_posix()}" KeyPath="yes" Checksum="yes" />
{indent}</Component> {indent}</Component>
""" """
lines.insert(start_index + 1, to_insert_lines[1:]) lines.insert(index_start + 1, to_insert_lines[1:])
start_index += 1 index_start += 1
idx += 1 idx += 1
return True return True
def gen_auto_component(app_name, build_dir): def gen_auto_component(app_name, build_dir):
target_file = Path(sys.argv[0]).parent.joinpath("Package/Components/RustDesk.wxs") return gen_content_between_tags(
start_tag = "<!--$AutoComonentStart$-->" "Package/Components/RustDesk.wxs",
end_tag = "<!--$AutoComponentEnd$-->" "<!--$AutoComonentStart$-->",
"<!--$AutoComponentEnd$-->",
lines, start_index = read_lines_and_start_index(target_file, start_tag, end_tag) lambda lines, index_start: insert_components_between_tags(
if lines is None: lines, index_start, app_name, build_dir
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
def gen_pre_vars(args, build_dir): def gen_pre_vars(args, build_dir):
target_file = Path(sys.argv[0]).parent.joinpath("Package/Includes.wxi") def func(lines, index_start):
start_tag = "<!--$PreVarsStart$-->" upgrade_code = uuid.uuid5(uuid.NAMESPACE_OID, app_name + ".exe")
end_tag = "<!--$PreVarsEnd$-->"
lines, start_index = read_lines_and_start_index(target_file, start_tag, end_tag) indent = g_indent_unit * 1
if lines is None: to_insert_lines = [
return False 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 for i, line in enumerate(to_insert_lines):
to_insert_lines = [ lines.insert(index_start + i + 1, line)
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): return gen_content_between_tags(
lines.insert(start_index + i + 1, line) "Package/Includes.wxi", "<!--$PreVarsStart$-->", "<!--$PreVarsEnd$-->", func
)
with open(target_file, "w") as f:
f.writelines(lines)
return True
def replace_app_name_in_lans(app_name): def replace_app_name_in_lans(app_name):
@ -142,6 +135,44 @@ def replace_app_name_in_lans(app_name):
f.writelines(lines) 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__": if __name__ == "__main__":
parser = make_parser() parser = make_parser()
args = parser.parse_args() args = parser.parse_args()
@ -158,6 +189,9 @@ if __name__ == "__main__":
if not gen_pre_vars(args, build_dir): if not gen_pre_vars(args, build_dir):
sys.exit(-1) sys.exit(-1)
if not gen_upgrade_info(args.version):
sys.exit(-1)
if not gen_auto_component(app_name, build_dir): if not gen_auto_component(app_name, build_dir):
sys.exit(-1) sys.exit(-1)