2011-06-07 12 views
18

मैंने पायथन वेबसाइट से पायथन 2.7.1 डाउनलोड किया और इसे विंडोज़ में स्थापित किया। फ़ाइल को सिमलिंक करने का प्रयास करते समय, मुझे लगता है कि यह समर्थित नहीं है।विंडोज़ में OS.symlink समर्थन

हालांकि, मुझे this issue मिला, और देखा कि यह तय किया गया था। क्या यह लागू किया जाएगा, और यदि ऐसा है तो? मैं विंडोज विस्टा चला रहा हूँ।

+0

पायथन 3.2 का प्रयास करें। – Blender

+0

इसे एक उत्तर के रूप में जोड़ें और मैं इसे सही के रूप में चिह्नित करूंगा। – xaav

+0

@xaav, चूंकि ब्लेंडर उत्तर हटा दिया गया था (मुझे नहीं पता क्यों), क्या आप मेरे उत्तर को सही के रूप में चिह्नित करने का समर्थन कर सकते हैं, क्योंकि इससे समस्या का समाधान ठीक हो जाता है? धन्यवाद! –

उत्तर

24

यह ठीक करने का एक तरीका है, os मॉड्यूल आपके पाइथन पर्यावरण प्रारंभ पर पैचिंग।

सिमलिंक बनाने के लिए फ़ंक्शन विंडोज एपीआई से पहले ही उपलब्ध है, आपको केवल इसे कॉल करने की आवश्यकता है।

अजगर के स्टार्टअप के दौरान, एक प्रयास site-packages directory पर, sitecustomize.py नाम के एक मॉड्यूल आयात करने के लिए किया जाता है। ओएस मॉड्यूल में हमारे फ़ंक्शन को संलग्न करने के लिए हम इस हुक का उपयोग करेंगे।

फ़ाइल sitecustomize.py पर इस कोड डालें:

import os 

__CSL = None 
def symlink(source, link_name): 
    '''symlink(source, link_name) 
     Creates a symbolic link pointing to source named link_name''' 
    global __CSL 
    if __CSL is None: 
     import ctypes 
     csl = ctypes.windll.kernel32.CreateSymbolicLinkW 
     csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32) 
     csl.restype = ctypes.c_ubyte 
     __CSL = csl 
    flags = 0 
    if source is not None and os.path.isdir(source): 
     flags = 1 
    if __CSL(link_name, source, flags) == 0: 
     raise ctypes.WinError() 

os.symlink = symlink 

आपका अजगर प्रक्रिया सक्षम "सांकेतिक लिंक बनाएँ" विशेषाधिकार के साथ शुरू करने की जरूरत है, यह एक अजगर मुद्दा नहीं है, हर कार्यक्रम है कि इस विंडोज एपीआई का उपयोग करने का दावा करने की आवश्यकता होगी। यह आपके पायथन दुभाषिया को एक उन्नत cmd.exe से चलाया जा सकता है। एक बेहतर विकल्प उपयोगकर्ता को विशेषाधिकार प्रदान करना है, जो आपके विंडोज संस्करण जहाजों को आवश्यक समूह नीति संपादक (gpedit.msc) प्रदान करता है। नीचे स्क्रीनशॉट देखें। आप प्रशासनिक खातों की सुरक्षा पर समझौता किये बिना किसी भी उपयोगकर्ता या सुरक्षा समूह को इस तरह के विशेषाधिकार की आवश्यकता के लिए मूल्य समायोजित कर सकते हैं।

The group policy editor

नोट: कोड here

+0

निजीकरण को मेरे सर्वोत्तम ज्ञान पर सही तरीके से सेट करने के बावजूद मुझे अनुमति त्रुटि मिल रही है (उपयोगकर्ता एक व्यवस्थापक है, स्क्रिप्ट गैर-उन्नत मोड में चलता है)। क्या कारण हो सकता है? – eudoxos

+0

@udoxos आपके पायथन प्रक्रिया को व्यवस्थापकीय विशेषाधिकारों के साथ शुरू करने की आवश्यकता है। यह इसे एक उन्नत cmd.exe से चलाया जा सकता है। –

+1

मुझे पहले से ही वेब पर यह पता चला है। यह पूरी तरह बेवकूफ है, कि एक प्रशासक को इसे काम करने के लिए अपनी प्रक्रिया को उन्नत करना होगा। चूंकि यह एक उपयोगकर्ता प्रोग्राम है, इसलिए मैं उपयोगकर्ताओं को इसे उन्नत मोड में चलाने का अनुरोध नहीं कर सकता। माइक्रोसॉफ्ट में सुरक्षा डिजाइन बनाया गया। – eudoxos

20

फर्नांडो Macedo जवाब तरह से झलकी, लेकिन IMO कम आक्रामक:

def symlink(source, link_name): 
    import os 
    os_symlink = getattr(os, "symlink", None) 
    if callable(os_symlink): 
     os_symlink(source, link_name) 
    else: 
     import ctypes 
     csl = ctypes.windll.kernel32.CreateSymbolicLinkW 
     csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32) 
     csl.restype = ctypes.c_ubyte 
     flags = 1 if os.path.isdir(source) else 0 
     if csl(link_name, source, flags) == 0: 
      raise ctypes.WinError() 
9
जियान मार्को Gherardi answer की तरह खिड़कियों पर

लेकिन परिभाषित करता है os.symlink, ताकि आपका कोड सुरक्षित रूप से विंडोज़ और लिनक्स पर काम कर सके:

import os 
os_symlink = getattr(os, "symlink", None) 
if callable(os_symlink): 
    pass 
else: 
    def symlink_ms(source, link_name): 
     import ctypes 
     csl = ctypes.windll.kernel32.CreateSymbolicLinkW 
     csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32) 
     csl.restype = ctypes.c_ubyte 
     flags = 1 if os.path.isdir(source) else 0 
     if csl(link_name, source, flags) == 0: 
      raise ctypes.WinError() 
    os.symlink = symlink_ms 

यदि आप अपनी स्क्रिप्ट को व्यवस्थापक के रूप में चलाते हैं तो सब ठीक है, अगर आप इसे उपयोगकर्ता के रूप में चलाने के लिए चाहते हैं - तो आपको grant python a permission to make symlinks - जो केवल विंडोज विस्टा + परम या पेशेवर के तहत संभव है।

संपादित:

जियान मार्को Gherardi answer एक यूनिक्स पथ का लिंक बनाता है: like/this और यह काम नहीं करता। ठीक source.replace('/', '\\') करना है:

# symlink support under windows: 
import os 
os_symlink = getattr(os, "symlink", None) 
if callable(os_symlink): 
    pass 
else: 
    def symlink_ms(source, link_name): 
     import ctypes 
     csl = ctypes.windll.kernel32.CreateSymbolicLinkW 
     csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32) 
     csl.restype = ctypes.c_ubyte 
     flags = 1 if os.path.isdir(source) else 0 
     if csl(link_name, source.replace('/', '\\'), flags) == 0: 
      raise ctypes.WinError() 
    os.symlink = symlink_ms 

एक और तरीका है खिड़की के विस्टा + mklink उपयोगिता का प्रयोग है। लेकिन इस उपयोगिता का उपयोग करने के लिए एक ही अनुमति की आवश्यकता है।फिर भी:

# symlink support under windows: 
import os 
os_symlink = getattr(os, "symlink", None) 
if callable(os_symlink): 
    pass 
else: 
    def symlink_ms(source, link_name): 
     os.system("mklink {link} {target}".format(
      link = link_name, 
      target = source.replace('/', '\\'))) 
    os.symlink = symlink_ms 

संपादित 2:

यहाँ मैं अंत में उपयोग कर रहा हूँ है: यदि उपयोगकर्ता ऐसा करने के लिए एक विशेषाधिकार है इस स्क्रिप्ट खिड़कियों के नीचे एक लिंक बनाता है, अन्यथा यह सिर्फ नहीं है एक लिंक:

import os 
if os.name == "nt": 
    def symlink_ms(source, link_name): 
     import ctypes 
     csl = ctypes.windll.kernel32.CreateSymbolicLinkW 
     csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32) 
     csl.restype = ctypes.c_ubyte 
     flags = 1 if os.path.isdir(source) else 0 
     try: 
      if csl(link_name, source.replace('/', '\\'), flags) == 0: 
       raise ctypes.WinError() 
     except: 
      pass 
    os.symlink = symlink_ms 
+0

मैं समझता हूं कि फ़ंक्शन को कोई समस्या नहीं होने पर एक नोप बनने के लिए डिज़ाइन किया गया है, लेकिन मुझे समझ में नहीं आ रहा है कि क्यों ctypes.WinError अपवाद उठाया जाता है अगर यह हमेशा अपवाद हैंडलर द्वारा निगलने जा रहा है? क्या यह एक प्लेसहोल्डर है जो डेवलपर को अपवाद के साथ कुछ अलग करने का विकल्प चुनने में सक्षम बनाता है, या क्या मुझे यहां एक सूक्ष्मता याद आ रही है? –

+0

@ विलियमपेयने: जहां तक ​​मुझे याद है, यह लिंक बना रहा था, इसके पास पर्याप्त अनुमतियां हैं, लेकिन 'csl (link_name, source.replace ('/', '\\'), झंडे के मामले में 'WinError'' बढ़ाएंगे = = 0' - इस मामले में यह एक लिंक भी बनायेगा। तो सब कुछ काम किया, और मुझे समझ में नहीं आया कि क्यों 'WinError'। तो मैंने बस त्रुटि को दबा दिया। – Adobe