2012-04-04 9 views
6

मैं _popen उपयोग कर रहा हूँ एक प्रक्रिया शुरू करने के लिए एक कमांड उत्पादन चलाने के लिए और इकट्ठा करने के लिएक्या डॉस विंडो खोलने के लिए _popen को रोकने का कोई तरीका है?

यह मेरा C++ कोड है: (

bool exec(string &cmd, string &result) 
{ 
    result = ""; 

    FILE* pipe = _popen(cmd.c_str(), "rt"); 
    if (!pipe) 
     return(false); 

    char buffer[128]; 
    while(!feof(pipe)) 
    { 
     if(fgets(buffer, 128, pipe) != NULL) 
       result += buffer; 
    } 
    _pclose(pipe); 
    return(true); 
} 

वहाँ एक डॉस खिड़की खोलने के बिना ऐसा करने का कोई तरीका है यह रूप में वर्तमान में _popen कथन पर करता है)?

+0

क्या यह अभी भी दिखाता है कि क्या आप इसे कहीं भी आउटपुट रीडायरेक्ट करते हैं?एक और पाइप या एक फ़ाइल के लिए? http://msdn.microsoft.com/en-us/library/ms682499.aspx (मुझे नहीं पता, मैं केवल अनुमान लगा रहा हूं) –

उत्तर

2

जहाँ तक मुझे पता है, आप नहीं कर सकते हैं: आप एक सांत्वना आवेदन (cmd.exe, कि निर्दिष्ट कमांड चलेगा) शुरू कर रहे हैं, और Windows हमेशा एक कंसोल विंडो से उत्पन्न होने वाला एक सांत्वना आवेदन शुरू।


  1. हालांकि, आप खिड़की के बाद प्रक्रिया शुरू कर दी छिपा कर सकते हैं, या यदि आप CreateProcess करने के लिए उपयुक्त झंडे पारित भी यह छिपा बनाएँ; समस्या यह है कि, _popen इन झंडे को पास न करें, इसलिए आपको अपनी पाइप बनाने के लिए _popen के बजाय Win32 API का उपयोग करना होगा।
+0

मैं सोच रहा था कि शायद मैं एक बाल प्रक्रिया चला सकता हूं ... क्या यह किया जा सकता है और एक खिड़की नहीं दिखाओ? "सिस्टम" का उपयोग भी एक खिड़की दिखाएगा? - धन्यवाद –

+0

मैं इसे विंडो को छिपाने के लिए एकमात्र तरीका सीधे 'CreateProcess' कहता हूं,' STARTUPINFO' संरचना के 'wShowWindow' सदस्य में' SW_HIDE' निर्दिष्ट करता है। –

3

विंडोज़ पर, STARTUPINFO संरचना के साथ CreateProcess जिसमें STARTF_USESSHOWWINDOW शामिल करने के लिए dwFlags है। फिर SW_HIDE पर STARTUPINFO.dwFlags सेट करने से कंसोल विंडो को ट्रिगर होने पर छुपाया जाएगा। उदाहरण कोड (जो खराब प्रारूपित हो सकता है, और सी ++ और WinAPI का मिश्रण होता है):

#include <windows.h> 
#include <iostream> 
#include <string> 

using std::cout; 
using std::endl; 

void printError(DWORD); 

int main() 
{ 
    STARTUPINFOA si = {0}; 
    PROCESS_INFORMATION pi = { 0 }; 

    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; 
    si.wShowWindow = SW_HIDE; 
    BOOL result = ::CreateProcessA("c:/windows/system32/notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); 
    if(result == 0) { 
     DWORD error = ::GetLastError(); 
     printError(error); 
     std::string dummy; 
     std::getline(std::cin, dummy); 
     return error; 
    } 

    LPDWORD retval = new DWORD[1]; 
    ::GetExitCodeProcess(pi.hProcess, retval); 
    cout << "Retval: " << retval[0] << endl; 
    delete[] retval; 

    cout << "Press enter to continue..." << endl; 
    std::string dummy; 
    std::getline(std::cin, dummy); 

    return 0; 
} 

void printError(DWORD error) { 
    LPTSTR lpMsgBuf = nullptr; 
    FormatMessage(
     FORMAT_MESSAGE_ALLOCATE_BUFFER | 
     FORMAT_MESSAGE_FROM_SYSTEM | 
     FORMAT_MESSAGE_IGNORE_INSERTS, 
     NULL, 
     error, 
     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
     (LPTSTR) &lpMsgBuf, 
     0, NULL); 
    cout << reinterpret_cast<char*>(lpMsgBuf) << endl; 
    LocalFree(lpMsgBuf); 
} 
+0

इसे मेरे प्रयास किए गए संपादन (http://stackoverflow.com/review/suggested-edits/4113333) के माध्यम से नोट किया जाना चाहिए कि आपको प्रतिलिपि के लिए नया [] हटाएं [] को कॉल करने की आवश्यकता नहीं है। यह बेहतर प्रदर्शन करेगा और एक DWORD retval = 0 बनाकर पढ़ने/बनाए रखना आसान होगा; और गुजरना :: GetExitCodeProcess (pi.hProcess, और retval); कोउट लाइन रेटवल [0] से भी बदले में बदल जाएगी। –

0

[अंतिम संपादित करें]

एक ऐसी ही तो सवाल यह सब कुछ ऊपर कहा विलीन हो जाती है और आप अपने उत्पादन हो जाता है C++ popen command without console

[संपादित किया गया]

erk। खेद है कि मैं spawning प्रक्रियाओं के बारे में उत्साहित हो गया। मैं आपके क्यू को फिर से पढ़ता हूं। और अतिरिक्त खिड़की के अलावा आप वास्तव में प्रक्रियाओं के stdout/stderr प्राप्त करने की कोशिश कर रहे हैं। मैं बस उस उद्देश्य के लिए इसे जोड़ना चाहता हूं, मेरे सभी सुझाव दुखद रूप से अप्रासंगिक हैं। लेकिन मैं उन्हें संदर्भ के लिए यहां छोड़ दूंगा।

[संपादित]

कोई अच्छा विशिष्ट कारण के लिए (कि "खुला" को छोड़कर दोनों खिड़कियों और Macs के लिए काम करता है), मैं नहीं बल्कि CreateProcess से स्पॉन प्रक्रियाओं के लिए ShellExecute का उपयोग करें। मैं बाद में शोध करूंगा..लेकिन यहां मेरा स्टार्टप्रोसेस फ़ंक्शन है।

छिपी हुई या न्यूनतम एक ही परिणाम उत्पन्न करने लगती है। cmd विंडो में आ रहा है लेकिन यह कम हो गया है और डेस्कटॉप पर कभी भी पॉप अप नहीं होता है जो आपका प्राथमिक लक्ष्य हो सकता है।

#if defined(PLATFORM_WIN32) 
#include <Windows.h> 
#include <shellapi.h> 
#elif defined(PLATFORM_OSX) 
#include <sys/param.h> 
#endif 
namespace LGSysUtils 
{ 
// ----------------------------------------------------------------------- 
// pWindow  : {Optional} - can be NULL 
// pOperation : "edit", "explore", "find", "open", "print" 
// pFile  : url, local file to execute 
// pParameters : {Optional} - can be NULL otherwise a string of args to pass to pFile 
// pDirectory : {Optional} - set cwd for process 
// type   : kProcessWinNormal, kProcessWinMinimized, kProcessWinMaximized, kProcessHidden 
// 
bool StartProcess(void* pWindow, const char* pOperation, const char* pFile, const char* pParameters, const char* pDirectory, LGSysUtils::eProcessWin type) 
{ 
    bool rc = false; 
#if defined(PLATFORM_WIN32) 

    int showCmd; 
    switch(type) 
    { 
    case kProcessWinMaximized: 
     showCmd = SW_SHOWMAXIMIZED; 
     break; 

    case kProcessWinMinimized: 
     showCmd = SW_SHOWMINIMIZED; 
     break; 

    case kProcessHidden: 
     showCmd = SW_HIDE; 
     break; 

    case kProcessWinNormal: 
    default: 
     showCmd = SW_NORMAL; 
    } 

    int shellRC = (int)ShellExecute(reinterpret_cast<HWND>(pWindow), pOperation,pFile,pParameters,pDirectory,showCmd); 
    //Returns a value greater than 32 if successful, or an error value that is less than or equal to 32 otherwise. 
    if(shellRC > 32) 
    { 
     rc = true; 
    } 

#elif defined(PLATFORM_OSX) 
    char cmd[1024]; 
    sprintf(cmd, "%s %s", pOperation, pFile); 
    int sysrc = system(cmd); 
    dbPrintf("sysrc = %d", sysrc); 
    rc = true; 
#endif 
    return rc; 
} 

} 

[और जैसा कि पहले उल्लेख]

आपको लगता है कि शुरू की है आवेदन के लिए स्रोत कोड के नियंत्रण में है, तो आप अपने main.cpp के शीर्ष करने के लिए इस जोड़ने की कोशिश कर सकते हैं (या आप जो कुछ भी इसे नामित किया गया)

// make this process windowless/aka no console window 
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") 

आप उन विकल्पों को सीधे लिंकर को भी खिला सकते हैं। अलग बिल्ड कॉन्फ़िगरेशन imho के लिए उपरोक्त खेलना आसान है।

+2

इतना आसान नहीं है, क्योंकि दिया गया आदेश चलाने के लिए '_popen' हमेशा' cmd.exe' लॉन्च करता है, और 'cmd.exe' लिंकर झंडे से अधिक आपके पास कोई नियंत्रण नहीं होता है। –

+0

सुझाव के लिए धन्यवाद लेकिन अफसोस की बात है कि मैं लॉन्च किए गए कोड के नियंत्रण में नहीं हूं। –

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

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