# OpenRGB MSI Builder for Windows
# PowerShell conversion of build-msi.sh
# Add Wix to path
$env:Path += ";C:\Program Files (x86)\WiX Toolset v3.14\bin"
# Add Qt to path
$env:Path += ";C:\Qt\6.8.3\msvc2022_64\bin"
# Function to generate random UUID v4
function Generate-UUIDv4
{
return [guid]::NewGuid().ToString().ToUpper()
}
# Function to generate namespace-based UUID (SHA1)
function Generate-NamespaceUUID
{
param
(
[guid]$Namespace,
[string]$Name
)
$nameBytes = [System.Text.Encoding]::UTF8.GetBytes($Name)
$combined = $Namespace.ToByteArray() + $nameBytes
$hash = [System.Security.Cryptography.SHA1]::Create().ComputeHash($combined)
# Set version to 5 (SHA1-based namespace UUID)
$hash[6] = ($hash[6] -band 0x0f) -bor 0x50
$hash[8] = ($hash[8] -band 0x3f) -bor 0x80
$uuidBytes = [byte[]]($hash[0..15])
$uuid = [guid]$uuidBytes
return $uuid.ToString().ToUpper()
}
# Configuration
$PRODUCTNAME = "OpenRGB"
$VENDOR = $PRODUCTNAME
$TLD = "org"
$WEBSITE = "https://$($PRODUCTNAME.ToLower()).$TLD"
# URL namespace UUID (RFC 4122, version 4 namespace)
$URLNamespace = [guid]'6ba7b810-9dad-11d1-80b4-00c04fd430c8'
$NAMESPACE = Generate-NamespaceUUID $URLNamespace $WEBSITE
$VENDOR_ID = "$TLD.$VENDOR"
$APP_ID = "$VENDOR_ID.$($PRODUCTNAME.ToLower())"
$GITURL = "https://gitlab.com/CalcProgrammer1/OpenRGB/-"
$GITPARAM = "?inline=false"
$ICONFILE = "qt/OpenRGB.ico"
$LICENSEFILE = "scripts/License.rtf"
$BANNERIMAGE = "scripts/banner.bmp"
$DIALOGBACKGROUND = "scripts/dialog_background.bmp"
$PROJECT_FILE = "OpenRGB.pro"
$XMLOUTFILE = "$($PRODUCTNAME.ToLower()).wxs"
# Extract version from project file
$VERSION = & qmake $PROJECT_FILE 2>&1 | Select-String 'VERSION_WIX' | Select-Object -First 1 | ForEach-Object {
$_.Line -split ':' | Select-Object -Last 1 | ForEach-Object { $_.Trim() }
}
# Check for suffix to determine channel
$CHANNEL = ""
$SUFFIX = Select-String -Path $PROJECT_FILE -Pattern 'SUFFIX\s' | ForEach-Object {
$_.Line -split '=' | Select-Object -Last 1 | ForEach-Object { $_.Trim() }
}
if($SUFFIX)
{
$CHANNEL = "-git"
}
# Calculate upgrade code
$UPGRADECODE = Generate-NamespaceUUID ([guid]$NAMESPACE) $APP_ID
$PRODUCTCOMMENT = "Open source RGB lighting control that doesn't depend on manufacturer software."
# Print Metadata to the log
Write-Host "Icon URL:`t" $GITURL$ICONFILE
Write-Host "License URL:`t" $GITURL$LICENSEFILE
Write-Host "AppID - Channel:`t" $APP_ID " - " $CHANNEL
Write-Host "Upgrade UUID:`t" $UPGRADECODE
Write-Host "Product Name:`t" $PRODUCTNAME
Write-Host "Vendor - VendorID:`t`t" $VENDOR " - " $VENDOR_ID
Write-Host "Version:`t" $VERSION
# Copy build directory to working path
$BUILT_PATH = "OpenRGB Windows 64-bit\*"
$WORKING_PATH = "OpenRGB Windows MSI Installer\"
if(Test-Path $BUILT_PATH)
{
Copy-Item -Path $BUILT_PATH -Destination $WORKING_PATH -Recurse -Force
}
$count = 1
$EXE_FILE = ""
$SVC_FILE = ""
$FILES = ""
$COMPONENTS = ""
$DIRECTORIES = ""
# Build file list for files in the working path
Get-ChildItem -Path $WORKING_PATH -Force | ForEach-Object {
$file = $_
$filename = $_.Name
if($filename -eq "$PRODUCTNAME.exe")
{
# If this is the executable, treat as special case
$script:EXE_ID = "$($PRODUCTNAME)00"
$script:SVC_ID = "$($PRODUCTNAME)00_SVC"
$script:EXE_FILE = " `r`n"
$script:SVC_FILE = " `r`n"
}
elseif($_.PSIsContainer)
{
# If this is a directory, add another component
$script:COMPONENTS += " `r`n"
$guid = Generate-UUIDv4
$TEMP = " `r`n"
$TEMP += " `r`n"
Get-ChildItem -Path $file.FullName -Force | ForEach-Object {
$filename2 = $_.Name
$TEMP += " `r`n"
$script:count++
}
$TEMP += " `r`n `r`n"
$script:DIRECTORIES += $TEMP
}
else
{
# Any other file to files list
$script:FILES += " `r`n"
$script:count++
}
}
# Create the Wix XML file
$XML_FILE = ""
$XML_FILE += "`r`n"
$XML_FILE += "`r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " VersionNT64`r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += "`r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += "`r`n"
$XML_FILE += " `r`n"
$XML_FILE += "`r`n"
$XML_FILE += " `r`n"
$XML_FILE += "`r`n"
$XML_FILE += " WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID=`"1`"`r`n"
$XML_FILE += " 1`r`n"
$XML_FILE += " 1`r`n"
$XML_FILE += " 1`r`n"
$XML_FILE += " 1`r`n"
$XML_FILE += " 1`r`n"
$XML_FILE += " `r`n"
$XML_FILE += "`r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$guid1 = Generate-UUIDv4
$XML_FILE += " `r`n"
$XML_FILE += $EXE_FILE
$XML_FILE += $FILES
$XML_FILE += " `r`n"
$guid2 = Generate-UUIDv4
$XML_FILE += " `r`n"
$XML_FILE += $SVC_FILE
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += $DIRECTORIES
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += $COMPONENTS
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += " `r`n"
$XML_FILE += ""
# Write XML file
$XML_FILE | Out-File -FilePath $XMLOUTFILE -Encoding UTF8
# Print the XML for debugging
Write-Host (Get-Content $XMLOUTFILE)
# Build the MSI package
Write-Host "`nBuilding MSI package..."
$wixObjFile = "$($PRODUCTNAME.ToLower()).wixobj"
$msiFile = "$($PRODUCTNAME)_Windows_64.msi"
& candle -arch x64 $XMLOUTFILE
& light -sval -ext WixUIExtension $wixObjFile -out $msiFile