diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index bda2fb5944..83d76df5d4 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -990,10 +990,19 @@ namespace System.Management.Automation // 1. When starting a process on Windows, if the 'FileName' is a symbolic link, the immediate link target will automatically be used, // but the OS does not do recursive resolution when the immediate link target is also a symbolic link. // 2. Keep the same behavior as before adopting the 'LinkTarget' and 'ResolveLinkTarget' APIs in .NET 6. - string linkTarget = File.ResolveLinkTarget(fileName, returnFinalTarget: false)?.FullName; - if (linkTarget is not null) + try { - fileName = linkTarget; + string linkTarget = File.ResolveLinkTarget(fileName, returnFinalTarget: false)?.FullName; + if (linkTarget is not null) + { + fileName = linkTarget; + } + } + catch + { + // An exception may be thrown from 'File.ResolveLinkTarget' when it fails to resolve a link path, + // for example, when the underlying file system doesn't support reparse points. + // Just use the original file name in this case. } SHFILEINFO shinfo = new SHFILEINFO(); diff --git a/test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1 b/test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1 index 6888f5cba7..b76cf67bfe 100644 --- a/test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1 +++ b/test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1 @@ -252,3 +252,48 @@ Categories=Application; { $dllFile = "$PSHOME\System.Management.Automation.dll"; & $dllFile } | Should -Throw -ErrorId "NativeCommandFailed" } } + +Describe "Run native command from a mounted FAT-format VHD" -tags @("Feature", "RequireAdminOnWindows") { + BeforeAll { + if (-not $IsWindows) { + return; + } + + $vhdx = Join-Path -Path $TestDrive -ChildPath ncp.vhdx + + if (Test-Path -Path $vhdx) { + Remove-item -Path $vhdx -Force + } + + $create_vhdx = Join-Path -Path $TestDrive -ChildPath 'create_vhdx.txt' + + Set-Content -Path $create_vhdx -Force -Value @" + create vdisk file="$vhdx" maximum=20 type=fixed + select vdisk file="$vhdx" + attach vdisk + convert mbr + create partition primary + format fs=fat + assign letter="T" + detach vdisk +"@ + + diskpart.exe /s $create_vhdx + Mount-DiskImage -ImagePath $vhdx > $null + + Copy-Item "$env:WinDir\System32\whoami.exe" T:\whoami.exe + } + + AfterAll { + if ($IsWindows) { + Dismount-DiskImage -ImagePath $vhdx + Remove-Item $vhdx, $create_vhdx -Force + } + } + + It "Should run 'whoami.exe' from FAT file system without error" -Skip:(!$IsWindows) { + $expected = & "$env:WinDir\System32\whoami.exe" + $result = T:\whoami.exe + $result | Should -BeExactly $expected + } +}