2010-11-16 16 views
10

मेरे पास एक ऐसा एप्लिकेशन है जो किसी अन्य एप्लिकेशन से डेटा भेजने और प्राप्त करने के लिए सॉकेट कनेक्शन का उपयोग करता है। सॉकेट बनाने के दौरान यह बंदरगाह 49 9 8 का उपयोग करता है।एप्लिकेशन का केवल एक उदाहरण कैसे चलाएं

यही वह जगह है जहां मेरी समस्या झूठ बोलती है। एक बार जब मैं अपना आवेदन शुरू करता हूं तो सॉकेट बंदरगाह 49 9 8 का उपयोग शुरू करता है। इसलिए यदि मैं एप्लिकेशन को फिर से निष्पादित करना चाहता हूं तो मुझे सॉकेट बाइंडिंग त्रुटि मिलती है।

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

उत्तर

10

आप नाम mutex का उपयोग कर सकते हैं। article से

कोड का नमूना:

WINAPI WinMain(
    HINSTANCE, HINSTANCE, LPSTR, int) 
{ 
    try { 
    // Try to open the mutex. 
    HANDLE hMutex = OpenMutex(
     MUTEX_ALL_ACCESS, 0, "MyApp1.0"); 

    if (!hMutex) 
     // Mutex doesn’t exist. This is 
     // the first instance so create 
     // the mutex. 
     hMutex = 
     CreateMutex(0, 0, "MyApp1.0"); 
    else 
     // The mutex exists so this is the 
     // the second instance so return. 
     return 0; 

    Application->Initialize(); 
    Application->CreateForm(
     __classid(TForm1), &Form1); 
    Application->Run(); 

    // The app is closing so release 
    // the mutex. 
    ReleaseMutex(hMutex); 
    } 
    catch (Exception &exception) { 
    Application-> 
     ShowException(&exception); 
    } 
    return 0; 
} 
+12

पहले OpenMutex() को कॉल करके, आपके पास दौड़ की स्थिति है। पहले CreateMutex/Ex() को कॉल करें। यह आपको बताएगा कि म्यूटेक्स पहले से मौजूद है या नहीं। OpenMutex() को केवल कॉल करें यदि CreateMutex() किसी ERROR_ACCESS_DENIED त्रुटि के साथ विफल रहता है। –

+0

Win7 + पर यह काम कैसे करें इस पर कोई सुझाव? वैश्विक \ x mutexes अलग-अलग उपयोगकर्ता लॉगऑन सत्रों से एक दूसरे को नहीं देखता है ... –

+1

@ रोमनप्लेसिल वे वास्तव में करते हैं, आपने कुछ गलत किया होगा – paulm

3

शुरुआत में नामांकित ईवेंट बनाएं और परिणाम जांचें। यदि ईवेंट पहले से मौजूद है तो एप्लिकेशन बंद करें।

BOOL CheckOneInstance() 
{ 
    m_hStartEvent = CreateEventW(NULL, TRUE, FALSE, L"EVENT_NAME_HERE"); 
    if (GetLastError() == ERROR_ALREADY_EXISTS) { 
     CloseHandle(m_hStartEvent); 
     m_hStartEvent = NULL; 
     // already exist 
     // send message from here to existing copy of the application 
     return FALSE; 
    } 
    // the only instance, start in a usual way 
    return TRUE; 
} 

ऐप निकास पर m_hStartEvent बंद करें।

+0

यदि CreatEvent() विफल रहता है, तो आप यह नहीं बता सकते कि ऐप पहले से चल रहा है या नहीं, इसलिए आपको बाहर निकलना चाहिए, जारी नहीं रखना चाहिए। –

1

आप पहले से ही है, तो आपके आवेदन चल रहा है की जाँच करने के लिए एक रास्ता नहीं है? अगर पोर्ट पहले से लिया गया है, तो आपको म्यूटेक्स की आवश्यकता है, आपको पता है कि ऐप चल रहा है!

+0

हाँ अब मैं त्रुटि दिखाने के बजाय मुझे प्रक्रिया का उपयोग कर अपना आवेदन लाने की आवश्यकता है आईडी। कोई मदद? – Simsons

+5

सिर्फ इसलिए कि बंदरगाह का उपयोग किया जा रहा है, इसका मतलब यह नहीं है कि आपका एप्लिकेशन इसका उपयोग कर रहा है। –

+0

@ ओजे, गुड कैच। बंदरगाह का उपयोग कुछ अन्य ऐप – Simsons

4

/* मुझे आवश्यक संपादन करने के लिए मिला है। आवश्यक कुछ अतिरिक्त कोड और संपादन जोड़ा गया है। वर्तमान में मेरे लिए पूरी तरह से काम कर रहा है। मदद के लिए, Kirill वी। Lyadvinsky और रेमी Lebeau धन्यवाद!

*/

bool CheckOneInstance() 
{ 

    HANDLE m_hStartEvent = CreateEventW(NULL, FALSE, FALSE, L"Global\\CSAPP"); 

    if(m_hStartEvent == NULL) 
    { 
    CloseHandle(m_hStartEvent); 
     return false; 
    } 


    if (GetLastError() == ERROR_ALREADY_EXISTS) { 

     CloseHandle(m_hStartEvent); 
     m_hStartEvent = NULL; 
     // already exist 
     // send message from here to existing copy of the application 
     return false; 
    } 
    // the only instance, start in a usual way 
    return true; 
} 

/* ऊपर कोड भी काम करता है जब एक किसी अन्य लॉगिन इसके उदाहरण चल साथ प्रथम प्रवेश के लिए खुला छोड़ने से दूसरे उदाहरण को खोलने के लिए कोशिश करता है। */

2

जब आपका एप्लिकेशन प्रारंभ होता है, तो एक म्यूटेक्स बनाएं। यदि यह पहले से मौजूद है, तो मौजूदा एप्लिकेशन ढूंढें और इसे अग्रभूमि में लाएं। यदि एप्लिकेशन की मुख्य विंडो के लिए एक निश्चित शीर्षक है, तो FindWindow के साथ ढूंढना आसान है।

m_singleInstanceMutex = CreateMutex(NULL, TRUE, L"Some unique string for your app"); 
if (m_singleInstanceMutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS) { 
    HWND existingApp = FindWindow(0, L"Your app's window title"); 
    if (existingApp) SetForegroundWindow(existingApp); 
    return FALSE; // Exit the app. For MFC, return false from InitInstance. 
} 
संबंधित मुद्दे