2017-02-28 14 views
5

Việc tạo tương đối liên kết tượng trưng trong PowerShell 5.1 không đơn giản. New-Item không hoạt động như mong đợi. Một số cách tiếp cận được liệt kê dưới đây. Tui bỏ lỡ điều gì vậy?Làm thế nào để tạo ra cách tương đối symlink powershell?

thiết lập mẫu cho tất cả các ví dụ:

mkdir C:\Temp\foo -ErrorAction SilentlyContinue 
'sample contents' > C:\Temp\foo\foo.txt 
cd C:\Temp 

SAMPLE1: Liệu không công việc như mong đợi

#new ps5 Item cmdlets (https://msdn.microsoft.com/en-us/powershell/wmf/5.0/feedback_symbolic) are not working well with relative paths 
#C:\Temp\foo and C:\Temp\foo\foo.txt are returned 
$fld = New-Item -ItemType SymbolicLink -Name 'bar' -Target '.\foo' 
$fl = New-Item -ItemType SymbolicLink -Name 'bar.txt' -Target '.\foo\foo.txt' 
$fld.Target 
$fl.Target 

Sample2: Liệu không công việc như mong đợi

#Powershell community extensions 
#same problem - paths are created as absolute: C:\Temp\foo C:\Temp\foo\foo.txt 
$fld = New-Symlink 'c:\Temp\bar' '.\foo' 
$fl = New-Symlink 'c:\Temp\bar.txt' '.\foo\foo.txt' 
$fld.Target 
$fl.Target 

Samp le3: Làm việc như mong đợi

#API call CreateSymbolicLink as per https://gallery.technet.microsoft.com/scriptcenter/new-symlink-60d2531e 
#.\foo and .\foo\foo.txt are returned 
Add-Type -MemberDefinition @' 
    [DllImport("kernel32.dll", EntryPoint = "CreateSymbolicLinkW", CharSet = CharSet.Unicode, SetLastError = true)] 
    public static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags); 

    public static DirectoryInfo CreateSymbolicLinkToFolder(string lpSymlinkFileName, string lpTargetFileName) { 
     bool res = CreateSymbolicLink(lpSymlinkFileName, lpTargetFileName, 1); 
     if (!res) { throw new Win32Exception(Marshal.GetLastWin32Error()); } 
     return (new DirectoryInfo(lpSymlinkFileName)); 
    } 

    public static FileInfo CreateSymbolicLinkToFile(string lpSymlinkFileName, string lpTargetFileName) { 
     bool res = CreateSymbolicLink(lpSymlinkFileName, lpTargetFileName, 0); 
     if (!res) { throw new Win32Exception(Marshal.GetLastWin32Error()); } 
     return (new FileInfo(lpSymlinkFileName)); 
    } 
'@ -Name Win32 -NameSpace System -UsingNamespace System.ComponentModel, System.IO 
[Win32]::CreateSymbolicLinkToFolder("c:\Temp\bar", ".\foo") 
[Win32]::CreateSymbolicLinkToFile("c:\Temp\bar.txt", ".\foo\foo.txt") 

Sample4: Làm việc như mong đợi

#using mklink from cmd produces correct relative paths 
#.\foo and .\foo\foo.txt are returned 
cmd /c mklink /d "c:\Temp\bar" ".\foo" 
cmd /c mklink "c:\Temp\bar.txt" ".\foo\foo.txt" 
(Get-Item "c:\Temp\bar").Target 
(Get-Item "c:\Temp\bar.txt").Target 

Edit: Sample3 đã được cập nhật vào api unicode và GetLastError

+4

PowerShell 6 [dừng lại giải quyết] (https://github.com/PowerShell/PowerShell/commit/3a43126a2ea163f38c8d02c8177c79e954576ec6) New-mục của mục tiêu đến một đường dẫn đầy đủ cho symlink qua globbing resolver. Vì vậy, cho đến khi đó bạn sẽ phải sử dụng cách giải quyết. – wOxxOm

+0

@wOxxOm: cảm ơn bạn đã thông tin –

+2

@wOxxOm: Thật không may, cam kết bạn liên kết chỉ thêm khả năng nhắm mục tiêu các mục không tồn tại mà không thay đổi hành vi giải quyết đường dẫn được chỉ định tới đường dẫn tuyệt đối trước (ngay cả mục tiêu không tồn tại được chuyển thành đường dẫn tuyệt đối). Tôi đã tạo [vấn đề GitHub này] (https://github.com/PowerShell/PowerShell/issues/3500) để yêu cầu các mục tiêu tương đối. – mklement0

Trả lời

0

Bạn có thể thử thêm chức năng này để $ PROFILE của bạn .

Function SymbolicLink-Add 
{ 
[CmdLetBinding()] 
Param ([string] $File, [string] $SymbolicLinkFolder) 

$LinkFile = (Get-Item $File) 

if ($false -eq $LinkFile.Exists) 
{ 
    return "Cannot create symbolic link file does not exist: [$File]" 
} 

if ($false -eq (Test-Path $SymbolicLinkFolder)) 
{ 
    New-Item -Type Directory -Path $SymbolicLinkFolder 
    -ErrorAction Stop 
} 

New-Item -ItemType SymbolicLink -Path $SymbolicLinkFolder -Name 
$LinkFile.Name -Value $LinkFile 
} 
Các vấn đề liên quan