क्या एक निष्पादन योग्य दोनों कंसोल और GUI अनुप्रयोग हो सकते हैं?


81

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

मैंने इन संबंधित प्रश्नों को पाया है, लेकिन वे मेरी स्थिति को पूरी तरह से कवर नहीं करते हैं:



1
सिर्फ रिकॉर्ड के लिए: यह वास्तव में ऑपरेटिंग सिस्टम से संबंधित है, सीएलआर से नहीं। उदाहरण के लिए, लिनक्स पर मोनो के साथ, इस तरह के एप्लिकेशन को बनाने में कोई समस्या नहीं है (वास्तव में, प्रत्येक एप्लिकेशन कंसोल है, लेकिन विंडोज़ के साथ जो कुछ भी कर सकते हैं) - जैसे कि जावा या किसी अन्य * निक्स प्रोग्राम के साथ। और सामान्य पैटर्न उपयोगकर्ता के लिए GUI का उपयोग करते समय कंसोल पर लॉगिंग करना है।
konrad.kruczynski

जवाबों:


99

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

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

चेन का लेख जुनफेंग झांग के एक लेख की ओर इशारा करता है जो अन्य तकनीकों के बारे में बताता है

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

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

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

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

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

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

इस तकनीक का साइड इफेक्ट यह है कि जब आप GUI इंटरफ़ेस से प्रोग्राम शुरू करते हैं, तब भी एक कंसोल होगा। यह स्क्रीन पर पल-पल फ्लैश करेगा और फिर गायब हो जाएगा।

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

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

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


मुझे पता है कि यह एक पुराना उत्तर है, लेकिन एडिटबिन के बारे में रेड-हेरिंग बिंदुओं पर, मेरा मानना ​​है कि ट्रिक का उद्देश्य WinMainउचित मापदंडों के साथ एक फ़ंक्शन को जोड़ने के लिए सीआरटी प्राप्त करना है (इसलिए इसके साथ संकलित करें /SUBSYSTEM:WINDOWS) फिर मोड पूर्व पोस्ट फैक्टो को बदलें लोडर एक कंसोल होस्ट लॉन्च करता है। अधिक प्रतिक्रिया के लिए, मैंने इसे CREATE_NO_WINDOWCreateProcess में और GetConsoleWindow() == NULLमेरे चेक-इफ़-relaunched या नहीं के रूप में आज़माया । यह कंसोल फ़्लिकर को ठीक नहीं करता है, लेकिन इसका मतलब यह नहीं है कि एक विशेष cmd तर्क नहीं है।

यह एक शानदार उत्तर है, लेकिन पूर्णता के लिए यह संभवतः यह बताने लायक है कि कंसोल और 'नॉन-कंसोल' प्रोग्राम के बीच मुख्य अंतर क्या हैं (गलतफहमी यहां गलत अनुमान के कई जवाब देने के लिए पैदा होती है)। वह है: कंसोल ऐप, कंसोल से लॉन्च किया गया, जब तक यह पूरा नहीं हो जाता है, तब तक पैरेंट कंसोल पर नियंत्रण वापस नहीं आएगा, जबकि GUI ऐप कांटा करेगा, और तुरंत वापस आ जाएगा। अनिश्चित होने पर, आप DUMPBIN / हेडर का उपयोग कर सकते हैं और SUBSYSTEM लाइन को देख सकते हैं कि वास्तव में आपको कौन सा स्वाद मिला है।
piers7

यह एक अप्रचलित सर्वश्रेष्ठ उत्तर है। कम से कम C / C ++ के नजरिए से। Win32 के लिए नीचे डेंटिल का समाधान देखें, जिसे संभवतः किसी के द्वारा C # के लिए अनुकूलित किया जा सकता है।
बी। नाडोलसन १३'१५ को

1
मैं इस उत्तर को अप्रचलित नहीं मानता। विधि अच्छी तरह से काम करती है, और उत्तर की रेटिंग खुद के लिए बोलती है। Dantill का दृष्टिकोण कंसोल ऐप से स्टड को डिस्कनेक्ट करता है। मैंने एक अलग उत्तर के रूप में नीचे कैनेडी के "क्षणिक झिलमिलाहट" दृष्टिकोण का एक सी संस्करण प्रदान किया है (हां, मुझे पता है, ओपी ने # के बारे में पोस्ट किया है)। मैंने कई बार इसका इस्तेमाल किया है और इससे काफी खुश हूं।
विलस

आप इसे जावा में कर सकते हैं ..)
एंटोनियोसस

11

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

https://devblogs.microsoft.com/oldnewthing/20090101-00/?p=19643

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


.Net वास्तव में इसे "नकली" करना बहुत आसान बनाता है, लेकिन यह उत्तर तकनीकी रूप से सही है।
जोएल कोएहॉर्न

6

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

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

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


कमांड लाइन परमेस का अस्तित्व शायद ही एक निश्चित अग्नि संकेत है। बहुत सारे विंडोज़ ऐप कमांड लाइन परम्स ले सकते हैं
नील एन

3
मेरा कहना था कि अगर कोई नहीं है, तो GUI संस्करण लॉन्च करें। यदि आप मापदंडों के साथ लॉन्च किया गया GUI संस्करण चाहते हैं, तो संभवतः आपके पास इसके लिए एक पैरामीटर हो सकता है।
रॉक्स

5

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

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
        });
      }
    }
  }

1
मुझे यह पसंद है और यह मेरे विंडोज 7 देव मशीन पर ठीक काम करता है। जब भी मेरे पास (वर्चुअल) विंडोज एक्सपी मशीन होती है और ऐसा लगता है कि रीस्टार्ट की गई प्रक्रिया में हमेशा एक कंसोल मिलता है और इसलिए एक अंतहीन लूप में ही गायब हो जाता है। कोई विचार?
सिमोन हेविट

1
इस के साथ बहुत सावधान रहें, विंडोज एक्सपी पर यह वास्तव में एक असीमित रिस्पॉन्स लूप की ओर जाता है जिसे मारना बहुत कठिन है।
उपयोगकर्ता

3

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

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

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


3

यहाँ मैं समस्या का सरल .NET C # समाधान होना मानता हूँ। बस समस्या को शांत करने के लिए, जब आप स्विच के साथ कमांड लाइन से ऐप के कंसोल "संस्करण" को चलाते हैं, तो कंसोल प्रतीक्षा करता रहता है (यह कमांड प्रॉम्प्ट पर वापस नहीं आता है और प्रक्रिया चालू रहती है) भले ही आपके पास Environment.Exit(0)अपने कोड के अंत में। इसे ठीक करने के लिए Environment.Exit(0), कॉल करने से ठीक पहले , इसे कॉल करें:

SendKeys.SendWait("{ENTER}");

तब कंसोल को अंतिम एंटर कुंजी मिलती है जिसे कमांड प्रॉम्प्ट पर वापस लौटना पड़ता है और प्रक्रिया समाप्त हो जाती है। नोट: कॉल न करें SendKeys.Send(), या ऐप क्रैश हो जाएगा।

यह अभी भी AttachConsole()कई पोस्टों में वर्णित के रूप में कॉल करने के लिए आवश्यक है , लेकिन इसके साथ ही मुझे ऐप के WinForm संस्करण को लॉन्च करते समय कोई कमांड विंडो झिलमिलाहट नहीं मिलती है।

मेरे द्वारा बनाए गए एक नमूना ऐप में पूरा कोड है (बिना WinForms कोड के):

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ConsoleWriter
{
    static class Program
    {
        [DllImport("kernel32.dll")]
        private static extern bool AttachConsole(int dwProcessId);
        private const int ATTACH_PARENT_PROCESS = -1;

        [STAThread]
        static void Main(string[] args)
        {
            if(args.Length > 0 && args[0].ToUpperInvariant() == "/NOGUI")
            {
                AttachConsole(ATTACH_PARENT_PROCESS);
                Console.WriteLine(Environment.NewLine + "This line prints on console.");

                Console.WriteLine("Exiting...");
                SendKeys.SendWait("{ENTER}");
                Environment.Exit(0);
            }
            else
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }
}

आशा है कि यह किसी को इस समस्या पर दिन बिताने से भी मदद करता है। संकेत के लिए @dantill पर जाएं।


मैंने यह कोशिश की और समस्या यह है कि कुछ भी लिखा हुआ उपयोग Console.WriteLineमाता-पिता (कंसोल) के टेक्स्ट कर्सर को आगे नहीं बढ़ाता है। इसलिए जब आप ऐप से बाहर निकलते हैं, तो कर्सर की स्थिति गलत जगह पर होती है और आपको इसे "क्लीन" प्रॉम्प्ट पर वापस लाने के लिए कुछ बार एंटर दबाना होता है।
ताहिर हसन

@TahirHassan आप यहां बताए अनुसार शीघ्र कब्जा और सफाई को स्वचालित कर सकते हैं, लेकिन यह अभी भी एक सही समाधान नहीं है: stackoverflow.com/questions/1305257/…
rkagerer

2
/*
** dual.c    Runs as both CONSOLE and GUI app in Windows.
**
** This solution is based on the "Momentary Flicker" solution that Robert Kennedy
** discusses in the highest-rated answer (as of Jan 2013), i.e. the one drawback
** is that the console window will briefly flash up when run as a GUI.  If you
** want to avoid this, you can create a shortcut to the executable and tell the
** short cut to run minimized.  That will minimize the console window (which then
** immediately quits), but not the GUI window.  If you want the GUI window to
** also run minimized, you have to also put -minimized on the command line.
**
** Tested under MinGW:  gcc -o dual.exe dual.c -lgdi32
**
*/
#include <windows.h>
#include <stdio.h>

static int my_win_main(HINSTANCE hInstance,int argc,char *argv[],int iCmdShow);
static LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam);
static int win_started_from_console(void);
static BOOL CALLBACK find_win_by_procid(HWND hwnd,LPARAM lp);

int main(int argc,char *argv[])

    {
    HINSTANCE hinst;
    int i,gui,relaunch,minimized,started_from_console;

    /*
    ** If not run from command-line, or if run with "-gui" option, then GUI mode
    ** Otherwise, CONSOLE app.
    */
    started_from_console = win_started_from_console();
    gui = !started_from_console;
    relaunch=0;
    minimized=0;
    /*
    ** Check command options for forced GUI and/or re-launch
    */
    for (i=1;i<argc;i++)
        {
        if (!strcmp(argv[i],"-minimized"))
            minimized=1;
        if (!strcmp(argv[i],"-gui"))
            gui=1;
        if (!strcmp(argv[i],"-gui-"))
            gui=0;
        if (!strcmp(argv[i],"-relaunch"))
            relaunch=1;
        }
    if (!gui && !relaunch)
        {
        /* RUN AS CONSOLE APP */
        printf("Console app only.\n");
        printf("Usage:  dual [-gui[-]] [-minimized].\n\n");
        if (!started_from_console)
            {
            char buf[16];
            printf("Press <Enter> to exit.\n");
            fgets(buf,15,stdin);
            }
        return(0);
        }

    /* GUI mode */
    /*
    ** If started from CONSOLE, but want to run in GUI mode, need to re-launch
    ** application to completely separate it from the console that started it.
    **
    ** Technically, we don't have to re-launch if we are not started from
    ** a console to begin with, but by re-launching we can avoid the flicker of
    ** the console window when we start if we start from a shortcut which tells
    ** us to run minimized.
    **
    ** If the user puts "-minimized" on the command-line, then there's
    ** no point to re-launching when double-clicked.
    */
    if (!relaunch && (started_from_console || !minimized))
        {
        char exename[256];
        char buf[512];
        STARTUPINFO si;
        PROCESS_INFORMATION pi;

        GetStartupInfo(&si);
        GetModuleFileNameA(NULL,exename,255);
        sprintf(buf,"\"%s\" -relaunch",exename);
        for (i=1;i<argc;i++)
            {
            if (strlen(argv[i])+3+strlen(buf) > 511)
                break;
            sprintf(&buf[strlen(buf)]," \"%s\"",argv[i]);
            }
        memset(&pi,0,sizeof(PROCESS_INFORMATION));
        memset(&si,0,sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
        si.dwX = 0; /* Ignored unless si.dwFlags |= STARTF_USEPOSITION */
        si.dwY = 0;
        si.dwXSize = 0; /* Ignored unless si.dwFlags |= STARTF_USESIZE */
        si.dwYSize = 0;
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_SHOWNORMAL;
        /*
        ** Note that launching ourselves from a console will NOT create new console.
        */
        CreateProcess(exename,buf,0,0,1,DETACHED_PROCESS,0,NULL,&si,&pi);
        return(10); /* Re-launched return code */
        }
    /*
    ** GUI code starts here
    */
    hinst=GetModuleHandle(NULL);
    /* Free the console that we started with */
    FreeConsole();
    /* GUI call with functionality of WinMain */
    return(my_win_main(hinst,argc,argv,minimized ? SW_MINIMIZE : SW_SHOWNORMAL));
    }


static int my_win_main(HINSTANCE hInstance,int argc,char *argv[],int iCmdShow)

    {
    HWND        hwnd;
    MSG         msg;
    WNDCLASSEX  wndclass;
    static char *wintitle="GUI Window";

    wndclass.cbSize        = sizeof (wndclass) ;
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = NULL;
    wndclass.hCursor       = NULL;
    wndclass.hbrBackground = NULL;
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = wintitle;
    wndclass.hIconSm       = NULL;
    RegisterClassEx (&wndclass) ;

    hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,wintitle,0,
                          WS_VISIBLE|WS_OVERLAPPEDWINDOW,
                          100,100,400,200,NULL,NULL,hInstance,NULL);
    SetWindowText(hwnd,wintitle);
    ShowWindow(hwnd,iCmdShow);
    while (GetMessage(&msg,NULL,0,0))
        {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }
    return(msg.wParam);
    }


static LRESULT CALLBACK WndProc (HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)

    {
    if (iMsg==WM_DESTROY)
        {
        PostQuitMessage(0);
        return(0);
        }
    return(DefWindowProc(hwnd,iMsg,wParam,lParam));
    }


static int fwbp_pid;
static int fwbp_count;
static int win_started_from_console(void)

    {
    fwbp_pid=GetCurrentProcessId();
    if (fwbp_pid==0)
        return(0);
    fwbp_count=0;
    EnumWindows((WNDENUMPROC)find_win_by_procid,0L);
    return(fwbp_count==0);
    }


static BOOL CALLBACK find_win_by_procid(HWND hwnd,LPARAM lp)

    {
    int pid;

    GetWindowThreadProcessId(hwnd,(LPDWORD)&pid);
    if (pid==fwbp_pid)
        fwbp_count++;
    return(TRUE);
    }

2

मैंने एक वैकल्पिक दृष्टिकोण लिखा है जो कंसोल फ्लैश से बचता है। देखें एक Windows कार्यक्रम है कि दोनों एक जीयूआई और सांत्वना आवेदन के रूप में काम करता है बनाने के लिए कैसे


1
मुझे संदेह था लेकिन यह त्रुटिपूर्ण काम करता है। वास्तव में, वास्तव में निर्दोष की तरह। बहुत ही उत्तम कार्य! मैंने देखा है जारी करने के लिए पहला सच्चा समाधान। (यह C / C ++ कोड है। C # कोड नहीं है।)
B. Nadolson

मैं बी नाडोलसन से सहमत हूं। यह काम करता है (C ++ के लिए), प्रक्रिया को फिर से शुरू किए बिना, और कई EXE के बिना।
ग्रेविटीवेल

2
इस पद्धति की कमियां: (1) इसे पूरा करने पर कंसोल को एक अतिरिक्त कीस्ट्रोक भेजना पड़ता है, (2) यह कंसोल आउटपुट को किसी फ़ाइल में रीडायरेक्ट नहीं कर सकता है, और (3) इसे जाहिरा तौर पर संलग्न स्टड (जो) के साथ परीक्षण नहीं किया गया है मुझे लगता है कि एक फ़ाइल से भी पुनर्निर्देशित नहीं किया जा सकता)। मेरे लिए, यह बहुत सारे ट्रेडों के लिए बस सांत्वना खिड़की को चमकाने से बचने के लिए है। री-लॉन्च विधि कम से कम एक सच्चे दोहरे कंसोल / GUI प्रदान करती है। मैंने ऐसे ऐप को हजारों उपयोगकर्ताओं को वितरित किया है, और उन्हें एक भी शिकायत नहीं मिली है या पल-पल चमकती कंसोल विंडो के बारे में कोई टिप्पणी नहीं मिली है।
18/07 पर विल्स

0

मेरे लिए एक स्थिर निर्माण कार्यों में AllocConsole () चलाएं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.