ContributionGuidelines.md and API Commands

Homes32
2022-05-14 08:03:12 -05:00
parent 711341516d
commit 04bf638b9e
40 changed files with 1900 additions and 0 deletions

21
ContributionGuidelines.md Normal file

@@ -0,0 +1,21 @@
## Contributing
Contributions are welcome and encouraged, provided your code is of sufficient quality. Before submitting a pull request, please ensure your code adheres to the following requirements:
1. Licensed under MIT, BSD or compatible license, or dedicated to the public domain
1. KISS (Keep It Simple Stupid). Your script should have 1 job and do it well. Keep the User Interface clean and simple. Only include options that will benefit the majority of users. Trying to cram in every conceivable option is not only confusing, it clutters the script interface, and it makes the code more difficult to test and maintain as well.
1. Runs cleanly with no warnings
1. Encoding should be UTF-8/UTF-16
1. Uses 2-spaces for code blocks & indentation
1. Uses descriptive function and variable names in the **P**ascal**C**ase convention
1. Avoids the use of `Not` and uses positive conditionals wherever possible (e.g. `If,%foo%,Equal,0` instead of `If,Not,%foo%,Equal,1`)
1. Uses common sense when it comes to embedded files. **Do not embed files or licensed software you do not have permission to distribute**. Do not create .script "container files" that only contain attachments; if your running into performance issues with attachment size use a standalone .7z file instead. Where possible downloading the files and caching them is preferred.
1. Does not use section parameters (#1, #2 , #9, etc.) as temporary variables for storing values. If you need temporary variables use `SetLocal` and declare an actual variable. If you need more then 1 section parameter please use `GetParam` and assign each parameter to a variable, as this makes the code much easier to read.
Your pull request should fully describe the functionality you are adding/removing or the problem you are solving. Regardless of whether your patch modifies one line or one thousand lines, you must describe what has prompted and/or motivated the change.
Solve only one problem in each pull request. If you're fixing a bug and adding a new feature, you need to make two separate pull requests. If you're fixing three bugs, you need to make three separate pull requests. If you're adding four new features, you need to make four separate pull requests. So on, and so forth.
If your patch fixes a bug, please be sure there is an [issue](https://github.com/PhoenixPE/PhoenixPE/issues) open for the bug before submitting a pull request. If your patch aims to improve performance or optimize a process, be sure to quantify your optimizations and document the trade-offs, and back up your claims with benchmarks and metrics.
In order to maintain the quality and integrity of the **PhoenixPE** source tree, all pull requests must be reviewed before being merged. The [project lead](https://github.com/Homes32) has the ultimate authority in deciding whether to accept or reject a pull request. Do not be discouraged if your pull request is rejected!

45
PhoenixAPI/7z.md Normal file

@@ -0,0 +1,45 @@
# 7z
Execute 7zip with the provided arguments.
This command is a wrapper for 7z.exe and passes any arguments directly to the executable.
Generally speaking PEBakery's builtin `Decompress` command works best for archives, such as 7z/zip/rar/etc. however extracting from self-extracting .exe and installers such as NSIS don't work. Use the `7z` command to extract these files directly with 7zip.
## Syntax
```pebakery
7z,<Args>[,<WorkDir>]
```
### Arguments
| Argument | Description |
| --- | --- |
| Args | The arguments to pass to the 7z executable. |
| WorkDir | The full path to the working directory. Default is the exe path. |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | ExitCode provided by the 7zip application. |
## Remarks
Make sure to escape double-quotes, percent, etc. in Args.
See the 7zip documentation for more details on 7z.exe arguments.
## Related
## Examples
### Example 1
```pebakery
Echo,"Extracting %ScriptTitle%..."
7z,"e -y -r- #$q%ProgramsCache%\%ProgramFolder%\WinPE.zip#$q Files\auto_reactivate64.bin Files\bootwiz64.efi -o#$q%TargetPrograms%\%ProgramFolder%\#$q"
If,Not,#r,Equal,0,Halt,"Error: Failed to extract [WinPE.zip]."
```

50
PhoenixAPI/AddAutoRun.md Normal file

@@ -0,0 +1,50 @@
# AddAutoRun
Run a program when the PE Environment starts.
## Syntax
```pebakery
AddAutoRun,<RunGroup>,<Mode>,<Title>,<ProgramExe>,[Parameters]
```
### Arguments
| Argument | Description |
| --- | --- |
| RunGroup | One of the following: |
|| `PreShell` - Run before the shell (ie. Explorer) is loaded. |
|| `PostShell` - Run after the shell is loaded. |
|| `RunOnce` - Run during startup via HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce |
|| `AfterNetwork` - Run after network connectivity has been established by PENetwork. |
| Mode | One of the following: |
|| `NoWait` - Do not wait for the program to terminate. |
|| `Wait` - Wait for the program to terminate before moving on. |
|| `HideNoWait` - Run the program hidden and do not wait for it to terminate. |
|| `HideWait` - Run the program hidden and wait for it to terminate. |
| Title | Text that may be shown in a progress window while the program is running. May be left blank. |
| ProgramExe | The full path to the program to be executed. |
| Parameters | (Optional) Parameters that will be passed to the program. |
## Return Codes
None.
## Remarks
None.
## Related
## Examples
### Example 1
Run a program on startup.
```pebakery
AddAutorun,PostShell,NoWait,"Starting %ScriptTitle%...","%PEPrograms%\%ProgramFolder%\%ProgramExe%"
```

@@ -0,0 +1,51 @@
# PinShortcut
Define a section to process during Build Post-Process.
## Syntax
```pebakery
AddPostProcess,<Script>,<Section>
```
### Arguments
| Argument | Description |
| --- | --- |
| Script | The full path to the script containing the section to process. |
| Section | The name of the section to process. |
## Return Codes
None.
## Remarks
This command adds EXEC entries to %ProjectTemp%\PostProcessCommands.script
The %ProjectTemp%\PostProcessCommands.script is run at the end of a build process, right before the .wim file captured.
It can be useful to run commands at the end of the build that may depend on the result of scripts that have not run at the time of the calling script.
## Related
## Examples
### Example 1
In the following example the `PostProcess-PatchOpenShell` section will be executed at the end of the project build. This is useful because at the time this script is processing the Open-Shell script has not processed, so StartMenu.exe will not be extracted until later in the build.
```pebakery
[Process]
AddPostProcess,%ScriptFile%,PostProcess-PatchOpenShell
[PostProcess-PatchOpenShell]
Echo,"Patch Open-Shell Menu..."
RunFromRam
Set,%StrExplorer%,"65 00 78 00 70 00 6C 00 6F 00 72 00 65 00 72 00 2E 00 65 00 78 00 65 00 00 00 00 00"
Set,%StrWinXShell%,"57 00 69 00 6E 00 58 00 53 00 68 00 65 00 6C 00 6C 00 2E 00 65 00 78 00 65 00 00 00"
ShellExecute,Hide,"%Tools%\%HostArch%\binmay.exe","-u #$q%TargetPrograms%\Open-Shell\StartMenu.exe#$q -s #$q%StrExplorer%#$q -r #$q%StrWinXShell%#$q"
```

87
PhoenixAPI/AddShortcut.md Normal file

@@ -0,0 +1,87 @@
# AddShortcut
Create Shortcuts for programs in PE.
## Syntax
```pebakery
AddShortcut,<Type>,<StartMenuFolder>,<Title>,<PathProgramExe>,[Parameters],[WorkDir],[IconPath],[IconIndex],[State],[Hotkey],[Tooltip]
```
### Arguments
Arguments marked as _(Optional)_ must be specified if there are succeeding arguments.
| Argument | Description |
| --- | --- |
| Type | One of the following: |
|| `Desktop` - The shortcut will be created on the desktop. |
|| `StartMenu` - The shortcut will be created in the start menu. |
|| `QuickLaunch` - The shortcut will be created in the Quick Launch folder. (Used by WinXShell) |
| StartMenuFolder | The name of the start menu folder where the shortcut will be created. |
| Title | The name of the shortcut. |
| ProgramExe | The full path to the program to be executed. |
| Parameters | (Optional) Parameters that will be passed to the program. |
| WorkDir | (Optional) The work directory for the program. |
| IconPath | (Optional) The full path to file containing the icon. |
| IconIndex | (Optional) For files containing multiple icons this is Index of the icon to use. |
| WindowState | (Optional) One of the following: |
|| `Normal` - Start the program normally. |
|| `Minimized` - Start the program minimized to the taskbar. |
|| `Maximized` - Start the program maximized. |
| Hotkey | (Optional) Keyboard sequence used to active the shortcut. `Ctrl + Alt <Letter>`|
| Tooltip | (Optional) Tooltip Text. |
## Return Codes
None.
## Remarks
None.
## Related
[PinShortcut](./PinShortcut.md)
## Examples
### Example 1
Simple desktop shortcut creation
```pebakery
AddShortcut,Desktop,,"Launch myProgram","C:\myProgram.exe"
```
### Example 2
Simple start menu shortcut creation
```pebakery
AddShortcut,StartMenu,"someFolder","Launch myProgram","C:\myProgram.exe"
```
### Example 3
Advanced start menu example calling a commandline sequence and selecting the shortcut icon from a .dll file.
```pebakery
AddShortcut,StartMenu,%txt_StartMenuFolder_InitNetwork%,%txt_ShortcutName_InitNetwork%,"cmd.exe","/C @Echo InitializeNetwork... & wpeutil.exe InitializeNetwork & pause",,"#$pSystemRoot#$p\system32\imageres.dll",170,,,"Initialize Network Settings"
```
### Example 4
Advanced start menu example, all parameters.
```pebakery
AddShortcut,StartMenu,"System","ImDisk Control Panel","#$pWinDir#$p\System32\imdisk.cpl","","#$pWinDir#$p","%WinDir%\System32\imdisk.cpl",-1,Minimized,"Ctrl + Alt + I","Configure Imdisk"
```

@@ -0,0 +1,52 @@
# ApplyBitMask
Apply a bitmask to a hex value in a binary string.
## Syntax
```pebakery
ApplyBitMask,<BitArray>,<BitGroup>,<BitMask>[,BitSize]
```
### Arguments
| Argument | Description |
| --- | --- |
| BitArray | A comma separated string of bits in hex format. |
| BitGroup | The specific group of bits to manipulate. This is determined by the 1-based index of the bit group supplied by _BitArray_. **Example:** In order to apply a mask to the value `DB` in `01,DB,1A,4C` we would specify a _BitGroup_ of `2`. |
| BitMask | The hexadecimal bitmask to apply to the specified _BitGroup_. Ex. 0x000020 |
| BitSize | (Optional) Specify the bitsize (8,16,32,64) used. **Default is 32.** |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | Returns _BitArray_ with the specified bitmask applied. |
## Remarks
None.
## Related
[BitClear](./BitClear.md), [BitSet](./BitSet.md), [BitToggle](./BitToggle.md)
## Examples
### Example 1
```pebakery
[Main]
Title=ApplyBitMask Example
Description=Show usage of the ApplyBitMask Command
Author=Homes32
Level=5
Version=1
[Process]
ApplyBitMask,%PrefMask%,6,0x000001,8
```

38
PhoenixAPI/Associate.md Normal file

@@ -0,0 +1,38 @@
# Associate
Associate a file extension with a program.
## Syntax
```pebakery
Associate,<FileExtension>,<ProgramExe>
```
### Arguments
| Argument | Description |
| --- | --- |
| FileExtension | The file extension to associate. |
| ProgramExe | The full path to the executable to which the file extension will be associated with. |
## Return Codes
None.
## Remarks
This command will automatically load/unload any registry hives needed provided they are not already loaded. If the hives are already loaded they will not be unloaded.
## Related
## Examples
### Example 1
Associate the `.ini` file extension with _notepad.exe_.
```pebakery
Associate,.ini,"C:\Windows\System32\notepad.exe"
```

56
PhoenixAPI/BitClear.md Normal file

@@ -0,0 +1,56 @@
# BitClear
Clear a specific bit in a binary string.
## Syntax
```pebakery
BitClear,<BitArray>,<BitGroup>,<BitPosition>[,BitSize]
```
### Arguments
| Argument | Description |
| --- | --- |
| BitArray | A comma separated string of bits in hex format. |
| BitGroup | The specific group of bits to manipulate. This is determined by the 1-based index of the bit group supplied by _BitArray_. **Example:** In order to clear a bit in the value `DB` in `01,DB,1A,4C` we would specify a _BitGroup_ of `2`. |
| BitPosition | The binary position to modify. (0-based Right to Left) |
| BitSize | (Optional) Specify the bitsize (8,16,32,64) used. **Default is 32.** |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | Returns _BitArray_ with the specified bit cleared. |
## Remarks
None.
## Related
[ApplyBitMask](./ApplyBitMask.md), [BitSet](./BitSet.md), [BitToggle](./BitToggle.md)
## Examples
### Example 1
Clear bit _0_ in the 8bit group _5_ of the array `90,01,00,00,65,00,00,00,64,00`
```pebakery
[Main]
Title=BitClear Example
Description=Show usage of the BitClear Command
Author=Homes32
Level=5
Version=1
[Variables]
%ProgramSettings%=90,01,00,00,65,00,00,00,64,00
[Process]
BitClear,%ProgramSettings%,5,0,8
```
Result: `90,01,00,00,64,00,00,00,64,00`

56
PhoenixAPI/BitSet.md Normal file

@@ -0,0 +1,56 @@
# BitSet
Set a specific bit in a binary string.
## Syntax
```pebakery
BitSet,<BitArray>,<BitGroup>,<BitPosition>[,BitSize]
```
### Arguments
| Argument | Description |
| --- | --- |
| BitArray | A comma separated string of bits in hex format. |
| BitGroup | The specific group of bits to manipulate. This is determined by the 1-based index of the bit group supplied by _BitArray_. **Example:** In order to set a a bit in value `DB` in `01,DB,1A,4C` we would specify a _BitGroup_ of `2`. |
| BitPosition | The binary position to modify. (0-based Right to Left) |
| BitSize | (Optional) Specify the bitsize (8,16,32,64) used. **Default is 32.** |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | Returns _BitArray_ with the specified bit set. |
## Remarks
None.
## Related
[ApplyBitMask](./ApplyBitMask.md), [BitClear](./BitClear.md), [BitToggle](./BitToggle.md)
## Examples
### Example 1
Set bit _0_ in the 8bit group _5_ of the array `90,01,00,00,64,00,00,00,64,00`
```pebakery
[Main]
Title=BitSet Example
Description=Show usage of the BitSet Command
Author=Homes32
Level=5
Version=1
[Variables]
%ProgramSettings%=90,01,00,00,64,00,00,00,64,00
[Process]
BitClear,%ProgramSettings%,5,0,8
```
Result: `90,01,00,00,65,00,00,00,64,00`

57
PhoenixAPI/BitToggle.md Normal file

@@ -0,0 +1,57 @@
# BitToggle
Set/Clear a specific bit in a binary string.
## Syntax
```pebakery
BitToggle,<BitArray>,<BitGroup>,<BitPosition>[,BitSize]
```
### Arguments
| Argument | Description |
| --- | --- |
| BitArray | A comma separated string of bits in hex format. |
| BitGroup | The specific group of bits to manipulate. This is determined by the 1-based index of the bit group supplied by _BitArray_. **Example:** In order to toggle a bit in the value `DB` in `01,DB,1A,4C` we would specify a _BitGroup_ of `2`. |
| BitPosition | The binary position to modify. (0-based Right to Left) |
| BitSize | (Optional) Specify the bitsize (8,16,32,64) used. **Default is 32.** |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | Returns _BitArray_ with the specified bit flipped. |
## Remarks
None.
## Related
[ApplyBitMask](./ApplyBitMask.md), [BitClear](./BitClear.md), [BitSet](./BitSet.md)
## Examples
### Example 1
Toggle bit _0_ in the 8bit group _5_ of the array `90,01,00,00,64,00,00,00,64,00`
```pebakery
[Main]
Title=BitToggle Example
Description=Show usage of the BitToggle Command
Author=Homes32
Level=5
Version=1
[Variables]
%ProgramSettings%=90,01,00,00,64,00,00,00,64,00
[Process]
BitClear,%ProgramSettings%,5,0,8
```
Result: `90,01,00,00,65,00,00,00,64,00`

@@ -0,0 +1,39 @@
# ConvertImage
Convert an image (jpg/png/etc.) to another format.
## Syntax
```pebakery
ConvertImage,<Source>,<Target>[,<Resize>]
```
### Arguments
| Argument | Description |
| --- | --- |
| Source | The full path to the image file. |
| Target | The full path to the converted image file. |
| Resize | (Optional) Resize the image. |
## Return Codes
None.
## Remarks
If image conversion fails the build will halt.
## Related
## Examples
### Example 1
Convert an image from .png to .bmp and resize it to 120x120
```pebakery
ConvertImage,"C:\myLogo.png","%TargetSystem32%\OEMLogo.bmp",120x120
```

54
PhoenixAPI/DISM.md Normal file

@@ -0,0 +1,54 @@
# DISM
Execute DISM with the provided arguments.
This command is a wrapper for dism.exe and passes any arguments directly to the executable.
This command is provided as compatibility shim to allow using DISM on Win10 images from a Win7 Host.
## Syntax
```pebakery
DISM,<Args>[,<WorkDir>]
```
### Arguments
| Argument | Description |
| --- | --- |
| Args | The arguments to pass to the DISM executable. |
| WorkDir | The full path to the working directory. Default is the exe path. |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | ExitCode provided by the DISM application. |
## Remarks
Make sure to escape double-quotes, percent, etc. in Args.
See the DISM documentation or `DISM /?` for more details on dism.exe arguments.
The version of DISM provided with Win7 does not recognize Win10 imagines when using the `/image:` argument.
In order to work around this limitation and allow DISM operations (Localization, driver integration, etc) on Win7 we use DISM from Win10 AIK tools, downloaded using JFX's GetWaikTools.exe during Pre-Flight Check.
* Win10+ - Executes DISM.exe from the HostOS
* Win7/8 - Executes Win10 AIK DISM.exe
Eventually GetWaikTools will no longer be able to download an AIK that works on Win7, at which time it will no longer be possible to build PhoenixPE on Win7. What do you expect running an unsupported OS? ;-)
## Related
## Examples
### Example 1
```pebakery
Echo,"Run DISM..."
DISM,"/image:#$q%MountDir%#$q /Disable-Feature /FeatureName:NetFx3 /LogPath:#$q%DismLog%#$q"
If,Not,#r,Equal,0,Halt,"Error: Failed to extract [WinPE.zip]."
```

39
PhoenixAPI/DirDeleteEx.md Normal file

@@ -0,0 +1,39 @@
# DirDeleteEx
Delete a directory if it exists.
If the DirDelete commands fails, for example if a file or folder is open in another application or Explorer then give the user a meaningful error message and a chance to correct the problem.
## Syntax
```pebakery
DirDeleteEx,<Directory>
```
### Arguments
| Argument | Description |
| --- | --- |
| Directory | The full path to the directory to delete. |
## Return Codes
None.
## Remarks
If the command fails the build will halt.
## Related
[FileDeleteEx](./FileDeleteEx.md)
## Examples
### Example 1
```pebakery
DirDeleteEx,"C:\Temp"
```

36
PhoenixAPI/FileCopyEx.md Normal file

@@ -0,0 +1,36 @@
# FileCopyEx
Copy a single file and it's .mui/mun files (if they exist) from a specified directory.
## Syntax
```pebakery
FileCopyEx,<SourcePath>,<DestPath>
```
### Arguments
| Argument | Description |
| --- | --- |
| SourcePath | Full path to the source file to copy. **Wildcards are NOT supported.** |
| DestPath | Full path to the destination. |
## Return Codes
None.
## Remarks
If the command fails the build will halt.
## Related
## Examples
### Example 1
```pebakery
FileCopyEx,"%TargetDir%\Windows\Boot\PXE\bootmgr.exe","%OutputDir%\boot\"
```

@@ -0,0 +1,39 @@
# FileDeleteEx
Delete a file if it exists.
If the DirDelete commands fails, for example if a file is open in another application or Explorer then give the user a meaningful error message and a chance to correct the problem.
## Syntax
```pebakery
DirDeleteEx,<File>
```
### Arguments
| Argument | Description |
| --- | --- |
| File | The full path to the file to delete. |
## Return Codes
None.
## Remarks
If the command fails the build will halt.
## Related
[DirDeleteEx](./DirDeleteEx.md)
## Examples
### Example 1
```pebakery
FileDeleteEx,"C:\Temp\someFile.ini"
```

44
PhoenixAPI/InnoCleanup.md Normal file

@@ -0,0 +1,44 @@
# InnoCleanup
Cleanup extracted Inno Setup files.
## Syntax
```pebakery
InnoCleanup,<Path>,<Filter>[,NOREC]
```
### Arguments
Optional arguments may be specified in any order.
| Argument | Description |
| --- | --- |
| Path | The full path to the extracted InnoSetup Files. |
| Filter | Comma delimited list of file types to include. eg. *.dll,*.exe |
| NOREC | (Optional) Do not recurse sub-directories. |
## Return Codes
None.
## Remarks
An Inno Setup installer may contain several identical files (possibly under different names). Inno Setup stores only one copy of such files, so identical files are unpacked with an incremental suffix eg. myfile,1.exe myfile,2.exe myfile,3.exe etc.
If the installer contains files for multiple processor architectures, you will need to determine which suffix is used for the architecture you are interested in. This can be accomplished with tools such as exeinfope or CFF Explorer. Note that sub-folders may use a different suffix then the parent folder for the same architecture.
You can use the InnoCleanup command to bulk remove files that you have not renamed with the InnoRename command. Once this has been accomplished you can then copy the entire directory or groups of files, instead of having to copy and rename each file individually.
## Related
[InnoExtract](./InnExtract.md), [Innounp](./Innounp.md), [InnoRename](./InnoRename.md)
## Examples
### Example 1
```pebakery
InnoCleanup,"%ProjectTemp%\%ProgramFolder%\{app}","*.dll,*.exe,*.sys"
```

66
PhoenixAPI/InnoExtract.md Normal file

@@ -0,0 +1,66 @@
# InnoExtract
Extract files from an Inno Setup installer.
## Syntax
```pebakery
InnoExtract,<SetupFile>,<DestDir>[,<Args>]
```
### Arguments
Optional arguments may be specified in any order.
| Argument | Description |
| --- | --- |
| SetupFile | The inno-setup file to unpack. |
| DestDir | The full path to the directory where the files will be unpacked. |
| PASSWORD=<Password> | Password required to decrypt the setup file. (-p) |
| CDIR=<CurrentDir> | Notifies innounp that you are only interested in paths from the current directory and below. (-c) |
| LIST=<FileList.txt> | Instructs innounp to use a list file to determine the files to extract (@listfile) |
## Return Codes
None.
## Remarks
If unpacking fails the build will halt.
## Related
[InnoCleanup](./InnoCleanup.md), [Innounp](./Innounp.md), [InnoRename](./InnoRename.md)
## Examples
### Example 1
```pebakery
Echo,"Extracting %ScriptTitle%..."
InnoExtract,"%ProgramsCache%\%ProgramFolder%\Setup.exe","%ProjectTemp%\%ProgramFolder%"
```
### Example 2
Unpack a password protected setup file.
```pebakery
Echo,"Extracting %ScriptTitle%..."
InnoExtract,"%ProgramsCache%\%ProgramFolder%\Setup.exe","%ProjectTemp%\%ProgramFolder%",PASSWORD=1234
```
### Example 3
Unpack only files from the _{app}_ directory of a setup file.
```pebakery
Echo,"Extracting %ScriptTitle%..."
InnoExtract,"%ProgramsCache%\%ProgramFolder%\Setup.exe","%ProjectTemp%\%ProgramFolder%",CDIR=#$q{app}\#$q
```

57
PhoenixAPI/InnoRename.md Normal file

@@ -0,0 +1,57 @@
# InnoRename
Rename extracted Inno Setup files.
## Syntax
```pebakery
InnoRename,<Path>,<Filter>,<Suffix>[,NOREC]
```
### Arguments
Optional arguments may be specified in any order.
| Argument | Description |
| --- | --- |
| Path | The full path to the extracted InnoSetup Files. |
| Filter | Comma delimited list of file types to include. eg. *.dll,*.exe |
| Suffix | A number representing the group of files to process. eg. `1` |
| NOREC | (Optional) Do not recurse sub-directories. |
## Return Codes
None.
## Remarks
An Inno Setup installer may contain several identical files (possibly under different names). Inno Setup stores only one copy of such files, so identical files are unpacked with an incremental suffix eg. myfile,1.exe myfile,2.exe myfile,3.exe etc.
If the installer contains files for multiple processor architectures, you will need to determine which suffix is used for the architecture you are interested in. This can be accomplished with tools such as exeinfope or CFF Explorer. Note that sub-folders may use a different suffix then the parent folder for the same architecture.
You can use the InnoRename command to bulk rename the files with the suffix you want and remove the others with the InnoCleanup command. Once this has been accomplished you can then copy the entire directory or groups of files, instead of having to copy and rename each file individually.
## Related
[InnoCleanup](./InnoCleanup.md), [InnoExtract](./InnoExtract.md), [Innounp](./Innounp.md)
## Examples
### Example 1
```pebakery
// Sort out Arch Specific files
If,%SourceArch%,Equal,x64,Begin
InnoRename,"%ProjectTemp%\%ProgramFolder%\{app}","*.dll",1
InnoRename,"%ProjectTemp%\%ProgramFolder%\{app}","*.exe,*.sys",2
End
Else,Begin
// x86
InnoRename,"%ProjectTemp%\%ProgramFolder%\{app}","*.dll",2
InnoRename,"%ProjectTemp%\%ProgramFolder%\{app}","*.exe,*.sys",1
End
// cleanup any leftover files
InnoCleanup,"%ProjectTemp%\%ProgramFolder%\{app}","*.dll,*.exe,*.sys"
```

48
PhoenixAPI/Innounp.md Normal file

@@ -0,0 +1,48 @@
# Innounp
Execute Innounp (Inno Setup Unpacker) with the provided arguments.
This command is a wrapper for Innounp.exe and passes any arguments directly to the executable.
You are responsible for checking the return code and handling any errors.
Unless you need advanced features such extracting using a @filelist or filemask it is recommended to use the InnoExtract macro instead.
## Syntax
```pebakery
Innounp,<Args>[,<WorkDir>]
```
### Arguments
| Argument | Description |
| --- | --- |
| Args | The arguments to pass to the Innounp executable. |
| WorkDir | The full path to the working directory. Default is the exe path. |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | ExitCode provided by the Innounp application. |
## Remarks
Make sure to escape double-quotes, percent, etc. in Args.
See the Innounp documentation for more details on innounp.exe arguments.
## Related
[InnoExtract](./InnoExtract.md)
## Examples
### Example 1
```pebakery
Echo,"Extracting %ScriptTitle%..."
Innounp,"-x -b -a -d#$q%TargetPrograms%\%ProgramFolder%#$q -c#$q{app}\Winpe64\#$q #$q%ProgramsCache%\%ProgramFolder%\%SetupFile%#$q {app}\Winpe64\*.*"
If,Not,#r,Equal,0,Halt,"Error: Failed to extract [%SetupFile%]."
```

37
PhoenixAPI/JSONCompact.md Normal file

@@ -0,0 +1,37 @@
# JSONCompact
Compact a JSON value.
## Syntax
```pebakery
JSONCompact,<JSONFile>
```
### Arguments
| Argument | Description |
| --- | --- |
| JSONFile | Full path to the JSON filed to edit. |
## Return Codes
None.
## Remarks
None.
## Related
[JSONDelete](./JSONDelete.md), [JSONPretty](./JSONPretty.md), [JSONRead](./JSONRead.md), [JSONWrite](./JSONWrite.md)
## Examples
### Example 1
```pebakery
JSONCompact,"C:\Temp\Test.json"
```

38
PhoenixAPI/JSONDelete.md Normal file

@@ -0,0 +1,38 @@
# JSONDelete
Delete a JSON value.
## Syntax
```pebakery
JSONDelete,<JSONFile>,<Path>
```
### Arguments
| Argument | Description |
| --- | --- |
| JSONFile | Full path to the JSON filed to edit. |
| Path | GJSON Path notation used to locate the value to delete. |
## Return Codes
None.
## Remarks
For help with GJSON Path Notation see [Path Syntax Help](https://github.com/tidwall/gjson/blob/master/SYNTAX.md).
## Related
[JSONCompact](./JSONCompact.md), [JSONPretty](./JSONPretty.md), [JSONRead](./JSONRead.md), [JSONWrite](./JSONWrite.md)
## Examples
### Example 1
```pebakery
JSONDelete,"C:\Temp\Test.json","JS_FILEEXPLORER.4th_filename"
```

37
PhoenixAPI/JSONPretty.md Normal file

@@ -0,0 +1,37 @@
# JSONPretty
Format and indent the JSON file for easy human reading.
## Syntax
```pebakery
JSONPretty,<JSONFile>
```
### Arguments
| Argument | Description |
| --- | --- |
| JSONFile | Full path to the JSON filed to format. |
## Return Codes
None.
## Remarks
None.
## Related
[JSONCompact](./JSONCompact.md), [JSONDelete](./JSONDelete.md), [JSONRead](./JSONRead.md), [JSONWrite](./JSONWrite.md)
## Examples
### Example 1
```pebakery
JSONPretty,"C:\Temp\Test.json"
```

42
PhoenixAPI/JSONRead.md Normal file

@@ -0,0 +1,42 @@
# JSONRead
Read a JSON value.
## Syntax
```pebakery
JSONRead,<JSONFile>,<Path>
```
### Arguments
| Argument | Description |
| --- | --- |
| JSONFile | Full path to the JSON filed to read. |
| Path | GJSON Path notation used to locate the value to read. |
## Return Codes
| Token | Description |
| --- | --- |
| #r | Returns the value of <Path> |
## Remarks
For help with GJSON Path Notation see [Path Syntax Help](https://github.com/tidwall/gjson/blob/master/SYNTAX.md).
## Related
[JSONCompact](./JSONCompact.md), [JSONDelete](./JSONDelete.md), [JSONPretty](./JSONPretty.md), [JSONWrite](./JSONWrite.md)
## Examples
### Example 1
```pebakery
JSONRead,"C:\Temp\Test.json","JS_FILEEXPLORER.4th_filename"
Set,%Value%,#r
Message,Return [%Value%]
```

39
PhoenixAPI/JSONWrite.md Normal file

@@ -0,0 +1,39 @@
# JSONWrite
Set/Modify an JSON value.
## Syntax
```pebakery
JSONWrite,<JSONFile>,<Path>,<Value>
```
### Arguments
| Argument | Description |
| --- | --- |
| JSONFile | Full path to the JSON filed to read. |
| Path | GJSON Path notation used to locate the value to read. |
| Value | The value to write. |
## Return Codes
None.
## Remarks
For help with GJSON Path Notation see [Path Syntax Help](https://github.com/tidwall/gjson/blob/master/SYNTAX.md).
## Related
[JSONCompact](./JSONCompact.md), [JSONDelete](./JSONDelete.md), [JSONPretty](./JSONPretty.md), [JSONWrite](./JSONWrite.md)
## Examples
### Example 1
```pebakery
JSONWrite,"C:\Temp\Test.json","JS_FILEEXPLORER.4th_filename","explorer++.exe"
```

39
PhoenixAPI/MSIExtract.md Normal file

@@ -0,0 +1,39 @@
# MSIExtract
Extract files from an .msi installer.
## Syntax
```pebakery
MSIExtract,<SetupFile>,<DestDir>
```
### Arguments
Optional arguments may be specified in any order.
| Argument | Description |
| --- | --- |
| SetupFile | The .msi file to unpack. |
| DestDir | The full path to the directory where the files will be unpacked. |
## Return Codes
None.
## Remarks
If unpacking fails the build will halt.
## Related
## Examples
### Example 1
```pebakery
Echo,"Extracting %ScriptTitle%..."
MSIExtract,"%ProgramsCache%\%ProgramFolder%\Setup.exe","%ProjectTemp%\%ProgramFolder%"
```

56
PhoenixAPI/PinShortcut.md Normal file

@@ -0,0 +1,56 @@
# PinShortcut
Pin a shortcut to the taskbar or start menu.
## Syntax
```pebakery
PinShortcut,<Location>,<Position>,<ProgramExe>
```
### Arguments
| Argument | Description |
| --- | --- |
| Location | One of the following: |
|| `StartMenu` - Pin to the start menu. |
|| `Taskbar` - Pin to the taskbar. |
| Position | One of the following: |
|| `Auto` - (Default) Automatically determine the pin position. |
|| `0-99` - Pin the shortcut to a specific position [0-99]. |
| ProgramExe | The full path to the program to be executed. |
## Return Codes
None.
## Remarks
### Programs located on removable media ###
Normally Windows does not allow Pins to target an executable located on removable media (CD/DVD/USB). To get around this restriction we trick Windows by creating a symlink on the RamdDive (B:\) to the _Y:\Programs_ folder. Consequently, this requires that the build have the RamDrive enabled, or the Pin operation will fail. If you don't want to enable the RamDrive and still want to Pin a program you must set your program to `RunFromRam`.
## Related
[AddShortcut](./AddShortcut.md)
## Examples
### Example 1
Pin an application to the taskbar in the first unused position.
```pebakery
PinShortcut,Taskbar,Auto,"%PEPrograms%\%ProgramFolder%\%ProgramExe%"
```
### Example 2
Pin an application to the taskbar in position #1.
```pebakery
PinShortcut,StartMenu,0,"#$pwindir#$p\Explorer.exe"
```

@@ -0,0 +1,44 @@
# RegCopyDriver
Copy the driver entries from the INSTALL.WIM driver database to the target registry driver database.
Both the DRIVERS hive and SYSTEM\Drivers store are processed.
## Syntax
```pebakery
RegCopyDriver,<filename.inf>
```
### Arguments
| Argument | Description |
| --- | --- |
| InfFile | The name of the driver's .inf file. |
## Return Codes
None.
## Remarks
Registry hives Tmp_Install_Drivers, Tmp_Install_System, Tmp_Drivers, Tmp_System must be loaded before calling.
## Related
[RequireDriver](./RequireDriver.md), [RegLoadHives](./RegLoadHives.md), [RegUnLoadHives](./RegUnLoadHives.md)
## Examples
### Example 1
```pebakery
Echo,"Configuring %ScriptTitle%..."
RegLoadHives
RegCopyDriver,display.inf
RegCopyDriver,displayoverride.inf
RegUnloadHives
```

@@ -0,0 +1,55 @@
# RegLoadHives
Mount Source and Build registry hives.
After running this command the following registry hives will be mounted under HKLM as:
| Argument | Description |
| --- | --- |
| Tmp_Default | The WinPE `DEFAULT` (HKCU) hive. |
| Tmp_Drivers | The WinPE `DRIVERS` hive. |
| Tmp_Software | The WinPE `SOFTWARE` (HKLM\Software) hive. |
| Tmp_System | The WinPE `SYSTEM` (HKLM\System) hive. |
| Tmp_Install_Default | The source Install.wim `DEFAULT` (HKCU) hive. |
| Tmp_Install_Drivers | The sourceInstall.wim `DRIVERS` hive. |
| Tmp_Install_Software | The sourceInstall.wim `SOFTWARE` (HKLM\Software) hive. |
| Tmp_Install_System | The source Install.wim `SYSTEM` (HKLM\System) hive. |
## Syntax
```pebakery
RegLoadHives
```
### Arguments
None.
## Return Codes
None.
## Remarks
It is recommended to use `RegUnloadHives` to unload hives loaded by this command.
## Related
[RegUnloadHives](./RegUnloadHives.md)
## Examples
### Example 1
```pebakery
Echo,"Configuring %ScriptTitle%..."
RegLoadHives
RegWrite,HKLM,0x4,"Tmp_Default\Software\mySoft","Language","en-US"
RegWrite,HKLM,0x1,"Tmp_Software\mySoft","InstallDir","C:\mySoft"
RegUnloadHives
```

@@ -0,0 +1,65 @@
# RegUnloadHives
UnMount Source and Build registry hives.
After running this command the following registry hives mounted under HKLM will be unloaded:
| Argument | Description |
| --- | --- |
| Tmp_Default | The WinPE `DEFAULT` (HKCU) hive. |
| Tmp_Drivers | The WinPE `DRIVERS` hive. |
| Tmp_Software | The WinPE `SOFTWARE` (HKLM\Software) hive. |
| Tmp_System | The WinPE `SYSTEM` (HKLM\System) hive. |
| Tmp_Install_Default | The source Install.wim `DEFAULT` (HKCU) hive. |
| Tmp_Install_Drivers | The sourceInstall.wim `DRIVERS` hive. |
| Tmp_Install_Software | The sourceInstall.wim `SOFTWARE` (HKLM\Software) hive. |
| Tmp_Install_System | The source Install.wim `SYSTEM` (HKLM\System) hive. |
## Syntax
```pebakery
RegUnLoadHives[,FORCE][,HKEY=<HKEY>][,Target=<Dir>]
```
### Arguments
| Argument | Description |
| --- | --- |
| FORCE | Force unloading of all non-system hives. |
| HKEY= Unload hives from this root key. (HKLM, HKU) |
| Target= | Unload hives from this directory. |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | If `FORCE` is specified the return code will be one of: |
|| 0 - All registry hives unloaded successfully. |
|| 1 - Warning: Not all registry hives could be unloaded! |
|| 2 - No loaded registry hives were found. |
You must handle ExitCode. The script will not Exit/Halt.
## Remarks
None.
## Related
[RegLoadHives](./RegLoadHives.md)
## Examples
### Example 1
```pebakery
Echo,"Configuring %ScriptTitle%..."
RegLoadHives
RegWrite,HKLM,0x4,"Tmp_Default\Software\mySoft","Language","en-US"
RegWrite,HKLM,0x1,"Tmp_Software\mySoft","InstallDir","C:\mySoft"
RegUnloadHives
```

@@ -0,0 +1,45 @@
# RequireDriver
Copy the driver support files and driver entries from the INSTALL.WIM driver database to the target registry driver database.
Both the DRIVERS hive and SYSTEM\Drivers store are processed.
## Syntax
```pebakery
RequireDriver,<filename.inf>,[NOREG]
```
### Arguments
| Argument | Description |
| --- | --- |
| InfFile | The name of the driver's .inf file. |
| NOREG | (Optional) Don't copy registry (services & driver database). |
## Return Codes
None.
## Remarks
Registry hives Tmp_Install_Drivers, Tmp_Install_System, Tmp_Drivers, Tmp_System must be loaded before calling.
## Related
[RegCopyDriver](./RegCopyDriver.md), [RegLoadHives](./RegLoadHives.md), [RegUnLoadHives](./RegUnLoadHives.md)
## Examples
### Example 1
```pebakery
Echo,"Configuring %ScriptTitle%..."
RegLoadHives
RequireDriver,display.inf
RequireDriver,displayoverride.inf,NOREG
RegUnloadHives
```

47
PhoenixAPI/RequireFile.md Normal file

@@ -0,0 +1,47 @@
# RequireFile
RequireFile is an alias to the `RequireFileEx,ExtractFile` command.
Extract files and their .mui/mun files (if they exist) from Install.wim
Wildcards (?, *) are supported.
## Syntax
```pebakery
RequireFile,<FilePath>[,NOMUI]
```
### Arguments
| Argument | Description |
| --- | --- |
| FilePath | Path to the file to extract relative to the root of Install.wim |
| NOMUI | (Optional) Don't extract .mui files. |
## Return Codes
None.
## Remarks
If you have multiple files to extract consider using `RequireFileEx,AppendList` as this will vastly improve extraction speed, as all files in the list can be extracted in one pass instead of one file at a time.
Hint: If you know the file to be extracted isn't localized you can save a some time by not checking for .mui files that don't exist.
## Related
[RequireFileEx](./RequireFileEx.md)
## Examples
### Example 1
Extract a single set of unlocalized files.
```pebakery
Echo,"Extracting..."
RequireFile,\ProgramData\Microsoft\User Account Pictures\user*.*,NOMUI
```

@@ -0,0 +1,69 @@
# RequireFileEx
Extract files and their .mui/mun files (if they exist) from Install.wim
Wildcards (?, *) are supported.
## Syntax
```pebakery
RequireFileEx,<Action>,<FilePath>[,NOMUI]
```
### Arguments
| Argument | Description |
| --- | --- |
| Action | One of the following: |
|| `AppendList` - Append the file to a list (bulk extraction). You must call RequireFileEx,ExtractList in order to perform the actual extraction of the list. |
|| `ExtractFile` - Single file extraction |
|| `ExtractList` - Extract the list created with AppendList |
| FilePath | Path to the file to extract relative to the root of Install.wim |
| NOMUI | (Optional) Don't extract .mui files. |
## Return Codes
None.
## Remarks
Using _AppendList_ vastly improves extraction speed, as all files in the list can be extracted in one pass instead of one file at a time.
Commands do not need to be concurrent, you can continue to call `RequireFileEx,AppendList` as often as you like to add files to the list, then extract them all at once at the end of your script.
Hint: If you know the file to be extracted isn't localized you can save a some time by not checking for .mui files that don't exist.
## Related
[RequireFile](./RequireFile.md)
## Examples
### Example 1
Extract a single set of unlocalized files.
```pebakery
Echo,"Extracting..."
RequireFileEx,ExtractFile,\ProgramData\Microsoft\User Account Pictures\user*.*,NOMUI
```
### Example 2
Bulk extract a list of files.
```pebakery
Echo,"Processing..."
// Append files to the bulk extraction list
RequireFileEx,AppendList,\Windows\System32\iernonce.dll
RequireFileEx,AppendList,\Windows\System32\ole32.dll
// Conditional extraction
If,%someValue%,Equals,%something%,RequireFileEx,AppendList,\Windows\System32\mylib.dll
// Extract
Echo,"Bulk Extracting..."
RequireFileEx,ExtractList
```

39
PhoenixAPI/RunFromRAM.md Normal file

@@ -0,0 +1,39 @@
# RunFromRam
Choose to redirect the programs folder to Boot.wim
When this option is enabled the program files will be stored in the _X:\Program Files_ folder in Boot.wim and loaded into memory on boot instead of being placed in the _Y:\Programs_ directory on your output media (CD/DVD/USB).
Generally speaking you should only select this option if you are booting Read-Only media and your program requires write-access to the file system."
## Syntax
```pebakery
RunFromRam
```
### Arguments
None.
## Return Codes
None.
## Remarks
None.
## Related
## Examples
### Example 1
Run a program "From RAM" if a checkbox is selected.
```pebakery
If,%cb_RunFromRam%,Equal,True,RunFromRam
```

37
PhoenixAPI/SetFileACL.md Normal file

@@ -0,0 +1,37 @@
# SetFileACL
Set Windows security to give full control for "Everyone" on a file or directory.
## Syntax
```pebakery
SetFileACL,<Path>
```
### Arguments
| Argument | Description |
| --- | --- |
| Path | The file or directory to modify. |
## Return Codes
None.
## Remarks
If the command fails the build will halt.
## Related
[SetRegACL](./SetRegACL.md)
## Examples
### Example 1
```pebakery
SetFileACL,"C:\Windows\System32\notepad.exe"
```

37
PhoenixAPI/SetRegACL.md Normal file

@@ -0,0 +1,37 @@
# SetRegACL
Take ownership and grant full control for "Everyone" on a registry key.
## Syntax
```pebakery
SetRegACL,<Path>
```
### Arguments
| Argument | Description |
| --- | --- |
| Path | Registry key to modify. The hive must already be mounted. |
## Return Codes
None.
## Remarks
If the command fails the build will halt.
## Related
[SetFileACL](./SetFileACL.md)
## Examples
### Example 1
```pebakery
SetRegACL,"HKLM\Tmp_System"
```

39
PhoenixAPI/WixExtract.md Normal file

@@ -0,0 +1,39 @@
# WixExtract
Extract files from an Windows Installer XML Toolset (WiX) installer.
## Syntax
```pebakery
WixExtract,<SetupFile>,<DestDir>
```
### Arguments
Optional arguments may be specified in any order.
| Argument | Description |
| --- | --- |
| SetupFile | The WiX installer file to unpack. |
| DestDir | The full path to the directory where the files will be unpacked. |
## Return Codes
None.
## Remarks
If unpacking fails the build will halt.
## Related
## Examples
### Example 1
```pebakery
Echo,"Extracting %ScriptTitle%..."
WixExtract,"%ProgramsCache%\%ProgramFolder%\Setup.exe","%ProjectTemp%\%ProgramFolder%"
```

56
PhoenixAPI/XMLAdd.md Normal file

@@ -0,0 +1,56 @@
# XMLAdd
Add a new element/text/attribute to an XML file.
To update an existing element/attribute you must use the XMLUpdate command.
## Syntax
```pebakery
XMLAdd,<Operation>,<XMLFile>,<XPath>,<Type>,<Name>[,<Value>]
```
### Arguments
| Argument | Description |
| --- | --- |
| Operation | One of the following: |
| | `Insert` - Insert a node at the the beginning of the XPath. |
| | `Append` - Append a node to the end of the XPath. |
| | `Subnode` - Add a new subnode to each XPath in the document. |
| XMLFile | Full path to the .xml filed to edit. |
| XPath | XPath (XML Path Language) query used to insert the Attribute/Element. |
| Type | XPath type [elem|text|attr] |
| Name | Value Name. |
| Value | (Optional) Value |
## Return Codes
None.
## Remarks
If the command fails the build will halt.
For more information about using XPath syntax check out this [XPath Tutorial](https://www.w3schools.com/xml/xpath_intro.asp).
## Related
[XMLDelete](./XMLDelete.md), [XMLRename](./XMLRename.md), [XMLUpdate](./XMLUpdate.md)
## Examples
### Example 1
```pebakery
// Add a Subnode called GUIConfig under GUIConfigs
XMLAdd,SubNode,%config.xml%,"NotepadPlus/GUIConfigs","elem","GUIConfig",""
// Insert a new attribute into an XML file.
XMLAdd,Insert,%config.xml%,"NotepadPlus/GUIConfigs/GUIConfig[not(@name)]","attr","name","DarkMode"
// Append an attribute to the DarkMode attribute
XMLAdd,Append,%config.xml%,"NotepadPlus/GUIConfigs/GUIConfig[@name='DarkMode']","attr","enable","yes"
```

41
PhoenixAPI/XMLDelete.md Normal file

@@ -0,0 +1,41 @@
# XMLDelete
Delete an XML path/value.
## Syntax
```pebakery
XMLDelete,<XMLFile>,<XPath>
```
### Arguments
| Argument | Description |
| --- | --- |
| XMLFile | Full path to the .xml filed to edit. |
| XPath | XPath (XML Path Language) query used to locate the Attribute/Element to delete. |
## Return Codes
None.
## Remarks
If the command fails the build will halt.
For more information about using XPath syntax check out this [XPath Tutorial](https://www.w3schools.com/xml/xpath_intro.asp).
## Related
[XMLAdd](./XMLAdd.md), [XMLRename](./XMLRename.md), [XMLUpdate](./XMLUpdate.md)
## Examples
### Example 1
```pebakery
// Add a Subnode called GUIConfig under GUIConfigs
XMLDelete,%config.xml%,"NotepadPlus/GUIConfigs"
```

44
PhoenixAPI/XMLRename.md Normal file

@@ -0,0 +1,44 @@
# XMLRename
Rename a value in an XML file.
The XPath must exist in order for the value to be Renamed.
## Syntax
```pebakery
XMLRename,<XMLFile>,<XPath>,<Value>
```
### Arguments
| Argument | Description |
| --- | --- |
| XMLFile | Full path to the .xml filed to edit. |
| XPath | XPath (XML Path Language) query used to locate the Attribute/Element to delete. |
| Value | New Value. |
## Return Codes
None.
## Remarks
If the command fails the build will halt.
For more information about using XPath syntax check out this [XPath Tutorial](https://www.w3schools.com/xml/xpath_intro.asp).
## Related
[XMLAdd](./XMLAdd.md), [XMLDelete](./XMLDelete.md), [XMLUpdate](./XMLUpdate.md)
## Examples
### Example 1
```pebakery
// Add a Subnode called GUIConfig under GUIConfigs
XMLRename,%config.xml%,"NotepadPlus/GUIConfigs","Configs"
```

59
PhoenixAPI/XMLUpdate.md Normal file

@@ -0,0 +1,59 @@
# XMLUpdate
Update the value of an existing Attribute/Element
The XPath must exist in order for the value to be updated.
## Syntax
```pebakery
XMLUpdate,<XMLFile>,<XPath>,<Value>,[NOERR]
```
### Arguments
| Argument | Description |
| --- | --- |
| XMLFile | Full path to the .xml filed to edit. |
| XPath | XPath (XML Path Language) query used to locate the Attribute/Element to delete. |
| Value | New Value. |
| NOERR | NOERR - Don't Halt on errors. (Use if you intend to handle errors yourself). |
## Return Codes
| Variable | Description |
| --- | --- |
| #r | Returns of the the following: |
| | `0` - Success |
| | `1` - Failure |
| | `2` - Invalid Arguments |
| | `3` - Invalid XML File |
| | `4` - Library Exception |
| | `5` - Internal Error |
| | `-99999999` - XPath does not exist |
## Remarks
If the command fails the build will halt unless the `NOERR` parameter is specified.
For more information about using XPath syntax check out this [XPath Tutorial](https://www.w3schools.com/xml/xpath_intro.asp).
## Related
[XMLAdd](./XMLAdd.md), [XMLDelete](./XMLDelete.md), [XMLRename](./XMLRename.md)
## Examples
### Example 1
```pebakery
XMLUpdate,%config.xml%,"NotepadPlus/GUIConfigs/GUIConfig[@name='stylerTheme']/@path","X:\Users\Default\AppData\Roaming\Notepad++\themes\DarkModeDefault.xml",NOERR
If,#r,Equal,-99999999,Begin
// Node <GUIConfig name='DarkMode'> does not exist, we need to create it
XMLAdd,SubNode,%config.xml%,"NotepadPlus/GUIConfigs","elem","GUIConfig",""
XMLAdd,Insert,%config.xml%,"NotepadPlus/GUIConfigs/GUIConfig[not(@name)]","attr","name","stylerTheme"
XMLAdd,Append,%config.xml%,"NotepadPlus/GUIConfigs/GUIConfig[@name='stylerTheme']","attr","path","X:\Users\Default\AppData\Roaming\Notepad++\themes\DarkModeDefault.xml"
End
```