2011-01-22 12 views
12

प्रश्न की लंबाई के लिए पहले से माफ़ी माफ़ी, मैं कुछ भी छोड़ना नहीं चाहता था।विराम (और अधिक) कार्यक्षमता को कैसे कार्यान्वित करें?

कुछ पृष्ठभूमि जानकारी

मैं Windows API का उपयोग करता है कीस्ट्रोक्स, माउस आंदोलन और खिड़की अनुकरण करने के लिए एक अजगर आवेदन लिख कर एक डेटा प्रविष्टि प्रक्रिया को स्वचालित करने/हेरफेर को नियंत्रित कोशिश कर रहा हूँ। मुझे इस विधि का सहारा लेना है क्योंकि मुझे अभी तक डेटास्टोर/डेटाबेस तक पहुंचने के लिए सुरक्षा मंजूरी नहीं है (उदाहरण के लिए एसक्यूएल का उपयोग करना) या अप्रत्यक्ष रूप से एक बेहतर उपयुक्त एपीआई के माध्यम से। नौकरशाही, यह एक दर्द है ;-)

डेटा प्रविष्टि प्रक्रिया में आलेख उपलब्धता में परिवर्तन के कारण बिक्री आदेशों में सुधार शामिल है। अनुपलब्ध लेख या तो ऑर्डर से हटा दिए जाते हैं या किसी अन्य उपयुक्त आलेख द्वारा प्रतिस्थापित किए जाते हैं।

प्रारंभ में मैं चाहता हूं कि एक मानव स्वचालित डेटा एंट्री प्रक्रिया की निगरानी करने में सक्षम हो, यह सुनिश्चित करने के लिए कि सब ठीक हो जाए। इसे प्राप्त करने के लिए मैं एक तरफ के कार्यों को धीमा कर देता हूं लेकिन उपयोगकर्ता को यह बताता हूं कि वर्तमान में पिन की गई विंडो के माध्यम से क्या चल रहा है।

वास्तविक प्रश्न

उपयोगकर्ता स्वचालन प्रक्रिया मैं एक हॉटकी के रूप में और हैंडलर मैं स्वचालन कार्यक्षमता रोकना चाहते हैं, उसमें रोकें/तोड़ कुंजी दर्ज की कर रहा हूँ को रोकने के लिए अनुमति देने के लिए। हालांकि, मैं वर्तमान में स्वचालन कार्यक्षमता के निष्पादन को ठीक से रोकने के लिए एक तरीका जानने के लिए संघर्ष कर रहा हूं। जब विराम समारोह का आह्वान किया जाता है, तो मैं चाहता हूं कि ऑटोमेशन प्रक्रिया अपने ट्रैक में मृत हो जाए, इससे कोई फर्क नहीं पड़ता कि यह क्या कर रहा है। मैं नहीं चाहता कि यह एक और कीस्ट्रोक निष्पादित भी करे।

अद्यतन [23/01]: मैं वास्तव में एक से अधिक बस को थामने करना चाहते हैं, मैं, जबकि यह चल रहा है स्वचालन की प्रक्रिया के साथ संवाद करने में सक्षम होने के लिए और चाहते हैं कि उसे रोक सकते हैं, वर्तमान बिक्री आदेश को छोड़ने के लिए अनुरोध करते हैं, पूरी तरह से और शायद और भी छोड़ दें।

क्या कोई मुझे मुझे प्राप्त करने के लिए सही रास्ता (टीएम) दिखा सकता है?

from pywinauto import application 
app = application.Application() 
app.start_("notepad") 
app.Notepad.TypeKeys("abcdef") 

अद्यतन [25/01]: पर काम करने का कुछ दिनों के बाद

कुछ अधिक जानकारी

यहाँ (मैं the pywinauto library उपयोग कर रहा हूँ) कैसे काम करता है स्वचालन का एक उदाहरण है मेरे आवेदन में मैंने देखा है कि मैं वास्तव में बहुत ज्यादा pywinauto का उपयोग नहीं करता हूं, अभी मैं केवल विंडो ढूंढने के लिए इसका उपयोग कर रहा हूं और फिर मैं माउस इनपुट अनुकरण करने के लिए कीबोर्ड इनपुट और win32api फ़ंक्शंस को अनुकरण करने के लिए सीधे SendKeysCtypes.SendKeys का उपयोग करता हूं।

  1. मैं स्वचालन कार्यक्षमता को अलग कर सकता और:

    मैं क्या बाहर मिल गया है अब तक

    यहाँ कुछ तरीकों मैं एक जवाब के लिए मेरे खोज में अब तक का सामना करना पड़ा हैं दो अलग प्रक्रियाओं में इंटरफ़ेस + हॉटकी श्रोता। आइए पूर्व को "ऑटोमेटर" और बाद वाले को "प्रबंधक" के रूप में देखें। प्रबंधक तब एक सिग्स्टॉप सिग्नल को भेजकर ऑटोमेटर के निष्पादन को रोक सकता है और SIGCONT सिग्नल (या SuspendThread/ResumeThread के माध्यम से विंडोज समकक्ष) का उपयोग करके इसे रोक सकता है।

    उपयोगकर्ता इंटरफ़ेस को अपडेट करने में सक्षम होने के लिए ऑटोमेटर को किसी भी प्रकार के आईपीसी तंत्र के माध्यम से इसकी प्रगति के प्रबंधक को सूचित करने की आवश्यकता होगी।

    विपक्ष:

    • SIGSTOP का उपयोग कर सकते हैं एक छोटे से कठोर नहीं हो सकता है? क्या यह ठीक से काम करेगा? बहुत से लोग इसके खिलाफ सलाह दे रहे हैं और इसे "खतरनाक" भी कहते हैं।

    • मुझे चिंता है कि आईपीसी तंत्र को लागू करना थोड़ा जटिल होगा। दूसरी तरफ, मैंने डीबीस के साथ काम किया है जो लागू करने में बहुत मुश्किल नहीं होगा।

  2. दूसरी विधि और एक कि बहुत से लोग सुझाव दे हो रहे हैं धागे का उपयोग करना शामिल है और अनिवार्य रूप को निम्नलिखित (सरलीकृत) पर निर्भर:

    while True: 
        if self.pause: # pause 
        # Do the work... 
    

    हालांकि, यह इस तरह से यह लगता है कर ऐसा करने के लिए और कोई काम नहीं होने के बाद ही यह रोक देगा। इस विधि को देखने का एकमात्र तरीका काम करेगा (पूरे स्वचालन प्रक्रिया) को छोटे कार्य खंडों (यानी कार्य) में विभाजित करना होगा। एक नया कार्य शुरू करने से पहले कार्यकर्ता धागा जांच करेगा कि क्या इसे रोकना चाहिए और इंतजार करना चाहिए।

    विपक्ष:

    • इस तरह के ऊपर एक के रूप में छोटे खंडों में काम को विभाजित करने, बहुत बदसूरत कोड बुद्धिमान (सौंदर्य की दृष्टि से) होगा एक कार्यान्वयन की तरह लगता है।

      तरह से मैं यह कल्पना, सभी बयानों की तरह कुछ देखने के लिए तब्दील किया जाएगा: queue.put((function, args)) (जैसे queue.put((app.Notepad.TypeKeys, "abcdef"))) और आप स्वचालित प्रक्रिया धागा कार्यों के माध्यम से चल रहा है और लगातार एक काम शुरू करने से पहले ठहराव राज्य के लिए जाँच होगा। यह सिर्फ सही नहीं हो सकता है ...

    • कार्यक्रम वास्तव में अपने ट्रैक में मृत नहीं होगा, लेकिन वास्तव में पहले रोके जाने से पहले एक कार्य (हालांकि छोटा) खत्म कर देगा।

प्रगति

अद्यतन बनाया [23/01]: मैंने कहा SuspendThread/ResumeThread कार्यक्षमता के माध्यम से पहली विधि का उपयोग कर अपने आवेदन के एक संस्करण क्रियान्वित किया है। अब तक यह बहुत अच्छी तरह से काम करता प्रतीत होता है और मुझे स्वचालन सामान लिखने की इजाजत देता है जैसे कि आप कोई अन्य स्क्रिप्ट लिखेंगे। एकमात्र क्विर्क जो मैंने पार किया है वह है कि कीबोर्ड संशोधक (CTRL, ALT, SHIFT) रोके जाने पर "अटक" हो जाते हैं। कुछ मैं आसानी से आसानी से काम कर सकते हैं।

मैंने दूसरी विधि (थ्रेड और सिग्नल/संदेश पासिंग) का उपयोग करके एक परीक्षण भी लिखा है और विराम कार्यक्षमता लागू की है। हालांकि, यह वास्तव में बदसूरत लग रहा है (दोनों विराम ध्वज की जांच और "काम करने" से संबंधित सब कुछ)। तो अगर कोई मुझे दूसरी विधि के समान कुछ का एक उचित उदाहरण दिखा सकता है तो मैं इसकी सराहना करता हूं।

संबंधित प्रश्नों

  • Pausing a process?
  • Pausing a thread using threading class

    Alex Martelli posted an answer कह रही:

    अन्य थ्रेड जबरन एक धागा (किसी भी एक से अधिक वहाँ के लिए है को रोकने के लिए के लिए कोई तरीका नहीं है उस धागे को मारने के लिए अन्य धागे) - लक्ष्य धागे को मौका द्वारा सहयोग करना चाहिए सायनिक रूप से उचित "झंडे" की जांच (एक थ्रेडिंग। रोकें विराम/विवाद मामले के लिए उपयुक्त हो सकता है)।

    तब उन्होंने मल्टीप्रोसेसिंग मॉड्यूल और सिगस्टॉप/सिगकंट को संदर्भित किया।

    इस समारोह में मुख्य रूप से डिबगर द्वारा उपयोग के लिए बनाया गया है:

  • Is there a way to indefinitely pause a thread?
  • Pausing a process in Windows

    An answer to this question SuspendThread के बारे में MSDN प्रलेखीकरण उद्धरण। यह थ्रेड सिंक्रनाइज़ेशन के लिए इस्तेमाल नहीं किया जाना है। सिंक्रनाइज़ेशन ऑब्जेक्ट का मालिक होने वाले थ्रेड पर सस्पेंड थ्रेड, जैसे म्यूटेक्स या महत्वपूर्ण सेक्शन, एक डेडलॉक का कारण बन सकता है यदि कॉलिंग थ्रेड एक निलंबित थ्रेड के स्वामित्व वाली सिंक्रनाइज़ेशन ऑब्जेक्ट प्राप्त करने का प्रयास करता है। इस स्थिति से बचने के लिए, एक ऐसे अनुप्रयोग के भीतर एक धागा जो डीबगर नहीं है, उसे अन्य थ्रेड को खुद को निलंबित करने का संकेत देना चाहिए। लक्ष्य धागा को इस सिग्नल को देखने और उचित प्रतिक्रिया देने के लिए डिज़ाइन किया जाना चाहिए।

  • Is there any way to kill a Thread in Python?
  • How do I pass an exception between threads in python
+4

+1 – Wolph

+0

GUI के लिए आप किस टूलकिट का उपयोग कर रहे हैं? आपने एक पिन की गई विंडो का उल्लेख किया है। –

+0

@ क्रिस्टियन: मैंने क्यूटी को एक शॉट देने का फैसला किया, लेकिन मैं जीटीके पर वापस जाने के बारे में सोच रहा हूं। –

उत्तर

2

मैं pywinauto पता नहीं है। लेकिन मुझे लगता है कि आपके पास एक ऐसा एप्लिकेशन क्लास है जो आप प्राप्त करते हैं और चीजों को करने के लिए SendKeys/SendMouseEvent/etc जैसी विधियां हैं।

अपनी खुद की माईप्लिकेशंस क्लास बनाएं जिसमें पाइविनाटो के एप्लिकेशन क्लास का संदर्भ है। एक ही विधि प्रदान करें लेकिन प्रत्येक विधि से पहले जांचें कि कोई विराम घटना हुई है या नहीं। यदि यह है, तो आप कोड में कूद सकते हैं जो विराम घटना को संभालता है। इस तरह आप हर बार जब आप किसी ईवेंट का कारण बनते हैं तो विराम की जांच कर रहे हैं, लेकिन यह सब आपके कोड पर रोक दिए बिना एक वर्ग द्वारा संभाला जाता है।

एक बार जब आप विराम का पता लगा लेते हैं तो आप इसे किसी भी तरह से संभाल सकते हैं। उदाहरण के लिए, आप वर्तमान कार्य को छोड़ने के लिए मजबूर करने के लिए अपवाद फेंक सकते हैं।

+0

+1 आप वहाँ कुछ करने के बारे में हो सकता है नीचे राज्य में अटक नहीं है ... स्वचालन सामान मैं पर काम कर रहा हूँ बस अनुकरण कीबोर्ड इनपुट से थोड़ा और अधिक जटिल है (वहाँ पाठ चयन है , पार्सिंग टेक्स्ट, टेक्स्ट तुलना इत्यादि) लेकिन इस तरह के कार्यों/वर्गों का एक समूह लपेटना बहुत अच्छी तरह से काम कर सकता है। मैं इस पर ध्यान देने जा करने के लिए जा रहा हूँ और मैं तुम्हें करने के लिए वापस मिल जाएगा। –

1

कार्यक्षमता और इंटरफ़ेस धागा अलग/प्रक्रिया निश्चित रूप से सबसे अच्छा विकल्प imho है, दूसरा समाधान से तेज़ और आसान है, लेकिन निश्चित रूप से बेहतर नहीं है।

शायद एकाधिक थ्रेड और अपवाद का उपयोग करना कई प्रक्रियाओं का उपयोग करने से बेहतर विचार होगा। लेकिन यदि आप SIGSTOP से कई प्रक्रियाओं का उपयोग कर रहे हैं तो यह काम करने के लिए आपका एकमात्र तरीका हो सकता है।

क्या इसके लिए 2 धागे का उपयोग करने के खिलाफ कुछ भी है?

  • 1 वास्तव में उपयोगकर्ता इनपुट
+0

दूसरी विधि में वास्तव में धागे का उपयोग करना शामिल है (मैंने यह स्पष्ट करने के लिए उत्तर अपडेट किया है)। लोग कह रहे हैं कि आपको बाहर से रोकने के लिए धागे को मजबूर नहीं करना चाहिए और इसके बजाय थ्रेड के बीच सिग्नलिंग/मैसेजिंग की सलाह देना चाहिए। मैं समझता हूं कि उत्तरार्द्ध को कैसे कार्यान्वित किया जाए, न कि वास्तव में एक सुखद तरीके से "काम" कैसे करें। –

+0

@ ब्रूस वैन डेर कुइज: मुझे इसके बारे में पता है। यह वास्तव में अनुशंसित नहीं है, लेकिन imho इसे करने का सबसे अच्छा तरीका है। ऐसा करने के 3 तरीके हैं, 'सत्य' विकल्प (जो वास्तव में बहुत अच्छा काम नहीं करता है क्योंकि आपको स्वयं को स्थिति की जांच करनी है)। धागा विकल्प (वास्तव में, सुंदर नहीं)। और बाहरी सिग्नल जो आम तौर पर थ्रेडेड विकल्प से परेशान होते हैं। – Wolph

+0

मैंने एक और अपडेट जोड़ा क्योंकि मैं अभी काफी अटक गया हूं। क्या आप इसका मतलब विस्तारित करने के इच्छुक होंगे? शायद एक कोड नमूना भी प्रदान करते हैं? मैं निश्चित रूप से इसकी सराहना करता हूं। –

4

ध्यान रखें कि हालांकि अमूर्त के अपने स्तर, "एक कीस्ट्रोक को क्रियान्वित करने" में एक भी परमाणु ऑपरेशन है, यह पढ़ने के लिए

  • 1 धागा क्रियान्वित करने के लिए धागा मशीन निर्देशों के बजाय जटिल निर्देश के रूप में मशीन पर लागू किया गया। तो, मनमानी बिंदुओं पर धागे को रोकना चीजों को अनिश्चित स्थिति में ले जा सकता है। SIGSTOP भेजना एक मनमाना बिंदु पर धागे को रोकने के रूप में खतरनाक स्तर का एक ही स्तर है। आप किसी विशेष चरण में कहां हैं, इस पर निर्भर करते हुए, आपका स्वचालन संभावित रूप से टूटा जा सकता है। उदाहरण के लिए, यदि आप एक समय-निर्भर चरण के बीच में रुकते हैं।

    ऐसा लगता है कि यह समस्या ऑटोमेशन लाइब्रेरी के स्तर पर सबसे अच्छी तरह हल हो जाएगी। मैं उस ऑटोमेशन लाइब्रेरी से बहुत परिचित नहीं हूं जिसका आप उपयोग कर रहे हैं। पुस्तकालय के डेवलपर्स से संपर्क करने के लायक हो सकता है यह देखने के लिए कि क्या उनके पास सुरक्षित उप-चरण स्तर पर स्वचालन चरणों के निष्पादन को रोकने के लिए कोई सुझाव है या नहीं।

  • +1

    अच्छा अंक। प्रक्रिया को निलंबित करने के साथ अब तक एकमात्र क्विर्क पाया गया है कि कीबोर्ड संशोधक (CTRL, ALT, SHIFT) रोके जाने पर "अटक" हो जाते हैं। मैं हालांकि उस के आसपास काम कर सकते हैं। सौभाग्य से अन्य कुंजियों :-) –

    0

    मैं अजगर नहीं बल्कि pywinauto का उपयोग करें; इस प्रकार के कार्यों के लिए मैं AutoHotKey का उपयोग करता हूं। एक ऑटोहॉटकी स्क्रिप्ट में एक साधारण विराम को लागू करने का एक तरीका स्क्रॉल लॉक जैसे "टॉगल" कुंजी का उपयोग कर और स्क्रिप्ट में मुख्य स्थिति का परीक्षण कर सकता है। साथ ही, स्क्रिप्ट आंतरिक रोक सेटिंग को चालू/बंद करने के बाद कुंजी स्थिति को पुनर्स्थापित कर सकती है। विस्तृत प्रश्न के लिए

    +0

    आपके उत्तर के लिए धन्यवाद। मैंने पहले AutoHotkey (कुछ सरल लिपि) लेकिन इस बार मैं क्योंकि मैं अपने संदेह था के रूप में मैं अजगर में कर सकते हैं कि क्या मैं जटिल बातें मैं एक ही आसानी के साथ क्या करने के लिए देख रहा हूँ में से कुछ कर सकता है अजगर के साथ जाने का फैसला किया साथ काम किया है । –

    +0

    @ ब्रूस: जटिल कार्यों के लिए मैं ऑटोहॉटकी पर पाइथन भी पसंद करता हूं।लेकिन "टॉगल" कुंजी विधि pywinauto में उपलब्ध नहीं है? हो सकता है कि आप वास्तविक कोड को संशोधित करने के बिना टॉगल कुंजी राज्य की जाँच करें और रोकें/फिर से शुरू करने के लिए sys.setprofile या sys.settrace उपयोग कर सकते हैं। (केवल मेरे दो सेंट्स) – PabloG

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