有没有一种方法来告诉使用C#如果文件是真实的还是符号链接?
我已经通过MSDN文档W32(挖http://msdn.microsoft.com/en-us/library/aa364232(VS.85).aspx ),并不能找到用于检查的事。 我使用CreateSymbolicLink从这里,和它的正常工作。
有没有一种方法来告诉使用C#如果文件是真实的还是符号链接?
我已经通过MSDN文档W32(挖http://msdn.microsoft.com/en-us/library/aa364232(VS.85).aspx ),并不能找到用于检查的事。 我使用CreateSymbolicLink从这里,和它的正常工作。
我有一些用于贴在我的博客符号链接的源代码 ,让您可以:
它还包含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()
以获得重分析点数据(注:这可能是一个结点!) private bool IsSymbolic(string path)
{
FileInfo pathInfo = new FileInfo(path);
return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint);
}
下面是从文件的链接和链接目录区分的文件和目录的例子。
链接到任何文件或目录维护自己的属性(创建日期,权限)从他们的目标分开。
文件链接可以(例如,使用“德尔”),而不会影响目标文件被删除。
目录链接可以在不影响目标目录中删除(如“命令rmdir”)。 使用“次/秒”时要小心。 这将删除目录链接目标。
关键FileAttributes
标志既要检查FileInfo
和DirectoryInfo
是FileAttributes.ReparsePoint
。
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");
}
根据这个答案对堆栈溢出问题找出一个文件是否在PowerShell中的符号链接 ,获得System.IO.FileAttributes的文件(通过File.GetAttributes ),以及测试的ReparsePoint位的作品。 如果该位被设置,它是一个符号或一个结点。 如果不是,它是一个普通文件(或硬链接)。
GetFileInformationByHandle填补了BY_HANDLE_FILE_INFORMATION结构具有场dwFileAttributes
其中位设置有大约在文件的属性(详细信息点击这里 )。 特别是,看在面具有点...:
FILE_ATTRIBUTE_REPARSE_POINT
1024的0x0400文件或目录具有关联的重分析点,或一个文件,是一个符号链接。
它证明了以上的回答都是不可靠的。 最后我得到了正确的解决方案MSDN :
要确定是否指定的目录是一个安装夹,首先调用GetFileAttributes功能并检查FILE_ATTRIBUTE_REPARSE_POINT标志在返回值中,以查看是否该目录都有一个关联的重分析点。 如果是这样,使用和用FindFirstFile功能FindNextFile获得在WIN32_FIND_DATA结构的dwReserved0构件重分析标记。 以确定是否重新分析点是已安装的文件夹(而不是重新分析点的一些其它形式的),测试该标记值是否等于值IO_REPARSE_TAG_MOUNT_POINT。 欲了解更多信息,请参阅解析点。