2010-10-15 9 views
6

डीएफएस पथ को देखते हुए मुझे कैसे पता चलेगा कि यह वर्तमान में प्रोग्रामिक रूप से सक्रिय पथ क्या है।मैं डीएफएस में सक्रिय यूएनसी पथ कैसे प्रोग्राम कर सकता हूं

उदाहरण के लिए मैं "\\Server1\Folder\" और "\\Server2\Folder\" के रूप में 2 सर्वर शेयरों है और यह डीएफएस चालू तो यह "\\DFS_Server\Folder\" पर पहुँचा जा सकता है कि कैसे मैं पता होगा सक्रिय पथ है वर्तमान में "\\DFS_Server\Folder\" पर, चाहे वह "\\Server1\Folder\" या "\\Server2\Folder\" है क्या है।

उत्तर

4

यह कोशिश करें जहां एसडीएफएसपीएथ वह पथ है जिसे आप क्वेरी करना चाहते हैं और sHostServer वह सर्वर है जिसे आप अपने डब्लूएमआई से पूछना चाहते हैं, यह ऊपर उल्लेखित दो सर्वरों में से कोई भी हो सकता है। तुम भी तो अगले सर्वर पर WMI क्वेरी

public static ArrayList GetActiveServers(string sDFSPath, string sHostServer) 
{ 
    ArrayList sHostNames = new ArrayList(); 

    ManagementPath oManagementPath = new ManagementPath(); 
    oManagementPath.Server = sHostServer; 
    oManagementPath.NamespacePath = @"root\cimv2"; 

    oManagementScope = new ManagementScope(oManagementPath); 
    oManagementScope.Connect(); 

    SelectQuery oSelectQuery = new SelectQuery(); 
    oSelectQuery.QueryString = @"SELECT * FROM Win32_DfsTarget WHERE LinkName LIKE '%" + sDFSPath.Replace("\\", "\\\\") + "%' and State = 1"; 

    ManagementObjectSearcher oObjectSearcher = new ManagementObjectSearcher(oManagementScope, oSelectQuery); 
    ManagementObjectCollection oObjectCollection = oObjectSearcher.Get(); 

    if (oObjectCollection.Count != 0) 
    { 
     foreach (ManagementObject oItem in oObjectCollection) 
     { 
      sHostNames.Add(oItem.Properties["ServerName"].Value.ToString()); 
     } 
    } 

    return sHostNames; 
} 

आशा है कि यह भावना

+0

कैसे WMI का उपयोग करके करते VBS में ऊपर देखो? किसी भी मार्गदर्शन की सराहना की जाएगी। – Lizz

5

बनाता अगर मैं आपकी आवश्यकता सही ढंग से समझ, वहाँ भी है एक API कि लगता है जब वह पहली बार सर्वर पर विफल रहता है एक और अधिक सुरुचिपूर्ण कोड बना सकते हैं कि आप क्या जरूरत है:

// mscorlib (no additional assemblies needed) 
using System.Runtime.InteropServices; 

public static class Dfs 
{ 
    private enum NetDfsInfoLevel 
    { 
     DfsInfo1 = 1, 
     DfsInfo2 = 2, 
     DfsInfo3 = 3, 
     DfsInfo4 = 4, 
     DfsInfo5 = 5, 
     DfsInfo6 = 6, 
     DfsInfo7 = 7, 
     DfsInfo8 = 8, 
     DfsInfo9 = 9, 
     DfsInfo50 = 50, 
     DfsInfo100 = 100, 
     DfsInfo150 = 150, 
    } 

    [DllImport("netapi32.dll", SetLastError = true)] 
    private static extern int NetApiBufferFree(IntPtr buffer); 

    [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
    private static extern int NetDfsGetInfo(
     [MarshalAs(UnmanagedType.LPWStr)] string DfsEntryPath, // DFS entry path for the volume 
     [MarshalAs(UnmanagedType.LPWStr)] string ServerName, // This parameter is currently ignored and should be NULL 
     [MarshalAs(UnmanagedType.LPWStr)] string ShareName, // This parameter is currently ignored and should be NULL. 
     NetDfsInfoLevel Level,         // Level of information requested 
     out IntPtr Buffer          // API allocates and returns buffer with requested info 
     ); 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    private struct DFS_INFO_3 
    { 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string EntryPath; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string Comment; 
     public int State; 
     public int NumberOfStorages; 
     public IntPtr Storage; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    private struct DFS_STORAGE_INFO 
    { 
     public int State; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string ServerName; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string ShareName; 
    } 

    private static T GetStruct<T>(IntPtr buffer, int offset=0)where T:struct 
    { 
     T r = new T(); 
     r = (T) Marshal.PtrToStructure(buffer + offset * Marshal.SizeOf(r), typeof(T)); 
     return r; 
    } 

    public static string GetDfsInfo(string server) 
    { 
     string rval = null; 
     IntPtr b; 
     int r = NetDfsGetInfo(server, null, null, NetDfsInfoLevel.DfsInfo3, out b); 
     if(r != 0) 
     { 
      NetApiBufferFree(b); 

      // return passed string if not DFS 
      return rval; 
     } 

     DFS_INFO_3 sRes = GetStruct<DFS_INFO_3>(b); 
     if(sRes.NumberOfStorages > 0) 
     { 
      DFS_STORAGE_INFO sResInfo = GetStruct<DFS_STORAGE_INFO>(sRes.Storage); 
      rval = string.Concat(@"\\", sResInfo.ServerName, @"\", sResInfo.ShareName, @"\"); 
     } 

     NetApiBufferFree(b); 

     return rval; 
    } 
} 

इस तरह यह प्रयोग करें:

string dfsPath = @"\\DFS_Server\Folder\"; 
string share = Dfs.GetDfsInfo(dfsPath) 

के लिए एक एपीआई संदर्भ, NetDfsGetInfo, DFS_INFO_3, DFS_STORAGE_INFO और NetApiBufferFree पर msdn की जांच करें।

+0

ग्रेट सॉल्यूशन, क्या आप कृपया 'सिस्टम का उपयोग कर सकते हैं। रनटाइम.इंटरोप सर्विसेज;' शीर्ष पर? – MKesper

+0

@MKesper एक संपादन सुझाव सबमिट करने के लिए स्वतंत्र महसूस करें ... – takrl

4

धन्यवाद, आपके संकेत उपयोगी थे। हालांकि मैं NetDfsGetClientInfo के साथ और अधिक सफल था। यह भी महसूस किया कि हल करने की प्रक्रिया पुनरावर्ती हो सकती है। मैं वास्तविक शारीरिक यूएनसी शेयर प्राप्त करने के लिए कम से कम 2 रिकर्सिव कॉल के साथ समाप्त हुआ और यहां मेरा उदाहरण है।

मैं नहीं जानता, कैसे

public static class DFS 
{ 
    #region Import 

    [DllImport("Netapi32.dll", EntryPoint = "NetApiBufferFree")] 
    public static extern uint NetApiBufferFree(IntPtr Buffer); 

    [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
    public static extern int NetDfsGetInfo(
     [MarshalAs(UnmanagedType.LPWStr)] string EntryPath, 
     [MarshalAs(UnmanagedType.LPWStr)] string ServerName, 
     [MarshalAs(UnmanagedType.LPWStr)] string ShareName, 
     int Level, 
     out IntPtr Buffer); 

    [DllImport("Netapi32.dll")] 
    public static extern int NetDfsGetClientInfo(
     [MarshalAs(UnmanagedType.LPWStr)] string EntryPath, 
     [MarshalAs(UnmanagedType.LPWStr)] string ServerName, 
     [MarshalAs(UnmanagedType.LPWStr)] string ShareName, 
     int Level, 
     out IntPtr Buffer); 

    #endregion 

    #region Structures 

    public struct DFS_INFO_3 
    { 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string EntryPath; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string Comment; 
     public UInt32 State; 
     public UInt32 NumberOfStorages; 
     public IntPtr Storages; 
    } 

    public struct DFS_STORAGE_INFO 
    { 
     public Int32 State; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string ServerName; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string ShareName; 
    } 

    #endregion 

    const int DFS_VOLUME_STATE_OK = 0x00000001; 
    const int DFS_VOLUME_STATE_ONLINE = 0x00000004; 
    const int DFS_STORAGE_STATE_ONLINE = 0x00000002; 
    const int DFS_STORAGE_STATE_ACTIVE = 0x00000004; 

    public static String GetSharePath(String DFSPath) 
    { 
     if (!String.IsNullOrEmpty(DFSPath)) 
     { 
      IntPtr Buffer = IntPtr.Zero; 
      try 
      { 
       int Error = NetDfsGetClientInfo(DFSPath, null, null, 3, out Buffer); 
       if (Error == 0) 
       { 
        DFS_INFO_3 DFSInfo = (DFS_INFO_3)Marshal.PtrToStructure(Buffer, typeof(DFS_INFO_3)); 
        if ((DFSInfo.State & DFS_VOLUME_STATE_OK) > 0) 
        { 
         String SubPath = DFSPath.Remove(0, 1 + DFSInfo.EntryPath.Length).TrimStart(new Char[] { '\\' }); 
         for (int i = 0; i < DFSInfo.NumberOfStorages; i++) 
         { 
          IntPtr Storage = new IntPtr(DFSInfo.Storages.ToInt64() + i * Marshal.SizeOf(typeof(DFS_STORAGE_INFO))); 
          DFS_STORAGE_INFO StorageInfo = (DFS_STORAGE_INFO)Marshal.PtrToStructure(Storage, typeof(DFS_STORAGE_INFO)); 
          if ((StorageInfo.State & DFS_STORAGE_STATE_ACTIVE) > 0) 
          { 
           if (String.IsNullOrEmpty(SubPath)) 
           { 
            return String.Format(@"\\{0}\{1}", StorageInfo.ServerName, StorageInfo.ShareName); 
           } 
           else 
           { 
            return GetSharePath(String.Format(@"\\{0}\{1}\{2}", StorageInfo.ServerName, StorageInfo.ShareName, SubPath)); 
           } 
          } 
         } 
        } 
       } 
       else if (Error == 2662) 
        return DFSPath; 
      } 
      finally 
      { 
       NetApiBufferFree(Buffer); 
      } 
     } 
     return null; 
    } 

    public static String GetShareName(String SharePath) 
    { 
     if (!String.IsNullOrEmpty(SharePath)) 
     { 
      String[] Tokens = SharePath.Trim(new Char[] { '\\' }).Split(new Char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); 
      if (2 <= Tokens.Length) 
       return Tokens[1]; 
     } 
     return null; 
    } 
} 
+0

मुझे थोड़ा मोड मिला। तो डीएफएस संकल्प रिकर्सिव है। मान लीजिए कि आप एक के लिए देख रहे हैं। प्रत्येक पुनरावृत्ति आपको एंट्रीपाथ को ए की शुरुआत से हटाने की आवश्यकता है, और इसे पुनर्निर्माण (सर्वर नाम और शेयरनाम के साथ उपसर्ग, जिसे आप स्टोरेजइन्फो से प्राप्त करते हैं) को बिना बी प्राप्त करना। यदि एक == बी रिज़ॉल्यूशन पूरा हो गया है। – user3042599

+0

NetDfsGetInfo त्रुटि 1168 (नहीं मिला) ट्रिगर कर रहा था, जो वायर्ड है, इसलिए मैंने NetDfsGetClientInfo का उपयोग किया। यह केवल सक्रिय भंडारण के लिए डेटा देता है। गैर सक्रिय भंडारण के लिए यह कुछ भी नहीं देता है। वर्कअराउंड-हैक NetDfsGetClientInfo को कॉल करने से पहले अपने unc पथ पर System.IO.Directory.Exists (...) का उपयोग करना है। – user3042599

+0

क्या NetDfsGetClientInfo का उपयोग वीबीएस में किया जा सकता है, शायद डब्लूएमआई के साथ? – Lizz

संबंधित मुद्दे