Question

Je veux écrire un programme qui montre les fichiers d'un autre disque dur avec des liens. Je veux garder les deux liens physiques cohérents dans le nom de fichier et d'autres choses, donc je dois obtenir une fonction / méthode où je peux énumérer tous les liens durs actuels d'un fichier.

Ainsi, par exemple:

J'ai un fichier C: \ file.txt et un second lien difficile à D: \ file.txt
. Alors je renomme D: \ file.txt à D: \ file_new.txt. Je veux maintenant être en mesure de renommer aussi le hardlink sur le lecteur C ainsi.
Donc je besoin d'une fonction qui retourne D: \ file_new.txt il y a les liens physiques suivants:
C: \ file.txt
D: \ file_new.txt
alors je peux renommer le lien dur C: \ également obtenir D: \ file_new.txt

Je dois donc obtenir tous les liens durs d'un fichier physique. Ou: Tous les liens durs d'un fichier adressés avec un lien dur

.

L'espoir quelqu'un peut aider!

Edit:

Oliver a remarqué que les liens durs ne peuvent pas être utilisés sur les disques differnt. merci ... Je tends la question: Que dois-je besoin? Points de jonction? Liens symboliques? Il devrait également travailler avec des fichiers non seulement avec des dossiers!

Était-ce utile?

La solution 4

J'ai trouvé une solution:

D'abord, je n'ai pas à utiliser des liens durs (car ils ne peuvent pointer vers un autre disque). Je dois utiliser des liens symboliques à la place. J'ai donc un fichier lié dur sur le disque d'origine et les liens symboliques sur d'autres disques à ce fichier. La limitation est OS doit être Vista ou plus récent.

Deuxièmement, je dois être en mesure de savoir où le lien symbolique pointe. Ici, je trouve un bon exemple comment trouver l'information nécessaire: http://www.codeproject.com/KB/vista/ReparsePointID.aspx

La seule chose que je ne réussi est de trouver tous les liens symboliques à partir d'un fichier spécifique (lien dur). Je suppose qu'il n'y a pas de la solution de boîte et je dois récursif tous les liens symboliques et de tester la cible. Mais dans mon cas, c'est pas de problème.

J'espère que d'autres d'aide peut!

Autres conseils

le code suivant devrait bien fonctionner (à l'origine postet par Peter provost sur PowerShell Code de dépôt):

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;

namespace HardLinkEnumerator
{
   public static class Kernel32Api
   {
       [StructLayout(LayoutKind.Sequential)]
       public struct BY_HANDLE_FILE_INFORMATION
       {
           public uint FileAttributes;
           public FILETIME CreationTime;
           public FILETIME LastAccessTime;
           public FILETIME LastWriteTime;
           public uint VolumeSerialNumber;
           public uint FileSizeHigh;
           public uint FileSizeLow;
           public uint NumberOfLinks;
           public uint FileIndexHigh;
           public uint FileIndexLow;
       }

       [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
       static extern SafeFileHandle CreateFile(
           string lpFileName,
           [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
           [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
           IntPtr lpSecurityAttributes,
           [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
           [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
           IntPtr hTemplateFile);

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

       [DllImport("kernel32.dll", SetLastError = true)]
       [return: MarshalAs(UnmanagedType.Bool)]
       static extern bool CloseHandle(SafeHandle hObject);

       [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
       static extern IntPtr FindFirstFileNameW(
           string lpFileName,
           uint dwFlags,
           ref uint stringLength,
           StringBuilder fileName);

       [DllImport("kernel32.dll", SetLastError = true, CharSet=CharSet.Unicode)]
       static extern bool FindNextFileNameW(
           IntPtr hFindStream,
           ref uint stringLength,
           StringBuilder fileName);

       [DllImport("kernel32.dll", SetLastError = true)]
       static extern bool FindClose(IntPtr fFindHandle);

       [DllImport("kernel32.dll")]
       static extern bool GetVolumePathName(string lpszFileName,
           [Out] StringBuilder lpszVolumePathName, uint cchBufferLength);

       [DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
       static extern bool PathAppend([In, Out] StringBuilder pszPath, string pszMore);

       public static int GetFileLinkCount(string filepath)
       {
           int result = 0;
           SafeFileHandle handle = CreateFile(filepath, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Archive, IntPtr.Zero);
           BY_HANDLE_FILE_INFORMATION fileInfo = new BY_HANDLE_FILE_INFORMATION();
           if (GetFileInformationByHandle(handle, out fileInfo))
               result = (int)fileInfo.NumberOfLinks;
           CloseHandle(handle);
           return result;
       }

       public static string[] GetFileSiblingHardLinks(string filepath)
       {
           List<string> result = new List<string>();
           uint stringLength = 256;
           StringBuilder sb = new StringBuilder(256);
           GetVolumePathName(filepath, sb, stringLength);
           string volume = sb.ToString();
           sb.Length = 0; stringLength = 256;
           IntPtr findHandle = FindFirstFileNameW(filepath, 0, ref stringLength, sb);
           if (findHandle.ToInt32() != -1)
           {
               do
               {
                   StringBuilder pathSb = new StringBuilder(volume, 256);
                   PathAppend(pathSb, sb.ToString());
                   result.Add(pathSb.ToString());
                   sb.Length = 0; stringLength = 256;
               } while (FindNextFileNameW(findHandle, ref stringLength, sb));
               FindClose(findHandle);
               return result.ToArray();
           }
           return null;
       }

   }
}

Peut-être que je méprendre à vos questions, mais les liens physiques ne peuvent pas aller d'un disque à l'autre. Ils ne peuvent exister que sur un seul disque.

Dans le .Net Framwork il n'y a pas de support pour obtenir ces informations. Mais l'API Win32 peut vous fournir ces informations.

Jetez un oeil à cet article . Il peut vous aider.

Mise à jour

Pour autant que je sais que ce n'est pas possible de le faire entre les différents lecteurs. Points de jonction ne sont certainement pas votre ami parce que ça ne fonctionne que sur Foldes. Mais après avoir lu cet article wikipedia il semble que vous pouvez le faire sur Vista et Win7 avec des liens symboliques. Il y a aussi un lien vers cette extension shell qui semble tout de couverture que vous pouvez faire avec ces NTFS fonctionnalités spéciales. Peut-être avec cela, vous pouvez vérifier si votre objectif est accessible et peut-être vérifier ensuite le MSDN pour la fonction API Win32 désirée.

essayer:

using System.IO;

string[] filePathsC = Directory.GetFiles(@"c:\");
string[] filePathsD = Directory.GetFiles(@"d:\");

et la boucle à travers les tableaux, trouver les fichiers et changer le nom

EDIT: En lisant les commentaires, je sais que je répondu avant que je sache quel est hardlink. Je me rends compte maintenant que cette réponse ne contribue pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top