7
votes

Comment puis-je obtenir un chemin UNC actif dans DFS Programmatiquement

Compte tenu d'un chemin DFS Comment savoir quel est le chemin actif qu'il est actuellement sur de manière problématique?

pour EXMAPLE, j'ai 2 serveurs partage comme "\\ Server1 \ dossier \" et "\\ serveur2 \ dossier \" et il a été allumé de sorte que DFS est allumé peut être consulté sur "\\ dfs_server \ dossier \" , comment savoir quel est le chemin actif actuellement "\\ dfs_server \ dossier \" est activé, que ce soit est "\\ dossier1 \ dossier \" ou "\\ serveur2 \ dossier \" . .


0 commentaires

3 Réponses :


4
votes

Essayez ici où SDFSPATH est le chemin que vous souhaitez interroger et Shoststerver est le serveur que vous souhaitez interroger votre WMI, cela peut être l'un des deux serveurs que vous avez mentionnés ci-dessus. Vous pouvez même créer un code plus élégant lorsqu'il échoue sur le premier serveur, puis requête WMI sur les serveurs suivants xxx

espère que cela a du sens


2 commentaires

Comment le regard ci-dessus serait-il dans VBS utilisant WMI? Toute directive serait appréciée.


@Raymund Je vois que vous passez dans l'hôte. Comment obtiendriez-vous une liste de liens DFS? Aussi quel est le shoststerver? Est-ce un serveur DFS? Aussi, quel type d'autorisations sont nécessaires pour cela



7
votes

Si je comprends votre exigence correctement, il existe également une API qui semble faire ce dont vous avez besoin:

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


1 commentaires

Grande solution, pourriez-vous s'il vous plaît ajouter à l'aide de system.runtime.Interopservices; en haut?



4
votes

Merci, vos indices étaient utiles. Cependant, j'avais plus de succès avec NetdfsgetClientInfo. Également réalisé que le processus de résolution peut être récursif. J'ai fini par au moins 2 appels récursifs pour obtenir la part de la SCC physique actuelle et voici mon exemple.

Je ne sais pas, comment P>

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


4 commentaires

J'ai trouvé petit mode. Donc, la résolution DFS est recuble. En supposant que vous recherchez UNC A. Chaque itération Vous devez supprimer EntryPath depuis le début de A et le reconstruire (préfixe avec serveurName et nom de Sharename, que vous obtenez de STANDSInfo) Réception de l'UNC B. Si une résolution A == B est terminée.


NetdfsgetInfo déclenchait une erreur 1168 (non trouvée), qui est câblée, j'ai donc utilisé NetdfsgetClientInfo. Celui-ci renvoie des données uniquement pour le stockage actif. Pour un stockage non actif, il ne renvoie rien. Solution de contournement doit utiliser System.IO.Directory.exists (...) sur votre chemin UNC avant d'appeler NetDFsgetClientInfo.


NetdfsgetClientInfo peut-il être utilisé dans VBS, peut-être avec WMI?


Obtenir 2662 Code de Int Error = NetdFsgetClientInfo (DFSPATH, NULL, NULL, 3, OUT TAMPER); tous les pointeurs pour le résoudre,