2011-10-26 17 views
11

मैंने सी # में एक एसएसएच सर्वर लिखा है और मैंने सोचा कि यह शेल के रूप में पावरहेल को हुक करने के लिए साफ होगा। मैंने इसे ठीक से काम करने के लिए 2 विधियों का प्रयास किया है लेकिन दोनों सही से बहुत दूर हैं। यहां मैंने जो कोशिश की है:क्या नकली विंडोज कंसोल एपीआई संभव है?

  1. powerhell.exe लॉन्च करें और इसके std (in/out) को रीडायरेक्ट करें। यह अच्छी तरह से काम नहीं करता है क्योंकि powerhell.exe का पता लगाया जाता है कि इसे पुनर्निर्देशित किया गया है, बदलता है यह व्यवहार है। और भी, यह stdid पर इनपुट डेटा की अपेक्षा करता है, आदेश नहीं। तो यह कमांड पढ़ने के लिए कंसोल एपीआई का उपयोग करता है।
  2. "रैपर" एप्लिकेशन में होस्ट पावरहेल। इसका का लाभ शक्तियों के लिए "कंसोल" कार्यान्वयन प्रदान करने में सक्षम है ( PSHostRawUserInterface के माध्यम से)। यह बेहतर काम करता है, लेकिन आप अभी भी कमांड (ज्यादातर वास्तविक कंसोल एप्लिकेशन) जैसे "... | अधिक" का आह्वान कर सकते हैं, जो कंसोल एपीआई का उपयोग करने में सक्षम होने के लिए की अपेक्षा करते हैं, और बाद में रैपर के कंसोल से पढ़ने का प्रयास करें प्रक्रिया।

तो मैं क्या करना चाहता हूं कि नियमित कंसोल इनपुट/आउटपुट फ़ंक्शंस को प्रतिस्थापित करने वाले कार्यों का एक सेट है जो अनुप्रयोगों को कंसोल करते हैं, इसलिए मैं उन्हें संभाल सकता हूं। लेकिन यह एक खराब डिजाइन विचार (आईएमओ) होने के बिंदु पर बल्कि कठोर लगता है।

अभी मैं मूल/पिनवोक कार्यों जैसे WriteConsoleInput के साथ प्रासंगिक कुंजी भेजकर कंसोल में हेरफेर करने के विचार पर हूं। मैं इकट्ठा करता हूं कि इस तरह कंसोल को नकली करना संभव हो सकता है। लेकिन मैं नहीं देखता कि मैं कैसे कंसोल पर क्या होता हूं "पढ़ता हूं"।

यह भी ध्यान रखें, यह एक सेवा है, इसलिए अधिमानतः इसे वास्तविक कंसोल विंडो नहीं बननी चाहिए, हालांकि शायद विंडोज सत्र 0 में जो दिखाई नहीं देगी और इससे कोई फर्क नहीं पड़ता।

उत्तर

3

इस उद्देश्य के लिए आपको PSSession और एंटर-पीएसएसशन सीएमडीएलट मिला है। पावरहेल के साथ आपका एसएसएच क्या करेगा कि PSSession नहीं कर रहा है?

लेकिन तुम यहाँ कि writting कुछ भी whithout एक समाधान है करना चाहते हैं: Using PowerShell through SSH


संपादित 02/11/2011

PowerShell inside एक और तरीका कुछ भी writting whithout यह करने के लिए प्रदान करते हैं के लिए (मुक्त व्यक्तिगत उपयोग)।

Host03 sample, शायद आप जो करना चाहते हैं उसे करने के लिए मूल कोड प्रदान कर सकते हैं।

+0

ठीक है, मैं अपने एंड्रॉइड मोबाइल डिवाइस से अपने एसएसएच तक पहुंचना चाहता हूं। मैंने इसके लिए एक असली पावरहेल क्लाइंट नहीं देखा है। इस परियोजना के लिए एक निश्चित "बस अच्छा मजा" हिस्सा है। सिगविन के लिए ... अच्छी तरह से मेरे पास इसके साथ समस्याएं हैं (शायद तर्कहीन)। –

+0

क्या आप इसे एक [PowerShellInside] (http: //www.powershellinside) आज़माएं।com/powershell/ssh/download.aspx)। यह एक कनेक्शन मुक्त संस्करण मौजूद है। – JPBlanc

+0

हम, एक इंटरस्टेस्टिंग खोज, मैं इसे देख लूंगा। मुझे आश्चर्य है कि उन्होंने समस्या को हल कैसे किया। –

1

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

हालांकि, अंत में, मैंने एक आवरण प्रक्रिया में विंडोज एपीआई कॉल का उपयोग करके समस्या को हल करने का प्रबंधन किया था। क्योंकि वहां कुछ परेशानी हैं, इसलिए मैंने अपने स्वयं के प्रश्न पूछने का फैसला किया और दूसरों को कुछ समस्याओं को एक ही समस्या पर देखने का फैसला किया। मूल संरचना निम्नानुसार है:

  • रीडायरेड stdin/-out (और यदि आप चाहते हैं तो stderr) के साथ रैपर प्रक्रिया शुरू करें।(मेरे मामले में stdin और out xterm नियंत्रण अनुक्रमों और डेटा की धाराएं होंगी, क्योंकि वह एसएसएच तरीका है)
  • GetStdHandle() का उपयोग करके पुनर्निर्देशित इनपुट और आउटपुट हैंडल को पुनः प्राप्त करें। अगला SetStdHandle() "CONIN $" और "CONOUT $" के CreateFile() के लिए है, जैसे कि बाल प्रक्रियाएं कंसोल को प्राप्त करती हैं और इसमें रैपर प्रक्रिया की पुनर्निर्देशन नहीं होती है। (ध्यान दें कि createfile के लिए विरासत की अनुमति देने वाला एक सुरक्षा डिस्क्रिप्टर आवश्यक है)
  • कंसोल मोड, आकार, शीर्षक, Ctrl-C हैंडलर आदि सेट अप करें नोट: यदि आप यूनिकोड समर्थन चाहते हैं तो फ़ॉन्ट सेट करना सुनिश्चित करें, मैंने लुसीडा कंसोल का उपयोग किया (.FontFamily = 54, FaceName = "लुसीडा कंसोल")। इसके बिना, आपके कंसोल आउटपुट से वर्ण पढ़ने से कोडपेड संस्करण वापस आ जाएंगे, जो प्रबंधित कोड में काम करने के लिए भयानक हैं।
  • पढ़ना आउटपुट SetWinEventHook() के साथ किया जा सकता है, संदर्भ के बाहर अधिसूचना का उपयोग करना सुनिश्चित करें, क्योंकि मुझे पूरा यकीन है कि आपका प्रबंधित एप्लिकेशन अचानक किसी अन्य प्रक्रिया संदर्भ/पता स्थान में चला रहा है, एक बुरा विचार ™ (मुझे पूरा यकीन है कि मैंने कोशिश भी नहीं की थी)। घटना सिर्फ आपके स्वयं के नहीं, बल्कि प्रत्येक कंसोल विंडो के लिए आग लग जाएगी। तो विंडो हैंडल द्वारा कॉलबैक में सभी कॉल फ़िल्टर करें। GetConsoleWindow() के साथ वर्तमान कंसोल एप्लिकेशन के विंडो हैंडल को पुनः प्राप्त करें। आवेदन पूरा होने पर कॉलबैक को अनदेखा करना भी न भूलें।
  • नोट, इस बिंदु तक सुनिश्चित करें कि सिस्टम का उपयोग न करें (या कुछ भी जो लोड का कारण बनता है)। कंसोल क्लास, या संभावना से अधिक चीजें गलत हो जाएंगी। इस बिंदु के बाद उपयोग इस तरह व्यवहार करेगा जैसे उप प्रक्रिया ने आउटपुट को लिखा था।
  • स्पोन जरूरत उप प्रक्रिया (ध्यान दें, आप का उपयोग करना चाहिए .UseShellExecute = झूठी या यह सांत्वना लागू नहीं होंगे)
  • आप या WriteConsoleInput()
  • का उपयोग कर इस बिंदु पर सांत्वना के लिए इनपुट प्रदान करने शुरू कर सकते हैं (पर एक अलग धागा) आपको एक विंडोज़ संदेश लूप चलाने के लिए है या आप कंसोल इवेंट अधिसूचना कॉलबैक प्राप्त नहीं करेंगे। आप इसे करने के लिए पैरामीटर रहित एप्लिकेशन.रुन() का उपयोग कर सकते हैं। संदेश लूप को तोड़ने के लिए, आपको किसी बिंदु पर अपने संदेश पाश पर निकास संदेश पोस्ट करना होगा। मैंने यह सबप्रोसेस के एक्सक्टेड ईवेंट में एप्लीकेशन.एक्सिट() के साथ किया था। (ध्यान दें। इसके लिए काम करने के लिए सक्षम RaisingEvents)
  • कॉल आपके कंसोल पर कुछ बदलते समय आपके जीत ईवेंट कॉलबैक में किए जाएंगे। स्क्रॉल घटना पर ध्यान दें, यह कुछ हद तक अप्रत्याशित काम कर सकता है। सिंक्रोनस डिलीवरी के बारे में भी कोई धारणा नहीं है। यदि उप प्रक्रिया 3 लाइनों को लिखती है, तब तक जब आप पहली घटना को संसाधित कर रहे हों, शेष 3 पंक्तियां पहले से ही लिखी जा सकती हैं। निष्पक्ष होने के लिए, खिड़कियां ऐसी घटनाओं को लिखने का एक अच्छा काम करती हैं जैसे कि आप एकल चरित्र परिवर्तनों के साथ घूमते नहीं हैं और परिवर्तनों को जारी रख सकते हैं।
  • CharSet = CharSet.Unicode के साथ सभी PInvoke परिभाषाओं को चिह्नित करना सुनिश्चित करें यदि उनमें इनपुट या आउटपुट में कहीं भी कोई वर्ण होता है। PInvoke.net इनमें से कुछ चूक गए।

इन सभी का शुद्ध परिणाम: विंडोज कंसोल एपीआई के लिए एक रैपर एप्लिकेशन। रैपर दुनिया के साथ संवाद करने के लिए पुनर्निर्देशित stdin और stdout को पढ़/लिख सकता है। अगर आप फैंसी प्राप्त करना चाहते हैं तो आप यहां किसी भी स्ट्रीम का उपयोग कर सकते हैं (नामित पाइप, टीसीपी/आईपी, आदि ..)। मैंने कुछ एक्सटेरम नियंत्रण अनुक्रमों को लागू किया और पूरी तरह से काम कर रहे टर्मिनल रैपर प्राप्त करने में कामयाब रहे जो किसी भी विंडोज कंसोल प्रक्रिया को लपेटने में सक्षम होना चाहिए, लक्ष्य अनुप्रयोग के कंसोल इनपुट पर इनपुट करने के लिए xterm इनपुट का अनुवाद करें और एप्लिकेशन के आउटपुट को xterm नियंत्रण अनुक्रमों में संसाधित करें। मुझे माउस को काम करने के लिए भी मिला। Subhe के रूप में powerhell.exe शुरू करना अब एक एसएसएच सत्र में चल रहे पावरहेल की मूल समस्या हल करता है। सीएमडी.एक्सई भी काम करता है। अगर कोई हस्तक्षेप कर रहा है तो मैं कहीं भी पूरा कोड पोस्ट करने के बारे में देखूंगा।

+0

यह शानदार होगा अगर आप इस कोड को साझा कर सकते हैं। –

+0

मार्क, यह एक सीमा हो सकती है जो लाभ आधारित है। –

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