Page 1 of 1

Single instance, argv and windows context menu !

Posted: Thu Jun 07, 2007 9:41 pm
by bidou
Helle everybody !

I've an application MyApp in wxWidgets code.
I use wxSingleInstanceChecker to have one instance of the program, but I want can retrieve the "argv" from the other instance (which are not created) and pass it into my single instance. I read about wxDDEClient and wxDDEServer and I understood nothing!

My english is not so good, so I hope you understood my problem :wink:

Thanks, Bidou

Posted: Thu Jun 07, 2007 11:07 pm
by mc2r
Hi,

I've never used wxSingleInstanceChecker. But could you do something like this.

Code: Select all

class mySingleInstanceChecker : public wxSingleInstanceChecker {
    public:
        void SetAppInstance(MyApp *myApp){ m_myApp = myApp};
        MyApp* GetAppInstance(void){ return m_myApp};
    protected:
        static MyApp *m_myApp;
};
Then

Code: Select all

bool MyApp::OnInit()
{
    const wxString name = wxString::Format("MyApp-%s", wxGetUserId().c_str());
    m_checker = new wxSingleInstanceChecker(name);
    if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
    m_checker-.SetAppInstance(this);
    ... more initializations ...

    return true;
}
Not sure if there is a better way to do this.

Hope this helps.

-Max

Posted: Fri Jun 08, 2007 7:50 am
by bidou
Thanks for your answer, it's a good idea, but the problem is that when I try to create a new instance of myApp it pass through the if statement :

Code: Select all

if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
but m_checker is a new instance for this app too, so GetAppInstance() return NULL and not the application which is running!

Maybe can I limit the instance of m_checker... I don't know how.

Any ideas ?

Thanks, Bidou :wink:

Posted: Fri Jun 08, 2007 3:41 pm
by mc2r
bidou wrote:Thanks for your answer, it's a good idea, but the problem is that when I try to create a new instance of myApp it pass through the if statement :

Code: Select all

if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
but m_checker is a new instance for this app too, so GetAppInstance() return NULL and not the application which is running!

Maybe can I limit the instance of m_checker... I don't know how.

Any ideas ?

Thanks, Bidou :wink:
I'm not sure what the problem is unless you are starting 2 instances of the app at the same time.
mc2r wrote:

Code: Select all

bool MyApp::OnInit()
{
    const wxString name = wxString::Format("MyApp-%s", wxGetUserId().c_str());
    m_checker = new wxSingleInstanceChecker(name);
    if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
    m_checker-.SetAppInstance(this);
    ... more initializations ...

    return true;
}
If there is no other instance of my app running m_checker->IsAnotherRunning(name) returns false so the if check is skipped. and m_checker->SetAppInstance(this) is called. If another instance is already running ie... m_checker->SetAppInstance(this) on another instance has been called the if statement will be entered for and get instance will be called.

I am not sure what the problem is, unless you are worried about two instances of MyApp starting close enough together that there is a race condition where both enter the if statement. Which I suppose could happen. That being the case lock the check in a wxMutex..


new MyApp.cpp:

Code: Select all

bool MyApp::OnInit()
{
    wxMutexLocker lock(MyAppInitMutex);
    const wxString name = wxString::Format("MyApp-%s", wxGetUserId().c_str());
    m_checker = new wxSingleInstanceChecker(name);
    if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
    m_checker->SetAppInstance(this);
    ... more initializations ...

    return true;
}
static protected member of MyApp:

Code: Select all

        static wxMutex MyAppInitMutex;
-Max

Posted: Tue Oct 09, 2007 5:33 pm
by cavolaccimiei
I'm having troubles implementing this... I really hope this works but i have some doubts because:

the m_myApp var of mySingleInstance instance named m_checker is relative to the "original" instance of the program... i think there is no way to pass that var among processes... for that i'm afraid i'll need IPC (inter process communication).

Am i wrong?

that is, in other words, i think that m_myApp is static, so it belongs to all instances of mySingleInstanceChecker one may create inside... the same Application! Which is kinda useless....

Please tell me that i'm wrong and where :)

Posted: Thu Oct 11, 2007 1:18 pm
by cavolaccimiei
in fact, i was right.
I had to do it through IPC, as mentioned in another post.
The real code is really really simple, so, if you are reading this, go ahead and use IPC straight away!

Posted: Fri Oct 03, 2008 7:16 pm
by jmason1182
Well it has been almost a year.... if you have it... could you share your IPC code? My needs are almost exactly what you are describing here.

Thanks