2009-09-28 17 views

cevap

18

ben sizi sağlayacak bazı source code for symlinks posted on my blog var:

  • symlinks bir yol
  • Bir sembolik bağın hedefi almak sembolik olup olmadığını
  • çek oluşturmak

Ayrıca içerir Uzatmak isteyebileceğiniz NUnit test senaryoları.

etli bit:

private static SafeFileHandle getFileHandle(string path) 
{ 
    return CreateFile(path, genericReadAccess, shareModeAll, IntPtr.Zero, openExisting, 
     fileFlagsForOpenReparsePointAndBackupSemantics, IntPtr.Zero); 
} 

public static string GetTarget(string path) 
{ 
    SymbolicLinkReparseData reparseDataBuffer; 

    using (SafeFileHandle fileHandle = getFileHandle(path)) 
    { 
     if (fileHandle.IsInvalid) 
     { 
      Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); 
     } 

     int outBufferSize = Marshal.SizeOf(typeof(SymbolicLinkReparseData)); 
     IntPtr outBuffer = IntPtr.Zero; 
     try 
     { 
      outBuffer = Marshal.AllocHGlobal(outBufferSize); 
      int bytesReturned; 
      bool success = DeviceIoControl(
       fileHandle.DangerousGetHandle(), ioctlCommandGetReparsePoint, IntPtr.Zero, 0, 
       outBuffer, outBufferSize, out bytesReturned, IntPtr.Zero); 

      fileHandle.Close(); 

      if (!success) 
      { 
       if (((uint)Marshal.GetHRForLastWin32Error()) == pathNotAReparsePointError) 
       { 
        return null; 
       } 
       Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); 
      } 

      reparseDataBuffer = (SymbolicLinkReparseData)Marshal.PtrToStructure(
       outBuffer, typeof(SymbolicLinkReparseData)); 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(outBuffer); 
     } 
    } 
    if (reparseDataBuffer.ReparseTag != symLinkTag) 
    { 
     return null; 
    } 

    string target = Encoding.Unicode.GetString(reparseDataBuffer.PathBuffer, 
     reparseDataBuffer.PrintNameOffset, reparseDataBuffer.PrintNameLength); 

    return target; 
} 

olduğu sonucunu verir:

  • Açık NOT (yeniden ayrıştırma noktası veri almak için CreateFile()
  • Çağrısı DeviceIoControl() ile dosyası: Bir kavşak noktası olabilir !) Denetlemek için returned data structure'a bakın. reparse tag, bir bağlantı noktası veya sembolik bir bağlantı olup olmadığını söyleyecektir. Tüm yapmak istediğin bu olabilir.
+0

Eğer mümkünse, buraya yapıştırın, tam kodu, blong'a girebilir, yoksa derleme yapamaz mısın? – TarmoPikaro

+0

Bu kod şu anda bir [NuGet paketi] (https://www.nuget.org/packages/SymbolicLinkSupport/) ve [GitHub'dadır] (https://github.com/michaelmelancon/symboliclinksupport) –

0

GetFileInformationByHandle bit dosyanın özelliklerine (ayrıntılar here) ilişkin bilgilerin yer aldığı ayarlanır bir alan dwFileAttributes olan bir BY_HANDLE_FILE_INFORMATION yapısını doldurur. Özellikle, ... maske de biraz bakmak:

FILE_ATTRIBUTE_REPARSE_POINT 1024 0x0400

bir ilişkili yeniden ayrıştırma noktası veya sembolik bağlantı olan bir dosyayı sahip bir dosya veya dizin.

+0

Ben uygular buna inanıyorum System.IO.File.GetAttributes() metodu kullanılarak denedim, ancak yalnızca Sembolik Linkler Kavşak Noktaları üzerinde çalışmak gibi görünüyor, değil. – mattdwen

+0

Sistemin kendisini deneyebilir misiniz? Bunu kendim denemek için elimde Vista yok. –

+0

Aynı şey - 32 almak, sadece Arşiv. Bu yöntemi iptal etmek ve Hard Links kullanmak zorunda kalabileceğimi öğrendim, ancak bunu anlamak güzel olurdu. – mattdwen

1

this answer göre bir dosya ReparsePoint biraz sembolik PowerShell bağlantı, (File.GetAttributes aracılığıyla) dosyası için System.IO.FileAttributes alma ve test olup olmadığını öğrenin Taşma soruyu Stack için çalışır. Bit ayarlanmışsa, bir bağlantı noktası veya bir bağlantı noktasıdır. Değilse, normal bir dosyadır (veya hardlink).

+0

Tekrar, ReparsePoint'e güvenmek yeterli değildir. – Joshua

7

Dosya ve dizin bağlantılarına olan bağlantılardan dosya ve dizinleri ayırt etmek için bir örnek aşağıdadır.

Linkler ya dosyaları veya dizinleri kendi nitelikleri (oluşturulma tarihi, izinleri) hedefleri ayrı muhafaza etmek.

Dosya bağlantıları hedef dosya etkilemeden (örneğin, "del" kullanarak) silinebilir.

Dizin bağlantılar hedef dizini etkilemeden (örneğin, "rmdir") çıkarılabilir. "Rd/s" kullanırken dikkatli olun. Bu, dizin bağlantı hedefini kaldıracaktır.

anahtar FileAttributes bayrak hem FileInfo kontrol etmek ve DirectoryInfoFileAttributes.ReparsePoint olup.

static void Main(string[] args) { 
FileInfo file_info = new FileInfo(args[0]); 
DirectoryInfo directory_info = new DirectoryInfo(args[0]); 

bool is_file = file_info.Exists; 
bool is_directory = directory_info.Exists; 

if (is_file) { 
    Console.WriteLine(file_info.ToString() + " is a file"); 

    if (file_info.Attributes.HasFlag(FileAttributes.ReparsePoint)) 
     Console.WriteLine(args[0] + " is a Windows file link"); 
} 
else if (is_directory) { 
    Console.WriteLine(directory_info.ToString() + " is a directory"); 

    if (directory_info.Attributes.HasFlag(FileAttributes.ReparsePoint)) 
     Console.WriteLine(args[0] + " is a Windows directory link"); 
} 
+0

İlana bakım d bir açıklama? Kod sadece bazen iyi ama cevabınızı tanımlamak için birkaç kelime uzun bir yol olabilir. –

+0

Teşekkür ederim Okuma.Scott –

+2

Yine, FileAttributes.ReparsePoint'e güvenmek yeterli değildir. – konsolebox

20
private bool IsSymbolic(string path) 
{ 
    FileInfo pathInfo = new FileInfo(path); 
    return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint); 
} 
+2

Bu kabul edilen cevap olmalı. Bu basit, özlü ve doğrudan soruyu cevaplar. –

+0

Bu çözüm hakkında kabul edilemez bir çözüme karşı eksik bir şey var mı? Çünkü bu daha güzel görünüyor. –

+5

Sadece bir dosya ile ilişkili bir yeniden ayrıştırma noktası olduğundan sembolik bir bağlantı olduğu anlamına gelmez. Yeniden ayrılma noktası, yalnızca bir dosyayla ilişkilendirilmiş rastgele bir özel veri kümesidir. Sembolik bir bağın gerçekten tanımlanıp tanımlanmadığını belirlemek için yeniden ayrıştırma noktası verilerinin kimliğini incelemeniz gerekir. Bu cevap, redaksiyon puanları ile gerçek bir dosya ile karşılaştığı zaman yanlış pozitifler verecektir. Buraya bakın: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx –

İlgili konular