【问题标题】:Checking for equivalent shared folders in .net检查 .net 中的等效共享文件夹
【发布时间】:2008-11-04 20:13:43
【问题描述】:

有没有办法在 .net 框架内检查两个不同的共享文件夹是否实际上指向同一个物理目录? Windows 中的目录是否具有某种唯一标识符? Google-fu 让我失望了。

(我的意思是,除了将临时文件写入一个文件并查看它是否出现在另一个文件中)

编辑:我想我已经找到了我需要的东西,感谢 Brody 让我在 System.Management 命名空间中指明了正确的方向。

【问题讨论】:

  • 共享文件夹是什么意思?网络共享?

标签: .net windows wmi wmi-query shared-directory


【解决方案1】:

如果您不使用 WMI,则非托管调用是 NetShareEnum,服务器名称为 NULL(本地计算机),级别为 502,以获取 SHARE_INFO_502 结构。本地路径在shi502_path中。

P/Invoke info 一如既往地在 pinvoke.net 结束。

【讨论】:

    【解决方案2】:

    您可以使用 System.Management 命名空间检查共享定义本身,但使用起来并不容易。

    它开始像

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

    之后情况变得更糟。我用它来创建共享。希望您可以将其用于每个共享的路径并进行比较。

    【讨论】:

      【解决方案3】:

      我认为 .NET 框架没有提供比较两个目录所需的信息... 你必须采取一种不受管理的方法。我就是这样做的:

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

      有效!希望这会有所帮助。

      干杯。

      【讨论】:

        【解决方案4】:

        我相信使用 WMI 查询可以解决我需要做的事情:

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

        Path 属性会给我共享的物理路径,我可以用它来比较两个共享。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-10
          • 2017-12-16
          • 1970-01-01
          相关资源
          最近更新 更多