Pregunta

¿Hay alguna forma, dentro del marco .net, de verificar si dos carpetas compartidas diferentes apuntan realmente al mismo directorio físico? ¿Los directorios en Windows tienen algún tipo de identificador único? Google-fu me está fallando.

(Quiero decir, aparte de escribir un archivo temporal en uno y ver si aparece en el otro)

Editar: creo que he descubierto lo que necesito, gracias a Brody por hacerme apuntar en la dirección correcta en el espacio de nombres System.Management.

¿Fue útil?

Solución 4

Creo que el uso de consultas WMI se encargará de lo que necesito hacer:

Connection options = new ConnectionOptions();
ManagementScope scpoe = new ManagementScope("\\\\Server\\root\\cimv2", options);
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Share WHERE Name = '" + name +"'")

ManagementObjectSearcher searcher = new ManagementObjectSearch(scope, query);
ManagementObjectCollection qc = searcher.Get();

foreach (ManagementObject m in qc) {
    Console.WriteLine(m["Path"]);
}

Y el atributo Ruta me dará la ruta física del recurso compartido, que puedo usar para comparar los dos recursos compartidos.

Otros consejos

Si no va a WMI, la llamada no administrada es NetShareEnum con un nombre de servidor NULL (computadora local) y un nivel de 502 para obtener un SHARE_INFO_502 struct. La ruta local está en shi502_path.

P / Invocar información , como siempre, ha terminado en pinvoke.net.

Puede examinar la definición del recurso compartido en sí utilizando el espacio de nombres System.Management, pero no es fácil de usar.

comienza algo como

ManagementClass management = new ManagementClass("\\\\.\\root\\cimv2", "Win32_Share", null)

Y se pone mucho peor después de eso. Lo he usado para crear un recurso compartido. Esperemos que pueda usarlo en la ruta para cada recurso compartido y comparar.

Creo que .NET Framework no proporciona la información que necesita para comparar 2 directorios ... Tienes que tomar un enfoque no administrado. Así es como lo hice:

class Program
{
    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;
    }

    //
    // CreateFile constants
    //
    const uint FILE_SHARE_READ = 0x00000001;
    const uint FILE_SHARE_WRITE = 0x00000002;
    const uint FILE_SHARE_DELETE = 0x00000004;
    const uint OPEN_EXISTING = 3;

    const uint GENERIC_READ = (0x80000000);
    const uint GENERIC_WRITE = (0x40000000);

    const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
    const uint FILE_READ_ATTRIBUTES = (0x0080);
    const uint FILE_WRITE_ATTRIBUTES = 0x0100;
    const uint ERROR_INSUFFICIENT_BUFFER = 122;
    const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;


    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr CreateFile(
        string lpFileName,
        uint dwDesiredAccess,
        uint dwShareMode,
        IntPtr lpSecurityAttributes,
        uint dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool GetFileInformationByHandle(IntPtr hFile, out BY_HANDLE_FILE_INFORMATION lpFileInformation);

    static void Main(string[] args)
    {
        string dir1 = @"C:\MyTestDir";
        string dir2 = @"\\myMachine\MyTestDir";
        Console.WriteLine(CompareDirectories(dir1, dir2));
    }

    static bool CompareDirectories(string dir1, string dir2)
    {
        BY_HANDLE_FILE_INFORMATION fileInfo1, fileInfo2;
        IntPtr ptr1 = CreateFile(dir1, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING,  FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);
        if ((int)ptr1 == -1)
        {
            System.ComponentModel.Win32Exception t = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
            Console.WriteLine(dir1 + ": " + t.Message);
            return false;
        }
        IntPtr ptr2 = CreateFile(dir2, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING,  FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);
        if ((int)ptr2 == -1)
        {
            System.ComponentModel.Win32Exception t = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
            Console.WriteLine(dir2 + ": " + t.Message);
            return false;
        }
        GetFileInformationByHandle(ptr1, out fileInfo1);
        GetFileInformationByHandle(ptr2, out fileInfo2);

        return ((fileInfo1.FileIndexHigh == fileInfo2.FileIndexHigh) &&
            (fileInfo1.FileIndexLow == fileInfo2.FileIndexLow));
    }
}

¡Funciona! Espero que esto ayude.

Saludos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top