Skip to content

Commit 90fa487

Browse files
authored
Fixed path issues main.ps1
Fixed path issues for long paths and paths with hyphens - within & files with double extensions
1 parent 2ac64af commit 90fa487

File tree

1 file changed

+80
-27
lines changed

1 file changed

+80
-27
lines changed

main.ps1

Lines changed: 80 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,28 @@ $asciiArt = @"
1414
1515
"@
1616

17+
# Enable long path support
18+
function Enable-LongPaths {
19+
Write-Host "Enabling long path support..."
20+
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1
21+
}
22+
23+
Enable-LongPaths
24+
25+
# Add Windows API DeleteFile and MoveFile functions
26+
Add-Type -TypeDefinition @"
27+
using System;
28+
using System.Runtime.InteropServices;
29+
public class WinAPI {
30+
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
31+
[return: MarshalAs(UnmanagedType.Bool)]
32+
public static extern bool DeleteFile(string path);
33+
34+
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
35+
public static extern bool MoveFile(string lpExistingFileName, string lpNewFileName);
36+
}
37+
"@
38+
1739
# Define symbolic link creation function
1840
function New-SymbolicLink {
1941
param (
@@ -23,13 +45,19 @@ function New-SymbolicLink {
2345
New-Item -Path $Path -ItemType SymbolicLink -Value $Target -Force
2446
}
2547

26-
# Define symbolic link removal function
48+
# Define symbolic link removal function using Windows API
2749
function Remove-SymbolicLink {
2850
param (
2951
[string]$Path
3052
)
3153
if ((Test-Path -Path $Path) -and ((Get-Item -Path $Path).Attributes -band [System.IO.FileAttributes]::ReparsePoint)) {
32-
Remove-Item -Path $Path -Force
54+
$result = [WinAPI]::DeleteFile($Path)
55+
if ($result) {
56+
Write-Host "Successfully removed symbolic link: $Path"
57+
} else {
58+
$errorMessage = [System.ComponentModel.Win32Exception]::new([System.Runtime.InteropServices.Marshal]::GetLastWin32Error()).Message
59+
Write-Host "Failed to remove symbolic link: $errorMessage"
60+
}
3361
}
3462
}
3563

@@ -47,6 +75,23 @@ function Remove-EmptyDirectories {
4775
}
4876
}
4977

78+
# Define a function to move files using the Windows API
79+
function Move-File-With-Metadata {
80+
param (
81+
[string]$SourcePath,
82+
[string]$DestinationPath
83+
)
84+
85+
if ([WinAPI]::MoveFile($SourcePath, $DestinationPath)) {
86+
Write-Host "Successfully moved $SourcePath to $DestinationPath with metadata updates."
87+
return $true
88+
} else {
89+
$errorMessage = [System.ComponentModel.Win32Exception]::new([System.Runtime.InteropServices.Marshal]::GetLastWin32Error()).Message
90+
Write-Host "Failed to move file: $errorMessage"
91+
return $false
92+
}
93+
}
94+
5095
# Define mod installation function
5196
function Install-Mod {
5297
param (
@@ -69,23 +114,23 @@ function Install-Mod {
69114
[string]$TargetPath
70115
)
71116

72-
Get-ChildItem -Path $SourcePath -Recurse -File | ForEach-Object {
117+
Get-ChildItem -LiteralPath $SourcePath -Recurse -File | ForEach-Object {
73118
$relativePath = $_.FullName.Substring($SourcePath.Length).TrimStart("\")
74119
$targetFilePath = Join-Path -Path $TargetPath -ChildPath $relativePath
75120
$backupFilePath = Join-Path -Path $backupDir -ChildPath $relativePath
76121

77-
if (Test-Path -Path $targetFilePath) {
122+
if (Test-Path -LiteralPath $targetFilePath) {
78123
$backupNeeded = $true
79124

80125
# Create necessary directories in backup path
81-
$backupDirPath = Split-Path -Path $backupFilePath -Parent
82-
if (-not (Test-Path -Path $backupDirPath)) {
126+
$backupDirPath = [System.IO.Path]::GetDirectoryName($backupFilePath)
127+
if (-not (Test-Path -LiteralPath $backupDirPath)) {
83128
New-Item -ItemType Directory -Path $backupDirPath -Force
84129
}
85130

86131
# If target is a symbolic link, prompt the user for action
87-
if ((Get-Item -Path $targetFilePath).Attributes -band [System.IO.FileAttributes]::ReparsePoint) {
88-
$currentTarget = (Get-Item -Path $targetFilePath).Target
132+
if ((Get-Item -LiteralPath $targetFilePath).Attributes -band [System.IO.FileAttributes]::ReparsePoint) {
133+
$currentTarget = (Get-Item -LiteralPath $targetFilePath).Target
89134
Write-Host "Conflict: $targetFilePath is already linked to $currentTarget"
90135
$choice = Read-Host "Do you want to replace the existing link? (Enter 'yes' to replace or 'no' to keep the existing link) [default: yes]"
91136
if ($choice -eq 'no' -or $choice -eq 'n') {
@@ -94,14 +139,22 @@ function Install-Mod {
94139
}
95140

96141
# Backup the existing file
97-
Copy-Item -Path $targetFilePath -Destination $backupFilePath -Force
98-
# Remove the existing file
99-
Remove-Item -Path $targetFilePath -Force
142+
$moveSuccess = Move-File-With-Metadata -SourcePath $targetFilePath -DestinationPath $backupFilePath
143+
if ($moveSuccess) {
144+
Write-Host "File moved successfully: $targetFilePath"
145+
} else {
146+
Write-Host "Failed to move file: $targetFilePath"
147+
}
148+
149+
# Remove the existing file if it was successfully moved
150+
if (Test-Path -LiteralPath $targetFilePath) {
151+
Remove-Item -LiteralPath $targetFilePath -Force
152+
}
100153
}
101154

102155
# Create necessary directories in target path
103-
$targetDir = Split-Path -Path $targetFilePath -Parent
104-
if (-not (Test-Path -Path $targetDir)) {
156+
$targetDir = [System.IO.Path]::GetDirectoryName($targetFilePath)
157+
if (-not (Test-Path -LiteralPath $targetDir)) {
105158
New-Item -ItemType Directory -Path $targetDir -Force
106159
}
107160

@@ -115,7 +168,7 @@ function Install-Mod {
115168
Copy-And-Link -SourcePath $ModSourcePath -TargetPath $GameDirectory
116169

117170
# Create the backup directory if needed
118-
if ($backupNeeded -and -not (Test-Path -Path $backupDir)) {
171+
if ($backupNeeded -and -not (Test-Path -LiteralPath $backupDir)) {
119172
New-Item -ItemType Directory -Path $backupDir
120173
}
121174

@@ -135,22 +188,22 @@ function Uninstall-Mod {
135188
$backupDir = Join-Path -Path $BackupDirectory -ChildPath ("Backup-" + $ModName)
136189

137190
# Restore backup if it exists
138-
if (Test-Path -Path $backupDir) {
139-
Get-ChildItem -Path $backupDir -Recurse -File | ForEach-Object {
191+
if (Test-Path -LiteralPath $backupDir) {
192+
Get-ChildItem -LiteralPath $backupDir -Recurse -File | ForEach-Object {
140193
$relativePath = $_.FullName.Substring($backupDir.Length).TrimStart("\")
141194
$targetFilePath = Join-Path -Path $GameDirectory -ChildPath $relativePath
142195

143196
# Remove the symbolic link if it exists
144197
Remove-SymbolicLink -Path $targetFilePath
145198

146199
# Create necessary directories in target path
147-
$targetDir = Split-Path -Path $targetFilePath -Parent
148-
if (-not (Test-Path -Path $targetDir)) {
200+
$targetDir = [System.IO.Path]::GetDirectoryName($targetFilePath)
201+
if (-not (Test-Path -LiteralPath $targetDir)) {
149202
New-Item -ItemType Directory -Path $targetDir -Force
150203
}
151204

152205
# Restore the backup file
153-
Copy-Item -Path $_.FullName -Destination $targetFilePath -Force
206+
Copy-Item -LiteralPath $_.FullName -Destination $targetFilePath -Force
154207
Write-Host "Restored: $targetFilePath"
155208
}
156209

@@ -160,7 +213,7 @@ function Uninstall-Mod {
160213
# No backup found, remove the symbolic links directly
161214
Write-Host "No backup found for mod: $ModName, removing symbolic links directly."
162215

163-
Get-ChildItem -Path $ModSourcePath -Recurse -File | ForEach-Object {
216+
Get-ChildItem -LiteralPath $ModSourcePath -Recurse -File | ForEach-Object {
164217
$relativePath = $_.FullName.Substring($ModSourcePath.Length).TrimStart("\")
165218
$targetFilePath = Join-Path -Path $GameDirectory -ChildPath $relativePath
166219

@@ -180,7 +233,7 @@ function List-Mods {
180233
param (
181234
[string]$GameDirectory
182235
)
183-
Get-ChildItem -Path $GameDirectory -Recurse | Where-Object {
236+
Get-ChildItem -LiteralPath $GameDirectory -Recurse | Where-Object {
184237
$_.Attributes -band [System.IO.FileAttributes]::ReparsePoint
185238
} | ForEach-Object {
186239
Write-Host $_.Name
@@ -193,8 +246,8 @@ function Read-Config {
193246
[string]$ConfigFilePath
194247
)
195248
$config = @{}
196-
if (Test-Path -Path $ConfigFilePath) {
197-
Get-Content -Path $ConfigFilePath | ForEach-Object {
249+
if (Test-Path -LiteralPath $ConfigFilePath) {
250+
Get-Content -LiteralPath $ConfigFilePath | ForEach-Object {
198251
$_ = $_.Trim()
199252
if ($_.Length -gt 0 -and $_.Substring(0, 1) -ne '#') {
200253
$parts = $_ -split '='
@@ -217,7 +270,7 @@ function Select-Game {
217270
Clear-Host
218271
Write-Host $asciiArt -ForegroundColor Blue
219272
$gamesPath = Join-Path -Path $BasePath -ChildPath 'Games'
220-
$games = Get-ChildItem -Path $gamesPath -Directory
273+
$games = Get-ChildItem -LiteralPath $gamesPath -Directory
221274

222275
Write-Host "Available games:" -ForegroundColor Cyan
223276
for ($i = 0; $i -lt $games.Count; $i++) {
@@ -275,11 +328,11 @@ function Is-Mod-Installed {
275328
[string]$GameDirectory
276329
)
277330

278-
$sampleFile = Get-ChildItem -Path $ModPath -Recurse -File | Select-Object -First 1
331+
$sampleFile = Get-ChildItem -LiteralPath $ModPath -Recurse -File | Select-Object -First 1
279332
if ($sampleFile) {
280333
$relativePath = $sampleFile.FullName.Substring($ModPath.Length).TrimStart("\")
281334
$linkPath = Join-Path -Path $GameDirectory -ChildPath $relativePath
282-
return (Test-Path -Path $linkPath) -and ((Get-Item -Path $linkPath).Attributes -band [System.IO.FileAttributes]::ReparsePoint)
335+
return (Test-Path -LiteralPath $linkPath) -and ((Get-Item -LiteralPath $linkPath).Attributes -band [System.IO.FileAttributes]::ReparsePoint)
283336
}
284337
return $false
285338
}
@@ -292,7 +345,7 @@ function Select-Mod {
292345
)
293346
Clear-Host
294347
Write-Host $asciiArt -ForegroundColor Blue
295-
$mods = Get-ChildItem -Path $modParentPath -Directory | Where-Object { $_.Name -notmatch '^Backup-' }
348+
$mods = Get-ChildItem -LiteralPath $modParentPath -Directory | Where-Object { $_.Name -notmatch '^Backup-' }
296349
$modList = @()
297350

298351
foreach ($mod in $mods) {

0 commit comments

Comments
 (0)