DotNetDllPathPatcher.ps1 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using namespace System.IO
  2. using namespace System.Text
  3. param([string]$exe_path, [string]$target_path = 'bin')
  4. $ErrorActionPreference = 'Stop'
  5. #$DebugPreference = 'Continue'
  6. $exe_path = (Resolve-Path -Path $exe_path).Path
  7. Write-Host "Origin path: `"$exe_path`""
  8. Write-Host "Target dll path: $target_path"
  9. $separator = '\'
  10. $max_path_length = 1024
  11. $exe_name = [Path]::GetFileName($exe_path)
  12. $dll_name = [Path]::ChangeExtension($exe_name, '.dll')
  13. Write-Debug "exe: $exe_name"
  14. Write-Debug "dll: $dll_name"
  15. function Update-Exe {
  16. $old_bytes = [Encoding]::UTF8.GetBytes("$dll_name`0")
  17. if ($old_bytes.Count -gt $max_path_length) {
  18. throw [PathTooLongException] 'old dll path is too long'
  19. }
  20. $new_dll_path = "$target_path$separator$dll_name"
  21. $new_bytes = [Encoding]::UTF8.GetBytes("$new_dll_path`0")
  22. Write-Host "Dll path Change to `"$new_dll_path`""
  23. if ($new_bytes.Count -gt $max_path_length) {
  24. throw [PathTooLongException] 'new dll path is too long'
  25. }
  26. $bytes = [File]::ReadAllBytes($exe_path)
  27. $index = (Get-Content $exe_path -Raw -Encoding 28591).IndexOf("$dll_name`0")
  28. if ($index -lt 0) {
  29. throw [InvalidDataException] 'Could not find old dll path'
  30. }
  31. Write-Debug "Position: $index"
  32. $end_postion = $index + $($new_bytes.Count)
  33. $end_length = $bytes.Count - $end_postion
  34. if ($end_postion -gt $bytes.Count) {
  35. throw [PathTooLongException] 'new dll path is too long'
  36. }
  37. Write-Debug "End Position: $end_postion"
  38. Write-Debug "End Length: $end_length"
  39. $fs = [File]::OpenWrite($exe_path)
  40. try {
  41. $fs.Write($bytes, 0, $index)
  42. $fs.Write($new_bytes)
  43. $fs.Write($bytes, $end_postion, $end_length)
  44. }
  45. finally {
  46. $fs.Dispose();
  47. }
  48. }
  49. function Move-Dll {
  50. $tmpbin = 'tmpbin'
  51. $dir = [Path]::GetDirectoryName($exe_path);
  52. $root = [Path]::GetDirectoryName($dir);
  53. Write-Debug "root path: $root"
  54. Write-Debug "dir path: $dir"
  55. Rename-Item $dir $tmpbin
  56. New-Item -ItemType Directory $dir > $null
  57. Move-Item $root\$tmpbin $dir
  58. Rename-Item $dir\$tmpbin $target_path
  59. Move-Item $dir\$target_path\$exe_name $dir
  60. }
  61. Update-Exe
  62. Move-Dll