Possible Duplicate:
Best way to determine if two path reference to same file in C#
There are several ways to specify a directory location.
For example:
\\machineName\c$\rootPath\subPath
\\machineName\shareName (share pointing to subPath)
C:\rootPath\subPath
subPath (relative path if already in C:\rootPath
I need to determine that all of these paths "equal" each other (are really the same physical location on the hard drive).
Is there any way I can do this in C#?
As Oded states this is tricky to do in .Net. You could possibly cheat (depening on your exact requirements and permissions etc) by writing a file with a long randomly generated filename to the location and then seeing if you can see it from the other location. Bit of a hack but this is a pretty sound test I think, rather than relying on resolving mapped drives etc etc.
Ok many apologies for the VB - it's all I've got on this tiny netbook... C# wouldn't be too different...
usage eg
If sameLocation("\\machineName\c$\rootPath\subPath","\\machineName\shareName") Then...
Public Function sameLocation(ByVal sPath1 As String, ByVal sPath2 As String) As TriState
Dim sFile As String = randomFilename()
Dim sFullPath1 As String = sPath1 & "\" & sFile
Dim sFullPath2 As String = sPath2 & "\" & sFile
Dim bReturn As Boolean = False
Try
Dim fs As New FileStream(sFullPath1, FileMode.CreateNew)
fs.Close()
Catch ex As Exception
Return TriState.UseDefault
End Try
Try
bReturn = File.Exists(sFullPath2)
Catch ex As Exception
Return TriState.UseDefault
End Try
File.Delete(sFullPath1)
Return bReturn
End Function
Public Function randomFilename() As String
Dim r As New Random
Randomize(My.Computer.Clock.TickCount)
Dim sb As New StringBuilder
Dim chars As Int16 = 100
While chars > 0
chars -= 1
sb.Append(Chr(r.Next(26) + 65))
End While
Return sb.ToString
End Function
You could add more security, ie reading the timestamp etc...
You need to use GetFileInformationByHandle.
Check out this answer in StackOverflow and MSDN help.
Here is a method I wrote that works with directories:
using System;
using System.Runtime.InteropServices;
namespace CompareByPath
{
public static class DirectoryHelper
{
// all user defined types copied from
// http://pinvoke.net/default.aspx/kernel32.CreateFile
// http://pinvoke.net/default.aspx/kernel32.GetFileInformationByHandle
// http://pinvoke.net/default.aspx/kernel32.CloseHandle
public const short INVALID_HANDLE_VALUE = -1;
struct BY_HANDLE_FILE_INFORMATION
{
public uint FileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
public uint VolumeSerialNumber;
public uint FileSizeHigh;
public uint FileSizeLow;
public uint NumberOfLinks;
public uint FileIndexHigh;
public uint FileIndexLow;
}
[Flags]
public enum EFileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000
}
[Flags]
public enum EFileShare : uint
{
None = 0x00000000,
Read = 0x00000001,
Write = 0x00000002,
Delete = 0x00000004
}
[Flags]
public enum EFileAttributes : uint
{
Readonly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Directory = 0x00000010,
Archive = 0x00000020,
Device = 0x00000040,
Normal = 0x00000080,
Temporary = 0x00000100,
SparseFile = 0x00000200,
ReparsePoint = 0x00000400,
Compressed = 0x00000800,
Offline = 0x00001000,
NotContentIndexed = 0x00002000,
Encrypted = 0x00004000,
Write_Through = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}
public enum ECreationDisposition : uint
{
New = 1,
CreateAlways = 2,
OpenExisting = 3,
OpenAlways = 4,
TruncateExisting = 5
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetFileInformationByHandle(IntPtr hFile, out BY_HANDLE_FILE_INFORMATION lpFileInformation);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
static extern IntPtr CreateFile(String lpFileName, UInt32 dwDesiredAccess, UInt32 dwShareMode, IntPtr lpSecurityAttributes, UInt32 dwCreationDisposition, UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
public static bool CompareDirectories(string d1, string d2)
{
bool result = false;
BY_HANDLE_FILE_INFORMATION info1;
BY_HANDLE_FILE_INFORMATION info2;
IntPtr fileHandle1 = CreateFile(d1, (uint)EFileAccess.GenericRead, (uint)EFileShare.Read, IntPtr.Zero, (uint)ECreationDisposition.OpenExisting, (uint)(EFileAttributes.Directory | EFileAttributes.BackupSemantics), IntPtr.Zero);
if (fileHandle1.ToInt32() != INVALID_HANDLE_VALUE)
{
bool rc = GetFileInformationByHandle(fileHandle1, out info1);
if ( rc )
{
IntPtr fileHandle2 = CreateFile(d2, (uint)EFileAccess.GenericRead, (uint)EFileShare.Read, IntPtr.Zero, (uint)ECreationDisposition.OpenExisting, (uint)(EFileAttributes.Directory | EFileAttributes.BackupSemantics), IntPtr.Zero);
if (fileHandle2.ToInt32() != INVALID_HANDLE_VALUE)
{
rc = GetFileInformationByHandle(fileHandle2, out info2);
if ( rc )
{
if (( info1.FileIndexHigh == info2.FileIndexHigh) &&
( info1.FileIndexLow == info2.FileIndexLow) &&
( info1.VolumeSerialNumber == info2.VolumeSerialNumber))
{
result = true;
}
}
}
CloseHandle(fileHandle2);
}
}
CloseHandle(fileHandle1);
return result;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With