|
| 1 | +$code = @" |
| 2 | +using System; |
| 3 | +using System.Text; |
| 4 | +using System.Runtime.InteropServices; |
| 5 | +using Microsoft.Win32.SafeHandles; |
| 6 | +using System.ComponentModel; |
| 7 | +
|
| 8 | +namespace SymLinkInterop { |
| 9 | + public sealed class SymLinkManager |
| 10 | + { |
| 11 | + private const int FILE_SHARE_READ = 1; |
| 12 | + private const int FILE_SHARE_WRITE = 2; |
| 13 | +
|
| 14 | + private const int CREATION_DISPOSITION_OPEN_EXISTING = 3; |
| 15 | +
|
| 16 | + private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000; |
| 17 | +
|
| 18 | + [DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)] |
| 19 | + public static extern int GetFinalPathNameByHandle(IntPtr handle, [In, Out] StringBuilder path, int bufLen, int flags); |
| 20 | +
|
| 21 | + [DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)] |
| 22 | + public static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, |
| 23 | + IntPtr SecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile); |
| 24 | +
|
| 25 | + public static string GetSymbolicLinkTarget(string symlinkpath) |
| 26 | + { |
| 27 | + SafeFileHandle directoryHandle = CreateFile(symlinkpath, 0, 2, System.IntPtr.Zero, CREATION_DISPOSITION_OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, System.IntPtr.Zero); |
| 28 | + if(directoryHandle.IsInvalid) |
| 29 | + throw new Win32Exception(Marshal.GetLastWin32Error()); |
| 30 | +
|
| 31 | + StringBuilder path = new StringBuilder(512); |
| 32 | + int size = GetFinalPathNameByHandle(directoryHandle.DangerousGetHandle(), path, path.Capacity, 0); |
| 33 | + if (size<0) |
| 34 | + throw new Win32Exception(Marshal.GetLastWin32Error()); |
| 35 | + if (path[0] == '\\' && path[1] == '\\' && path[2] == '?' && path[3] == '\\') |
| 36 | + return path.ToString().Substring(4); |
| 37 | + else |
| 38 | + return path.ToString(); |
| 39 | + } |
| 40 | + } |
| 41 | +} |
| 42 | +"@ |
| 43 | + |
| 44 | +Add-Type -TypeDefinition $code |
| 45 | + |
| 46 | +function Get-SymbolicLinkTarget |
| 47 | +{ |
| 48 | + [CmdletBinding()] |
| 49 | + param |
| 50 | + ( |
| 51 | + [parameter(Mandatory=$true, ValueFromPipeline=$true)] |
| 52 | + [string]$Path |
| 53 | + ) |
| 54 | + PROCESS |
| 55 | + { |
| 56 | + return [SymLinkInterop.SymLinkManager]::GetSymbolicLinkTarget($Path) |
| 57 | + } |
| 58 | +} |
0 commit comments