42

ファイルが本物かシンボリック リンクかを C# を使用して判断する方法はありますか?

MSDN W32 docsを掘り下げましたが、これを確認するためのものが見つかりません。ここから CreateSymbolicLink を使用していますが、正常に動作しています。

4

8 に答える 8

57
private bool IsSymbolic(string path)
{
    FileInfo pathInfo = new FileInfo(path);
    return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint);
}
于 2014-10-20T20:04:55.950 に答える
26

私のブログに投稿されたシンボリックリンクのソースコードがいくつかあります。これにより、次のことが可能になります。

  • シンボリックリンクを作成する
  • パスがシンボリックリンクかどうかを調べる
  • シンボリックリンクのターゲットを取得する

また、拡張したい NUnit テスト ケースも含まれています。

肉のビットは次のとおりです。

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;
}

あれは:

  • でファイルを開きますCreateFile()
  • 再解析ポイント データを取得するための呼び出しDeviceIoControl()(注: 接合ポイントである可能性があります!)
  • 返されたデータ構造をチェックアウトして検査します。reparseタグは、それがジャンクション ポイントかシンボリック リンクかを示します。やりたいことはこれだけかもしれません。
于 2012-03-27T03:02:49.510 に答える
0

GetFileInformationByHandledwFileAttributesは、ファイルの属性に関する情報でビットが設定されるフィールドを持つ BY_HANDLE_FILE_INFORMATION 構造体を埋めます(詳細はこちら)。特に、マスクのビットを見てください...:

FILE_ATTRIBUTE_REPARSE_POINT 1024 0x0400

関連する再解析ポイントを持つファイルまたはディレクトリ、またはシンボリック リンクであるファイル。

于 2009-09-28T02:42:13.727 に答える
0

スタック オーバーフローの質問に対するこの回答によれば、ファイルが PowerShell のシンボリック リンクであるかどうかを確認し、ファイルのSystem.IO.FileAttributesを取得し( File.GetAttributes を介して)、ReparsePoint ビットのテストが機能します。ビットが設定されている場合、それはシンボリック リンクまたはジャンクション ポイントです。そうでない場合は、通常のファイル (またはハードリンク) です。

于 2010-02-12T22:31:41.743 に答える
0

私はパーティーに遅れていることを知っていますが、同じ質問を調査しているときにこの議論を見つけました

以下が私のために働いていることがわかったので、他の人に使用する場合に投稿すると思いました

それはこのように動作します:-

var provider = ReparsePointFactory.Provider;

var link = provider.GetLink(@"c:\program files (x86)\common files\microsoft shared\vgx\vgx.dll");

MsgBox("Link Type: " + link.Type.ToString + " Link Target: " + link.Target + " Link Attributes: " + link.Attributes.ToString);

https://github.com/NCodeGroup/NCode.ReparsePoints https://www.nuget.org/packages/NCode.ReparsePoints/

于 2020-10-10T16:26:34.693 に答える