2009-02-04 16 views
34

मुझे एक कंसोल एप्लिकेशन बनाना है जिसके लिए कुछ पैरामीटर की आवश्यकता है। अगर वे गुम या गलत हैं तो मैं एक त्रुटि संदेश मुद्रित करता हूं।क्या एक Win32 कंसोल एप्लिकेशन पता लगा सकता है कि यह एक्सप्लोरर से चलाया गया है या नहीं?

अब समस्या: यदि कोई कंसोल विंडो डबल-क्लिक करके एक्सप्लोरर से प्रोग्राम शुरू करता है तो तुरंत गायब हो जाता है। (लेकिन एप्लिकेशन एक्सप्लोरर से पूरी तरह बेकार नहीं है, आप फाइलों को खींच सकते हैं और यह काम करेगा)

मैं हमेशा एक कीप्रेस की प्रतीक्षा कर सकता हूं, लेकिन मैं नहीं चाहता कि उपयोगकर्ता इसे शुरू कर दे कमांड लाइन से।

क्या इन स्थितियों के बीच अंतर करने का कोई तरीका है?

+1

+1! बस एक समान प्रश्न पूछने के बारे में था। –

उत्तर

27

http://support.microsoft.com/kb/99115 देखें, "जानकारी: कंसोल विंडो को गायब होने से रोकें"।

विचार यह निर्धारित करने के लिए GetConsoleScreenBufferInfo का उपयोग करना है कि कर्सर प्रारंभिक 0,0 स्थिति से स्थानांतरित नहीं हुआ है। @tomlogic से

कोड का नमूना, संदर्भित ज्ञानकोष लेख पर आधारित:

// call in main() before printing to stdout 
// returns TRUE if program is in its own console (cursor at 0,0) or 
// FALSE if it was launched from an existing console. 
// See http://support.microsoft.com/kb/99115 
#include <stdio.h> 
#include <windows.h> 
int separate_console(void) 
{ 
    CONSOLE_SCREEN_BUFFER_INFO csbi; 

    if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) 
    { 
     printf("GetConsoleScreenBufferInfo failed: %lu\n", GetLastError()); 
     return FALSE; 
    } 

    // if cursor position is (0,0) then we were launched in a separate console 
    return ((!csbi.dwCursorPosition.X) && (!csbi.dwCursorPosition.Y)); 
} 
+1

यह काफी मूल :) हालांकि यह एक हैक है, यह वही करता है जो मुझे चाहिए और पीपीआईडी ​​प्राप्त करने के बाद यह कहीं अधिक सरल है। –

+0

आपको केवल इस हैक का उपयोग करना चाहिए जब ऐप को कोई तर्क नहीं दिया जाता है ताकि आप cmd.exe – Anders

+0

से "cls और app फ़ाइल नाम" कर सकें, बस इस समाधान को कार्यान्वित किया गया है, और यह MinGW/MSYS- संकलित कमांड-लाइन ऐप के लिए बहुत अच्छा काम करता है । और, @Anders, 'cls && appname.exe' ठीक काम करता है। मैं इस जवाब को संपादित करने जा रहा हूं जिसमें कोड का उपयोग कर रहा हूं, दूसरों के संदर्भ में। – tomlogic

3

मेरा मानना ​​है कि cmd.exe सीएमडीसीएमडीलाइन और सीएमडीईक्स्टवर्सन एनवायरमेंटल चर सेट करता है जब यह शुरू होता है। तो यदि ये सेट हैं तो आपका प्रोग्राम शायद एक खोल से शुरू हुआ था।

यह मूर्खतापूर्ण नहीं है लेकिन यह कुछ है।

कुछ पतले और संभवतः अविश्वसनीय तरीके से अपने माता-पिता पीआईडी ​​को निर्धारित करना भी संभव है, या इसलिए मैं इकट्ठा करता हूं। आप उसमें देखना चाह सकते हैं।

+1

मैंने पर्यावरण चर की कोशिश की, और वे मौजूद नहीं हैं, न ही cmd.exe से चलते हैं और न ही जब बाहर चलाते हैं। हालांकि, 'echo% cmdcmdline% 'टाइप करना कुछ उत्पन्न करता है, इसलिए चर स्पष्ट रूप से केवल cmd.exe में मान्य है, न कि इसकी बाल प्रक्रियाएं। – Timwi

0

त्रुटि संदेश प्रदर्शित करते समय एक कीस्ट्रोक की प्रतीक्षा करने के बारे में, और अन्य बार नहीं?

5

GetConsoleTitle()

मैंने देखा है कोड है जो

if (!GetConsoleTitle(NULL, 0) && GetLastError() == ERROR_SUCCESS) { 
    // Console 
} else { 
    // GUI 
} 

लेकिन करता है ... मैं हमने पाया कि AttachConsole() अधिक सहायक है

सी ++ में (मेरे सिर के ऊपर से, और मैं कोई सी ++ प्रोग्रामर नहीं हूं)

if (!AttachConsole(ATTACH_PARENT_PROCESS)) { 
    // GUI 
} else { 
    // Console, and you have a handle to the console that already exists. 
} 

अधिक प्रभावी है। इसके अतिरिक्त, यदि आप स्वयं को जीयूआई पर्यावरण में पाते हैं और जब तक आप कर सकते हैं तब तक वहां रहना चाहेंगे, लेकिन बाद में कुछ आपदाजनक हो गया है जो वास्तव में एक कंसोल विंडो में डंप का उपयोग कर सकता है (आप एक संपादन बॉक्स लिखने के लिए arsed नहीं किया जा सकता खिड़की को एनटी सिस्टम लॉग से जोड़ने या संलग्न करने के लिए और MessageBox() फेंक दें) अच्छी तरह से आप प्रक्रिया में बाद में AllocConsole() कर सकते हैं, जब जीयूआई विधियां विफल हो गई हैं।

+2

कुछ प्रतिक्रिया: मैं इसे मिनीजीडब्लू/एमएसवाईएस के साथ संकलित कमांड लाइन एप में करने के लिए देख रहा हूं। मेरे लिए कोई भी विधि काम नहीं की गई - मैं विंडोज एक्सप्लोरर में ऐप पर फ़ाइल खींचने और बैश खोल के अंदर कमांड लाइन पर इसे निष्पादित करने के बीच अंतर नहीं कर सका। – tomlogic

0

यह एक आकर्षण की तरह काम करता है:

@echo off 
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" goto nonconsole 

:console 
<do something> 
goto exit 

:nonconsole 
<do something> 
pause 

:exit 

this thread से कॉपी किया गया। मैंने% cmdcmdline% का मूल्यांकन करने का भी प्रयास किया, हालांकि उद्धरण वर्णों (") के बारे में कोई समस्या है, जो जैसे"% cmdcmdline% "=="% comSpec% "goto [target] काम करने से रोकती है।

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

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