c# - क्या एक निष्पादन योग्य कंसोल और जीयूआई आवेदन दोनों हो सकता है?




user-interface command-line-interface (6)

आप जो चाहते हैं उसे करने का एक आसान तरीका है। जब मैं एक सीएलआई और एक जीयूआई होना चाहिए, तो मैं हमेशा इसका उपयोग कर रहा हूं। काम करने के लिए आपको अपने "आउटपुट टाइप" को "कंसोल एप्लिकेशन" पर सेट करना होगा।

class Program {
  [DllImport("kernel32.dll", EntryPoint = "GetConsoleWindow")]
  private static extern IntPtr _GetConsoleWindow();

  /// <summary>
  /// The main entry point for the application.
  /// </summary>
  [STAThread]
  static void Main(string[] args) {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    /*
     * This works as following:
     * First we look for command line parameters and if there are any of them present, we run the CLI version.
     * If there are no parameters, we try to find out if we are run inside a console and if so, we spawn a new copy of ourselves without a console.
     * If there is no console at all, we show the GUI.
     * We make an exception if we find out, that we're running inside visual studio to allow for easier debugging the GUI part.
     * This way we're both a CLI and a GUI.
     */
    if (args != null && args.Length > 0) {

      // execute CLI - at least this is what I call, passing the given args.
      // Change this call to match your program.
      CLI.ParseCommandLineArguments(args);

    } else {
      var consoleHandle = _GetConsoleWindow();

      // run GUI
      if (consoleHandle == IntPtr.Zero || AppDomain.CurrentDomain.FriendlyName.Contains(".vshost"))

        // we either have no console window or we're started from within visual studio
        // This is the form I usually run. Change it to match your code.
        Application.Run(new MainForm());
      else {

        // we found a console attached to us, so restart ourselves without one
        Process.Start(new ProcessStartInfo(Assembly.GetEntryAssembly().Location) {
          CreateNoWindow = true,
          UseShellExecute = false
        });
      }
    }
  }

मैं एक C# प्रोग्राम बनाना चाहता हूं जिसे सीएलआई या जीयूआई एप्लीकेशन के रूप में चलाया जा सकता है, इस पर निर्भर करता है कि इसमें क्या झंडे हैं। क्या यह किया जा सकता है?

मुझे इन संबंधित प्रश्न मिल गए हैं, लेकिन वे मेरी स्थिति को बिल्कुल सही नहीं करते हैं:


इस विषय पर रेमंड के ब्लॉग देखें:

http://blogs.msdn.com/oldnewthing/archive/2009/01/01/9259142.aspx

उनकी पहली वाक्य: "आप नहीं कर सकते, लेकिन आप इसे नकली करने की कोशिश कर सकते हैं।"


मुझे लगता है कि पसंदीदा तकनीक वह है जिसे रॉब ने दो एक्जिक्यूटिव का उपयोग करने की डेवेन तकनीक कहा: एक लॉन्चर ".com" और मूल ".exe"। यदि आपके पास बॉयलरप्लेट कोड के साथ काम करने के लिए है (नीचे लिंक देखें) तो यह उपयोग करना मुश्किल नहीं है।

यह तकनीक ट्रिक्स का उपयोग करती है ताकि ".com" stdin / stdout / stderr के लिए प्रॉक्सी हो और समान नाम वाली .exe फ़ाइल लॉन्च करे। यह प्रोग्राम को कमांड लाइन मोड में प्रीफ़ॉर्म करने की अनुमति देता है जब फॉर्म कंसोल कहा जाता है (संभावित रूप से केवल कुछ कमांड लाइन तर्कों का पता लगाया जाता है) जबकि अभी भी एक कंसोल से जीयूआई एप्लिकेशन के रूप में लॉन्च करने में सक्षम होता है।

मैंने Google Code पर ड्यूलसब्ससिस्टम नामक एक प्रोजेक्ट की मेजबानी की जो इस तकनीक के पुराने कोडगुरु समाधान को अपडेट करता है और स्रोत कोड और कामकाजी उदाहरण बाइनरी प्रदान करता है।



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

कैड का उत्तर एक कंसोल के साथ .Net WinForms एप्लिकेशन चलाने के बारे में एक लेख को इंगित करता है । कार्यक्रम शुरू होने के बाद यह AttachConsole को कॉल करने की तकनीक का उपयोग करता है। इस कार्यक्रम को प्रोग्राम शुरू करने वाले कमांड प्रॉम्प्ट की कंसोल विंडो पर वापस लिखने की अनुमति देने का प्रभाव है। लेकिन उस लेख में टिप्पणियां बताती हैं कि मैं क्या घातक दोष मानता हूं: बाल प्रक्रिया वास्तव में कंसोल को नियंत्रित नहीं करती है। कंसोल मूल प्रक्रिया की तरफ से इनपुट स्वीकार कर रहा है, और माता-पिता की प्रक्रिया इस बात से अवगत नहीं है कि इसे अन्य चीजों के लिए कंसोल का उपयोग करने से पहले बच्चे को दौड़ना समाप्त करना चाहिए।

चेन का लेख जूनफेंग झांग द्वारा एक लेख को इंगित करता है जो कुछ अन्य तकनीकों को बताता है

पहला यह है कि डेवेनव क्या उपयोग करता है। यह वास्तव में दो कार्यक्रमों के द्वारा काम करता है। एक devenv.exe है , जो मुख्य जीयूआई प्रोग्राम है, और दूसरा devenv.com है , जो कंसोल-मोड कार्यों को संभालता है, लेकिन यदि इसका उपयोग गैर-कंसोल-जैसी तरीके से किया जाता है, तो यह इसके कार्यों को devenv.exe पर आगे बढ़ाता है और बाहर निकलता है। तकनीक Win32 नियम पर निर्भर करती है कि जब आप फ़ाइल एक्सटेंशन के बिना कमांड टाइप करते हैं तो कॉम फ़ाइलों को exe फ़ाइलों से पहले चुना जाता है।

इस पर एक सरल भिन्नता है कि विंडोज स्क्रिप्ट होस्ट करता है। यह दो पूरी तरह से अलग बाइनरी, wscript.exe और cscript.exe प्रदान करता है। इसी तरह, जावा कंसोल प्रोग्राम्स के लिए java.exe प्रदान करता है और गैर-कंसोल प्रोग्राम्स के लिए javaw.exe प्रदान करता है।

जुन्फेंग की दूसरी तकनीक हल्का उपयोग करता है। उन्होंने इस प्रक्रिया को उद्धृत किया कि ildasm के लेखक दोनों मोड में इसे चलाने के दौरान चले गए। आखिरकार, यह वही है जो यह करता है:

  1. कार्यक्रम को कंसोल-मोड बाइनरी के रूप में चिह्नित किया गया है, इसलिए यह हमेशा कंसोल से शुरू होता है। यह सामान्य और सामान्य रूप से काम करने के लिए इनपुट और आउटपुट रीडायरेक्शन की अनुमति देता है।
  2. यदि प्रोग्राम में कोई कंसोल-मोड कमांड-लाइन पैरामीटर नहीं है, तो यह स्वयं को फिर से लॉन्च करता है।

पहला उदाहरण कंसोल प्रोग्राम होने के लिए बस FreeConsole को कॉल करने के लिए पर्याप्त नहीं है। ऐसा इसलिए है क्योंकि प्रोग्राम शुरू करने वाली प्रक्रिया, cmd.exe , "जानता है" कि यह एक कंसोल-मोड प्रोग्राम शुरू कर दिया है और प्रोग्राम को चलना बंद करने का इंतजार कर रहा है। कॉलिंग FreeConsole कंसोल का उपयोग करके ildasm स्टॉप कर देगा, लेकिन यह कंसोल का उपयोग करके मूल प्रक्रिया शुरू नहीं करेगा।

तो पहला उदाहरण खुद को पुन: प्रारंभ करता है (एक अतिरिक्त कमांड लाइन पैरामीटर के साथ, मुझे लगता है)। जब आप CreateProcess कॉल करते हैं, तो DETACHED_PROCESS और CREATE_NEW_CONSOLE को आजमाने के लिए दो अलग-अलग झंडे हैं, जिनमें से कोई भी यह सुनिश्चित करेगा कि दूसरा उदाहरण पैरेंट कंसोल से जुड़ा नहीं होगा। उसके बाद, पहला उदाहरण कमांड प्रॉम्प्ट को प्रोसेसिंग कमांड को फिर से शुरू करने की अनुमति दे सकता है।

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

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

तब नीचे की रेखा यह है कि आप या तो दो द्विआधारी हो सकते हैं, या आप कंसोल विंडो का एक क्षणिक झिलमिलाहट कर सकते हैं । एक बार जब आप कम बुराई तय करते हैं, तो आपके पास कार्यान्वयन की आपकी पसंद है।

* मैं जीयूआई के बजाय गैर-कंसोल कहता हूं क्योंकि अन्यथा यह एक झूठी डिचोटोमी है। सिर्फ इसलिए कि किसी प्रोग्राम में कंसोल नहीं होता है इसका मतलब यह नहीं है कि इसमें एक जीयूआई है। एक सेवा आवेदन एक प्रमुख उदाहरण है। इसके अलावा, एक प्रोग्राम में एक कंसोल और खिड़कियां हो सकती हैं।


http://www.csharp411.com/console-output-from-winforms-application/

WinForms Application. से पहले कमांड लाइन तर्कों की जांच करें Application. सामान।

मुझे इसे .NET में जोड़ना चाहिए, यह एक ही समाधान में कंसोल और जीयूआई परियोजनाओं को सरल बनाना आसान है जो मुख्य को छोड़कर उनके सभी असेंबली साझा करते हैं। और इस मामले में, आप कमांड लाइन संस्करण को जीयूआई संस्करण लॉन्च कर सकते हैं यदि इसे बिना पैरामीटर के लॉन्च किया गया हो। आपको एक चमकदार कंसोल मिलेगा।





command-line-interface