Existe-t-il un moyen de créer un point de jonction NTFS en Python? Je sais que je peux appeler l'utilitaire junction
, mais il serait préférable de ne pas compter sur des outils externes.Créer un point de jonction NTFS en Python
Répondre
J'ai répondu à cela dans un similar question, donc je vais copier ma réponse ci-dessous. Depuis l'écriture de cette réponse, j'ai fini par écrire un module python seulement (si vous pouvez appeler un module qui utilise ctypes python seulement) pour créer, lire et vérifier les jonctions qui peuvent être trouvées dans this folder. J'espère que cela pourra aider.
De même, contrairement à la réponse qui utilise l'API CreateSymbolicLinkA, l'implémentation liée doit fonctionner sur n'importe quelle version de Windows prenant en charge les jonctions. CreateSymbolicLinkA est uniquement pris en charge dans Vista +.
Réponse:
Ou si vous voulez utiliser pywin32, vous pouvez utiliser la méthode précédemment indiqué, et à lire, utilisez:
from win32file import *
from winioctlcon import FSCTL_GET_REPARSE_POINT
__all__ = ['islink', 'readlink']
# Win32file doesn't seem to have this attribute.
FILE_ATTRIBUTE_REPARSE_POINT = 1024
# To make things easier.
REPARSE_FOLDER = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)
# For the parse_reparse_buffer function
SYMBOLIC_LINK = 'symbolic'
MOUNTPOINT = 'mountpoint'
GENERIC = 'generic'
def islink(fpath):
""" Windows islink implementation. """
if GetFileAttributes(fpath) & REPARSE_FOLDER:
return True
return False
def parse_reparse_buffer(original, reparse_type=SYMBOLIC_LINK):
""" Implementing the below in Python:
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
ULONG Flags;
WCHAR PathBuffer[1];
} SymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
WCHAR PathBuffer[1];
} MountPointReparseBuffer;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
} DUMMYUNIONNAME;
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
"""
# Size of our data types
SZULONG = 4 # sizeof(ULONG)
SZUSHORT = 2 # sizeof(USHORT)
# Our structure.
# Probably a better way to iterate a dictionary in a particular order,
# but I was in a hurry, unfortunately, so I used pkeys.
buffer = {
'tag' : SZULONG,
'data_length' : SZUSHORT,
'reserved' : SZUSHORT,
SYMBOLIC_LINK : {
'substitute_name_offset' : SZUSHORT,
'substitute_name_length' : SZUSHORT,
'print_name_offset' : SZUSHORT,
'print_name_length' : SZUSHORT,
'flags' : SZULONG,
'buffer' : u'',
'pkeys' : [
'substitute_name_offset',
'substitute_name_length',
'print_name_offset',
'print_name_length',
'flags',
]
},
MOUNTPOINT : {
'substitute_name_offset' : SZUSHORT,
'substitute_name_length' : SZUSHORT,
'print_name_offset' : SZUSHORT,
'print_name_length' : SZUSHORT,
'buffer' : u'',
'pkeys' : [
'substitute_name_offset',
'substitute_name_length',
'print_name_offset',
'print_name_length',
]
},
GENERIC : {
'pkeys' : [],
'buffer': ''
}
}
# Header stuff
buffer['tag'] = original[:SZULONG]
buffer['data_length'] = original[SZULONG:SZUSHORT]
buffer['reserved'] = original[SZULONG+SZUSHORT:SZUSHORT]
original = original[8:]
# Parsing
k = reparse_type
for c in buffer[k]['pkeys']:
if type(buffer[k][c]) == int:
sz = buffer[k][c]
bytes = original[:sz]
buffer[k][c] = 0
for b in bytes:
n = ord(b)
if n:
buffer[k][c] += n
original = original[sz:]
# Using the offset and length's grabbed, we'll set the buffer.
buffer[k]['buffer'] = original
return buffer
def readlink(fpath):
""" Windows readlink implementation. """
# This wouldn't return true if the file didn't exist, as far as I know.
if not islink(fpath):
return None
# Open the file correctly depending on the string type.
handle = CreateFileW(fpath, GENERIC_READ, 0, None, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, 0) \
if type(fpath) == unicode else \
CreateFile(fpath, GENERIC_READ, 0, None, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, 0)
# MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384 = (16*1024)
buffer = DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, None, 16*1024)
# Above will return an ugly string (byte array), so we'll need to parse it.
# But first, we'll close the handle to our file so we're not locking it anymore.
CloseHandle(handle)
# Minimum possible length (assuming that the length of the target is bigger than 0)
if len(buffer) < 9:
return None
# Parse and return our result.
result = parse_reparse_buffer(buffer)
offset = result[SYMBOLIC_LINK]['substitute_name_offset']
ending = offset + result[SYMBOLIC_LINK]['substitute_name_length']
rpath = result[SYMBOLIC_LINK]['buffer'][offset:ending].replace('\x00','')
if len(rpath) > 4 and rpath[0:4] == '\\??\\':
rpath = rpath[4:]
return rpath
def realpath(fpath):
from os import path
while islink(fpath):
rpath = readlink(fpath)
if not path.isabs(rpath):
rpath = path.abspath(path.join(path.dirname(fpath), rpath))
fpath = rpath
return fpath
def example():
from os import system, unlink
system('cmd.exe /c echo Hello World > test.txt')
system('mklink test-link.txt test.txt')
print 'IsLink: %s' % islink('test-link.txt')
print 'ReadLink: %s' % readlink('test-link.txt')
print 'RealPath: %s' % realpath('test-link.txt')
unlink('test-link.txt')
unlink('test.txt')
if __name__=='__main__':
example()
Adjust les attributs le CreateFile à vos besoins, mais pour une situation normale, cela devrait fonctionner. N'hésitez pas à améliorer cela.
Il devrait également fonctionner pour les jonctions de dossiers si vous utilisez MOUNTPOINT au lieu de SYMBOLIC_LINK.
Vous peut ainsi vérifier que
sys.getwindowsversion()[0] >= 6
si vous mettez cela en quelque chose que vous libérer, car cette forme de lien symbolique est uniquement prise en charge sur Vista +.
Vous ne voulez pas compter sur des outils externes, mais cela ne vous dérange pas de dépendre de l'environnement spécifique? Je pense que vous pouvez sans risque supposer que, si c'est NTFS que vous exécutez, l'utilitaire de jonction sera probablement là. Mais, si vous voulez dire que vous préférez ne pas appeler à un programme externe, j'ai trouvé que les choses ctypes sont inestimables. Il vous permet d'appeler des DLL Windows directement depuis Python. Et je suis sûr que c'est dans les versions standard de Python de nos jours.
Vous devez juste savoir quelle DLL Windows est l'appel API CreateJunction()
(ou quel que soit l'appel Windows) et configurer les paramètres et appeler. Bonne chance avec ça, Microsoft ne semble pas très bien le supporter. Vous pourrait désassembler le programme SysInternals junction
ou linkd
ou l'un des autres outils pour savoir comment ils le font.
Moi, je suis assez paresseux, je voudrais simplement appeler junction
comme un processus externe :-)
ctypes est inclus dans Python à partir de la version 2.5. –
La commande de jonction n'existe pas sur Vista et Win7. Il a été remplacé par mklink. –
Il existe sous la forme d'une jonction d'outil Sysinternals. – Nux
vous pouvez utiliser des modules API python win32 par exemple
import win32file
win32file.CreateSymbolicLink(srcDir, targetDir, 1)
voir http://docs.activestate.com/activepython/2.5/pywin32/win32file__CreateSymbolicLink_meth.html pour plus de détails
si vous ne voulez pas compter sur cela aussi, vous pouvez toujours utiliser ctypes et appelez directement CreateSymbolicLinl API win32, ce qui est quand même un simple appel
ici est appel à l'aide par exemple ctypes
import ctypes
kdll = ctypes.windll.LoadLibrary("kernel32.dll")
kdll.CreateSymbolicLinkA("d:\testdir", "d:\testdir_link", 1)
MSDN dit client pris en charge minimum Windows Vista
Je pense que les jonctions étaient à partir de Win2K, mais pas officiellement (ou bien) soutenu par MS, compte tenu de la rareté des docs sur la façon de le faire. Les nouveaux liens symboliques semblent beaucoup mieux, d'autant plus que vous pouvez les faire vers des fichiers et (je pense) qu'ils peuvent maintenant traverser des réseaux. – paxdiablo
oui les jonctions sont un sous-ensemble de liens symboliques –
Les jonctions sont _not_ un sous-ensemble de liens symboliques. Les jonctions ne s'appliquent qu'aux répertoires. Cette réponse est incorrecte et crée un lien symbolique pour les fichiers (qui ne fonctionne que sur Vista et au-dessus) plutôt qu'une jonction pour les répertoires (qui fonctionne sur NTFS sous Windows 2000) et plus. Malheureusement, il n'y a pas vraiment de moyen facile de le faire en Python. –
Depuis Python 3.5, il y a une fonction CreateJunction
dans le module _winapi
.
import _winapi
_winapi.CreateJunction(source, target)
- 1. Comment créer un générateur répétitif en Python
- 2. Fusion d'une jonction en une branche fourchue
- 3. Meilleure façon de créer un script "runner" en Python?
- 4. Faire pivoter un point par un autre point en 2D
- 5. Comment puis-je dessiner des graphiques automatiques en utilisant un point en Python sur un Mac?
- 6. Créer un nouveau point de connexion dans VC++ 6?
- 7. Comment puis-je modifier les autorisations Windows NTFS en Perl?
- 8. Table de jonction avec sous-table en SQL
- 9. Comment puis-je créer un document Word en utilisant Python?
- 10. Comment créer un serveur COM persistant en Python
- 11. comment créer un nouveau fichier en utilisant python
- 12. Créer un groupe d'utilisateurs sous Linux en utilisant python
- 13. Comment créer une référence faible à un objet en Python?
- 14. outil de réallocation de fichiers pour ntfs
- 15. Comment créer une classe Python en C?
- 16. Supprimer la file d'attente dans NTFS?
- 17. Comment créer un PyMe (bibliothèque Python) Exécuter en Python 2.4 sous Windows?
- 18. dessine un point sur linechart en flex
- 19. Créer une icône en mémoire avec win32 en python
- 20. Comment créer des objets dynamiquement de façon élégante en python?
- 21. Comment: créer un point d'arrêt en utilisant des conditions? [C# Express]
- 22. Comment déterminer les blocs alloués sur un disque NTFS
- 23. comment l'indexation se produit sur un lecteur NTFS
- 24. python créer un objet tranche à partir de la chaîne
- 25. Inbound jonction UDF sur SQL Server
- 26. Comment créer des sous-listes dans le point de partage
- 27. créer un fichier .mat à partir de python
- 28. Dessiner un point sur l'écran
- 29. Ce tutoriel en ligne est-il un bon point de départ pour créer un framework PHP5 pour des raisons d'apprentissage?
- 30. par un certain nombre de Split point décimal en php
Notez que l'extension ntfslink est actuellement cassée sous Python3 – CharlesB
Voir ma réponse ci-dessous pour Python> = 3.5 – CharlesB