Skip to content

Commit

Permalink
Enhancement: added a PowerShell applying subscript, as the default co…
Browse files Browse the repository at this point in the history
…de path for Windows.

PowerShell is installed by default in Windows 7 and later. It has native Unicode support and should work in a more consistent way than normal Windows command prompt.
Users should still run apply_patch_windows.bat as usual. If PowerShell is installed (in default location), it will switch to the subscript. Otherwise, the normal legacy code path is used.
Also moved up 3 lines of code to where they should have been.
  • Loading branch information
dreamer2908 committed May 6, 2016
1 parent aff81d6 commit 6c5b0a6
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 3 deletions.
16 changes: 13 additions & 3 deletions YAXBPC/CopyMe/apply_patch_windows.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,21 @@ setlocal
rem Roses are red, violets are blue, sugar is sweet, and so are you.
rem Enjoy your usual ratio: 5% of lines do the actual work, and the rest are there to make sure they work. (It's like 1%, actually)

set "powershell=%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe"
if exist %powershell% (
rem If PowerShell is installed, execute the sub-script, and exit when it's done. Nothing is set up, so nothing to cleanup
%powershell% -noprofile -executionpolicy bypass -file "%~dp0\subscript1.ps1" "%~1"
goto :eof
) else (
echo PowerShell not found. Executing the legacy code path...
)

for /f "tokens=2 delims=:." %%x in ('chcp') do set cp=%%x
chcp 65001>nul
set WORKINGDIR=%CD%
chdir /d "%~dp0"
(call )

set sourcefile=&sourcefile&
set targetfile=&targetfile&
set app=xdelta3.exe
Expand All @@ -16,9 +29,6 @@ set targetfiletmp=targetfile.tmp
set movesourcefile=0
set movetargetfile=0
set olddir=old
set WORKINGDIR=%CD%
chdir /d "%~dp0"
(call )

call :find_xdelta3 && call :find_inputs "%~1" && call :run_patch
call :gtfo
Expand Down
105 changes: 105 additions & 0 deletions YAXBPC/CopyMe/subscript1.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
$global:WORKINGDIR = get-location
$global:SCRIPTDIR = split-path $MyInvocation.MyCommand.Definition -parent
Set-Location $global:SCRIPTDIR

$global:sourcefile = '&sourcefile&' # keep it in a pair of single quotes. Any single quote must be doubled (replace ' with '')
$global:targetfile = '&targetfile&'
$global:app = '.\xdelta3.exe'
$global:changes = 'changes.vcdiff'
$global:sourcefiletmp = 'sourcefile.tmp'
$global:targetfiletmp = 'targetfile.tmp'
$global:movesourcefile = 0
$global:movetargetfile = 0
$global:olddir = 'old'

function check_sanity {
$re = $true
If (!(Test-Path -LiteralPath $global:app)) {
Write-Host "Error: The required application '$global:app' is missing."
$re = $false
}
if (!(Test-Path -LiteralPath "$global:changes")) {
Write-Host "Error: The delta file '$global:changes' is missing."
$re = $false
}
if (!$re) {
Write-Host "Can't continue. Please extract everything from the archive."
}
return $re
}

function find_inputs ([String] $dropin = "") {
if ($dropin) {
if (Test-Path -LiteralPath $dropin) {
$global:sourcefile = $dropin
} else {
Write-Host "Warning: Input file '$dropin' not found. Ignored."
}
}

if (!(Test-Path -LiteralPath $global:sourcefile)) {
if (Test-Path -LiteralPath ('..\' + $global:sourcefile)) {
$global:sourcefile = '..\' + $global:sourcefile
} elseif (Test-Path -LiteralPath ('..\..\' + $global:sourcefile)) {
$global:sourcefile = '..\..\' + $global:sourcefile
} elseif (Test-Path -LiteralPath ('..\..\..\' + $global:sourcefile)) {
$global:sourcefile = '..\..\..\' + $global:sourcefile
} else {
Write-Host "Error: Source file '$global:sourcefile' not found."
Write-Host "You must put it in the same folder as this script."
return $false
}
}

$parent = Split-Path $global:sourcefile -Parent
if ($parent) {
$global:targetfile = Join-Path $parent $global:targetfile
$global:sourcefiletmp = Join-Path $parent $global:sourcefiletmp
$global:targetfiletmp = Join-Path $parent $global:targetfiletmp
$global:olddir = Join-Path $parent $global:olddir
}

return $true
}

function run_patch {
Write-Host "Attempting to patch '$sourcefile' ..."

if ($global:movesourcefile -eq 1) {
Move-Item -literalPath $global:sourcefile $global:sourcefiletmp -force
} else {
$global:sourcefiletmp = $global:sourcefile
}

if ($global:movetargetfile -eq 0) {
$global:targetfiletmp = $global:targetfile
}

Start-Process -FilePath "$global:app" -ArgumentList "-d -f -s `"$global:sourcefiletmp`" `"$global:changes`" `"$global:targetfiletmp`"" -NoNewWindow -Wait

if ($global:movesourcefile -eq 1) {
Move-Item -literalPath $global:sourcefiletmp $global:sourcefile -force
}
if ($global:movetargetfile -eq 1) {
Move-Item -literalPath $global:targetfiletmp $global:targetfile -force
}

if (Test-Path -LiteralPath $global:targetfile) {
if ( -Not (Test-Path -LiteralPath $global:olddir)) {
New-Item -Path $global:olddir -ItemType Directory | out-null
}
Move-Item -literalPath $global:sourcefile $global:olddir -force
Write-Host "Done."
return $true
} else {
Write-Host "Error occured! Patching wasn't successful!"
return $false
}
}

if (((check_sanity) -eq $true) -and ((find_inputs $args[0]) -eq $true)) {
$dummy = run_patch
}

Set-Location($global:WORKINGDIR)
exit 0
7 changes: 7 additions & 0 deletions YAXBPC/Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -559,15 +559,20 @@ private void createApplyingScripts(string sourceFile, string targetFile, string

// Unified both scripts. Now only apply_patch_windows.bat
string winScript = File.ReadAllText(Path.Combine(programDir, "apply_patch_windows.bat"));
// The brand-new PowerShell subscript
string psScript = File.ReadAllText(Path.Combine(programDir, "subscript1.ps1"));

winScript = winScript.Replace("&sourcefile&", escapeStringForBatch(sourceFile)).Replace("&targetfile&", escapeStringForBatch(targetFile));
psScript = psScript.Replace("&sourcefile&", sourceFile.Replace("'", "''")).Replace("&targetfile&", targetFile.Replace("'", "''")); // Any single quote in single-quoted PowerShell string must be doubled (replace ' with '')
if (stringContainsNonASCIIChar(Path.GetFileName(sourceFile)))
{
winScript = winScript.Replace("set movesourcefile=0", "set movesourcefile=1");
psScript = psScript.Replace("movesourcefile = 0", "movesourcefile = 1"); // even though PS has native unicode support, calling xdelta3 with unicode paramenters still ends up in failure
}
if (stringContainsNonASCIIChar(Path.GetFileName(targetFile)))
{
winScript = winScript.Replace("set movetargetfile=0", "set movetargetfile=1");
psScript = psScript.Replace("movetargetfile = 0", "movetargetfile = 1");
}
if (!(stringContainsNonASCIIChar(Path.GetFileName(sourceFile) + Path.GetFileName(targetFile))))
{
Expand All @@ -579,12 +584,14 @@ private void createApplyingScripts(string sourceFile, string targetFile, string
string winPath = Path.Combine(outputDir, "apply_patch_windows.bat");
string linuxPath = Path.Combine(outputDir, "apply_patch_linux.sh");
string readMePath = Path.Combine(outputDir, "how_to_apply_this_patch.txt");
string psPath = Path.Combine(outputDir, "subscript1.ps1");

// write outputs
File.WriteAllText(winPath, winScript);
File.WriteAllText(linuxPath, linuxScript);
File.WriteAllText(macPath, macScript);
File.WriteAllText(readMePath, readMe);
File.WriteAllText(psPath, psScript, Encoding.UTF8); // encoding utf-8 with BOM

// "Apply all" scripts
if (addNewPatchToApplyAllScripts)
Expand Down

0 comments on commit 6c5b0a6

Please sign in to comment.