2020-08-25 06:10:50 +08:00
# This script is used to move the resources from all the resx files in the directory (args[0]) to a .rc and .h file for use in C++ projects.
# Root directory which contains the resx files
$parentDirectory = $args [ 0 ]
# File name of the base resource.h which contains all the non-localized resource definitions
$baseHeaderFileName = $args [ 1 ]
# Target file name of the resource header file, which will be used in code - Example: resource.h
$generatedHeaderFileName = $args [ 2 ]
# File name of the base ProjectName.rc which contains all the non-localized resources
$baseRCFileName = $args [ 3 ]
# Target file name of the resource rc file, which will be used in code - Example: ProjectName.rc
$generatedRCFileName = $args [ 4 ]
2020-08-25 08:51:48 +08:00
# Optional argument: Initial resource id in the resource header file. By default it is 101
if ( $args . Count -eq 6 )
{
$initResourceID = $args [ 5 ]
}
else
{
$initResourceID = 101
}
2020-08-25 06:10:50 +08:00
# Flags to check if the first updated has occurred
$headerFileUpdated = $false
$rcFileUpdated = $false
# Output folder for the new resource files. It will be in ProjectDir\Generated Files so that the files are ignored by .gitignore
$generatedFilesFolder = $parentDirectory + " \Generated Files "
# Create Generated Files folder if it doesn't exist
if ( ! ( Test-Path -Path $generatedFilesFolder ) )
{
$paramNewItem = @ {
Path = $generatedFilesFolder
ItemType = 'Directory'
Force = $true
}
New-Item @paramNewItem
}
# Hash table to get the language codes from the code used in the file name
$languageHashTable = @ { " en " = @ ( " ENU " , " ENGLISH " , " ENGLISH_US " , " English (United States) " ) ;
" zh-Hans " = @ ( " CHS " , " CHINESE " , " NEUTRAL " , " Chinese (Simplified) " ) ;
2021-12-18 10:15:31 +08:00
" zh-CN " = @ ( " CHS " , " CHINESE " , " NEUTRAL " , " Chinese (Simplified) " ) ;
2020-08-25 06:10:50 +08:00
" cs " = @ ( " CSY " , " CZECH " , " NEUTRAL " , " Czech " ) ;
" hu " = @ ( " HUN " , " HUNGARIAN " , " NEUTRAL " , " Hungarian " ) ;
" pl " = @ ( " PLK " , " POLISH " , " NEUTRAL " , " Polish " ) ;
" ro " = @ ( " ROM " , " ROMANIAN " , " NEUTRAL " , " Romanian " ) ;
" sk " = @ ( " SKY " , " SLOVAK " , " NEUTRAL " , " Slovak " ) ;
" bg " = @ ( " BGR " , " BULGARIAN " , " NEUTRAL " , " Bulgarian " ) ;
" ru " = @ ( " RUS " , " RUSSIAN " , " NEUTRAL " , " Russian " ) ;
" ca " = @ ( " CAT " , " CATALAN " , " NEUTRAL " , " Catalan " ) ;
" de " = @ ( " DEU " , " GERMAN " , " NEUTRAL " , " German " ) ;
" es " = @ ( " ESN " , " SPANISH " , " NEUTRAL " , " Spanish " ) ;
" fr " = @ ( " FRA " , " FRENCH " , " NEUTRAL " , " French " ) ;
" it " = @ ( " ITA " , " ITALIAN " , " NEUTRAL " , " Italian " ) ;
" nl " = @ ( " NLD " , " DUTCH " , " NEUTRAL " , " Dutch " ) ;
" nb-NO " = @ ( " NOR " , " NORWEGIAN " , " NORWEGIAN_BOKMAL " , " Norwegian Bokmål (Norway) " ) ;
" pt-BR " = @ ( " PTB " , " PORTUGUESE " , " PORTUGUESE_BRAZILIAN " , " Portuguese (Brazil) " ) ;
" eu-ES " = @ ( " EUQ " , " BASQUE " , " DEFAULT " , " Basque (Basque) " ) ;
" tr " = @ ( " TRK " , " TURKISH " , " NEUTRAL " , " Turkish " ) ;
" he " = @ ( " HEB " , " HEBREW " , " NEUTRAL " , " Hebrew " ) ;
" ar " = @ ( " ARA " , " ARABIC " , " NEUTRAL " , " Arabic " ) ;
" ja " = @ ( " JPN " , " JAPANESE " , " NEUTRAL " , " Japanese " ) ;
" ko " = @ ( " KOR " , " KOREAN " , " NEUTRAL " , " Korean " ) ;
" sv " = @ ( " SVE " , " SWEDISH " , " NEUTRAL " , " Swedish " ) ;
" pt-PT " = @ ( " PTG " , " PORTUGUESE " , " PORTUGUESE " , " Portuguese (Portugal) " ) ;
" zh-Hant " = @ ( " CHT " , " CHINESE " , " CHINESE_TRADITIONAL " , " Chinese (Traditional) " )
2021-12-18 10:15:31 +08:00
" zh-TW " = @ ( " CHT " , " CHINESE " , " CHINESE_TRADITIONAL " , " Chinese (Traditional) " )
2020-08-25 06:10:50 +08:00
}
# Store the content to be written to a buffer
$headerFileContent = " "
$rcFileContent = " "
# Iterate over all resx files in parent directory
2021-12-18 10:15:31 +08:00
Get-ChildItem $parentDirectory -Recurse -Filter * . resx |
2020-08-25 06:10:50 +08:00
Foreach-Object {
2021-12-18 10:15:31 +08:00
Write-Host " Processing $( $_ . FullName ) "
$xmlDocument = $null
2020-08-25 06:10:50 +08:00
try {
2021-12-18 10:15:31 +08:00
$xmlDocument = [ xml ] ( Get-Content $_ . FullName -ErrorAction: Stop )
2020-08-25 06:10:50 +08:00
}
catch {
2021-12-18 10:15:31 +08:00
Write-Host " Failed to load $( $_ . FullName ) "
2020-08-25 06:10:50 +08:00
exit 0
}
# Get language code from file name
$lang = " en "
$tokens = $_ . Name -split " \. "
if ( $tokens . Count -eq 3 ) {
$lang = $tokens [ 1 ]
2021-12-18 10:15:31 +08:00
} else {
$d = $_ . Directory . Name
If ( $d . Contains ( '-' ) ) { # Looks like a language directory
$lang = $d
}
2020-08-25 06:10:50 +08:00
}
2021-12-18 10:15:31 +08:00
2020-08-25 06:10:50 +08:00
$langData = $languageHashTable [ $lang ]
2021-12-18 10:15:31 +08:00
if ( $null -eq $langData -and $lang . Contains ( '-' ) ) {
# Modern Localization comes in with language + country tuples;
# we want to detect the language alone if we don't support the language-country
# version.
$lang = ( $lang -split " - " ) [ 0 ]
$langData = $languageHashTable [ $lang ]
}
if ( $null -eq $langData ) {
Write-Warning " Unknown language $lang "
Return
}
2020-08-25 06:10:50 +08:00
$newLinesForRCFile = " "
$newLinesForHeaderFile = " "
2020-08-25 08:51:48 +08:00
$count = $initResourceID
2020-08-25 06:10:50 +08:00
try {
2021-12-18 10:15:31 +08:00
foreach ( $entry in $xmlDocument . root . data ) {
2020-08-26 22:54:28 +08:00
$culture = [ System.Globalization.CultureInfo ] :: GetCultureInfo ( 'en-US' )
2020-10-15 00:03:45 +08:00
# Each resource is named as IDS_ResxResourceName, in uppercase. Escape occurrences of double quotes in the string
2021-12-18 10:15:31 +08:00
$lineInRCFormat = " IDS_ " + $entry . name . ToUpper ( $culture ) + " L `" " + $entry . value . Replace ( " `" " , " `" `" " ) + " `" "
2020-08-25 06:10:50 +08:00
$newLinesForRCFile = $newLinesForRCFile + " `r `n " + $lineInRCFormat
# Resource header file needs to be updated only for one language
if ( ! $headerFileUpdated ) {
2021-12-18 10:15:31 +08:00
$lineInHeaderFormat = " #define IDS_ " + $entry . name . ToUpper ( $culture ) + " " + $count . ToString ( )
2020-08-25 06:10:50 +08:00
$newLinesForHeaderFile = $newLinesForHeaderFile + " `r `n " + $lineInHeaderFormat
$count + +
}
}
}
catch {
2021-12-18 10:15:31 +08:00
echo " Failed to read XML document. "
2020-08-25 06:10:50 +08:00
exit 0
}
2022-07-01 04:10:14 +08:00
if ( $newLinesForRCFile -ne " " ) {
# Add string table syntax
$newLinesForRCFile = " `r `n STRINGTABLE `r `n BEGIN " + $newLinesForRCFile + " `r `n END "
2020-08-25 06:10:50 +08:00
2022-07-01 04:10:14 +08:00
$langStart = " `r `n ///////////////////////////////////////////////////////////////////////////// `r `n // " + $langData [ 3 ] + " resources `r `n `r `n "
$langStart + = " #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ " + $langData [ 0 ] + " ) `r `n LANGUAGE LANG_ " + $langData [ 1 ] + " , SUBLANG_ " + $langData [ 2 ] + " `r `n "
2020-08-25 06:10:50 +08:00
2022-07-01 04:10:14 +08:00
$langEnd = " `r `n `r `n #endif // " + $langData [ 3 ] + " resources `r `n ///////////////////////////////////////////////////////////////////////////// `r `n "
2020-08-25 06:10:50 +08:00
2022-07-01 04:10:14 +08:00
$newLinesForRCFile = $langStart + $newLinesForRCFile + $langEnd
}
2020-08-25 06:10:50 +08:00
# Initialize the rc file with an auto-generation warning and content from the base rc
if ( ! $rcFileUpdated ) {
$rcFileContent = " // This file was auto-generated. Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. `r `n "
try {
$rcFileContent + = ( Get-Content $parentDirectory \ $baseRCFileName -Raw )
}
catch {
echo " Failed to read base rc file. "
exit 0
}
$rcFileUpdated = $true
}
# Add in the new string table to the rc file
$rcFileContent + = $newLinesForRCFile
# Resource header file needs to be set only once, with an auto-generation warning, content from the base resource header followed by #define for all the resources
if ( ! $headerFileUpdated ) {
$headerFileContent = " // This file was auto-generated. Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. `r `n "
try {
$headerFileContent + = ( Get-Content $parentDirectory \ $baseHeaderFileName -Raw )
}
catch {
echo " Failed to read base header file. "
exit 0
}
$headerFileContent + = $newLinesForHeaderFile
$headerFileUpdated = $true
}
}
# Write to header file if the content has changed or if the file doesnt exist
try {
if ( ! ( Test-Path -Path $generatedFilesFolder \ $generatedHeaderFileName ) -or ( ( $headerFileContent + " `r `n " ) -ne ( Get-Content $generatedFilesFolder \ $generatedHeaderFileName -Raw ) ) ) {
Set-Content -Path $generatedFilesFolder \ $generatedHeaderFileName -Value $headerFileContent
}
else {
2020-09-11 02:09:04 +08:00
# echo "Skipping write to generated header file"
2020-08-25 06:10:50 +08:00
}
}
catch {
echo " Failed to access generated header file. "
exit 0
}
# Write to rc file if the content has changed or if the file doesnt exist
try {
if ( ! ( Test-Path -Path $generatedFilesFolder \ $generatedRCFileName ) -or ( ( $rcFileContent + " `r `n " ) -ne ( Get-Content $generatedFilesFolder \ $generatedRCFileName -Raw ) ) ) {
Set-Content -Path $generatedFilesFolder \ $generatedRCFileName -Value $rcFileContent -Encoding unicode
}
else {
2020-09-11 02:09:04 +08:00
# echo "Skipping write to generated rc file"
2020-08-25 06:10:50 +08:00
}
}
catch {
echo " Failed to access generated rc file. "
exit 0
}