Domanda

Esiste un modo, all'interno del framework .net, di verificare se due diverse cartelle condivise puntano effettivamente alla stessa directory fisica? Le directory in Windows hanno una sorta di identificatore univoco? Google-fu mi sta fallendo.

(Voglio dire, oltre a scrivere un file temporaneo su uno e vedere se appare nell'altro)

Modifica: penso di aver scoperto ciò di cui ho bisogno, grazie a Brody per avermi indirizzato nella giusta direzione nello spazio dei nomi System.Management.

È stato utile?

Soluzione 4

Credo che l'uso delle query WMI si occuperà di ciò che devo fare:

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"]);
}

E l'attributo Path mi darà il percorso fisico della condivisione, che posso usare per confrontare le due condivisioni.

Altri suggerimenti

Se non si utilizza WMI, la chiamata non gestita è NetShareEnum con un nomeserver di NULL (computer locale) e un livello di 502 per ottenere un SHARE_INFO_502 struct. Il percorso locale è in shi502_path.

P / Invoke info , come sempre, è finito su pinvoke.net.

Puoi esaminare la definizione della condivisione stessa usando lo spazio dei nomi System.Management ma non è facile da usare.

inizia qualcosa come

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

E dopo ciò peggiora molto. L'ho usato per creare una condivisione. Spero che tu possa usarlo nel percorso per ogni condivisione e confrontare.

Penso che .NET Framework non fornisca le informazioni necessarie per confrontare 2 directory ... Devi adottare un approccio non gestito. Ecco come l'ho fatto:

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

Funziona! Spero che questo aiuti.

Saluti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top