ファイルが本物かシンボリック リンクかを C# を使用して判断する方法はありますか?
MSDN W32 docsを掘り下げましたが、これを確認するためのものが見つかりません。ここから CreateSymbolicLink を使用していますが、正常に動作しています。
ファイルが本物かシンボリック リンクかを C# を使用して判断する方法はありますか?
MSDN W32 docsを掘り下げましたが、これを確認するためのものが見つかりません。ここから CreateSymbolicLink を使用していますが、正常に動作しています。
private bool IsSymbolic(string path)
{
FileInfo pathInfo = new FileInfo(path);
return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint);
}
私のブログに投稿されたシンボリックリンクのソースコードがいくつかあります。これにより、次のことが可能になります。
また、拡張したい 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()
(注: 接合ポイントである可能性があります!)GetFileInformationByHandledwFileAttributes
は、ファイルの属性に関する情報でビットが設定されるフィールドを持つ BY_HANDLE_FILE_INFORMATION 構造体を埋めます(詳細はこちら)。特に、マスクのビットを見てください...:
FILE_ATTRIBUTE_REPARSE_POINT
1024 0x0400関連する再解析ポイントを持つファイルまたはディレクトリ、またはシンボリック リンクであるファイル。
スタック オーバーフローの質問に対するこの回答によれば、ファイルが PowerShell のシンボリック リンクであるかどうかを確認し、ファイルのSystem.IO.FileAttributesを取得し( File.GetAttributes を介して)、ReparsePoint ビットのテストが機能します。ビットが設定されている場合、それはシンボリック リンクまたはジャンクション ポイントです。そうでない場合は、通常のファイル (またはハードリンク) です。
私はパーティーに遅れていることを知っていますが、同じ質問を調査しているときにこの議論を見つけました
以下が私のために働いていることがわかったので、他の人に使用する場合に投稿すると思いました
それはこのように動作します:-
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/