Single-instance app revisited

  • Thread starter Thread starter Peter Morris
  • Start date Start date
P

Peter Morris

Some time ago I needed to write a single-instance app. That's an easy task
but I also needed duplicate instances to pass their command line parameters
to the first instance so that it can act upon them.

I ended up achieving this using Remoting to start my first app, and then
call into that Singleton remoted object from secondary instances. I thought
I was pretty clever until today when I tried to show an OpenFileDialog and
received an error telling me I have to use my app's main thread.

It's proving to be a real pain :-) Does anyone have a solution they have
tried?



Pete
 
Peter Morris said:
Some time ago I needed to write a single-instance app. That's an easy task
but I also needed duplicate instances to pass their command line parameters
to the first instance so that it can act upon them.

I ended up achieving this using Remoting to start my first app, and then
call into that Singleton remoted object from secondary instances. I thought
I was pretty clever until today when I tried to show an OpenFileDialog and
received an error telling me I have to use my app's main thread.

It's proving to be a real pain :-) Does anyone have a solution they have
tried?

Have you tried using the Microsoft.VisualBasic.ApplicationServices
classes?

Read http://msdn.microsoft.com/en-us/library/w3xx6ewx(VS.80).aspx and
see if it helps you. Personally I think it would be nice to have this
sort of functionality in System.*...
 
Yes. Unfortunately it threw a "NotImplemented" or "NotSupported" exception
(don't recall which) on a couple of machines at work, so I abandoned it.
 
Peter Morris said:
Yes. Unfortunately it threw a "NotImplemented" or "NotSupported" exception
(don't recall which) on a couple of machines at work, so I abandoned it.

I suspect it's worth digging into a bit further, as VB.NET uses it
pretty easily. It may be worth coming up with a quick VB.NET app then
decompiling it to see what it's doing.
 
Hi Pete

Using Invoke doesn't work either.....


Thanks for your time!


Pete



private void ButtonSelectSpeechAudioFileName_Click(object sender,
EventArgs e)
{
Invoke(new System.Threading.ThreadStart(
delegate()
{
OpenFileDialog ofd = GetOpenWavDialog(Composition.SpeechAudioFile);
if (ofd.ShowDialog() == DialogResult.OK)
Composition.SpeechAudioFile = ofd.FileName;
}));
}



System.Threading.ThreadStateException was unhandled by user code
Message="Current thread must be set to single thread apartment (STA) mode
before OLE calls can be made. Ensure that your Main function has
STAThreadAttribute marked on it. This exception is only raised if a debugger
is attached to the process."
Source="System.Windows.Forms"
StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller,
Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[]
args)
at System.Windows.Forms.Control.Invoke(Delegate method)
at
AlterEgo.WizardStepControls.AudioAndScriptStepControl.ButtonSelectSpeechAudioFileName_Click(Object
sender, EventArgs e) in
C:\Data\CustomerProjects\Inteevo\Projects\AlterEgo\AlterEgo\WizardStepControls\AudioAndScriptStepControl.cs:line
77
at System.Windows.Forms.Control.OnClick(EventArgs e)
at DevExpress.XtraEditors.BaseButton.OnClick(EventArgs e)
at DevExpress.XtraEditors.BaseButton.OnMouseUp(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at DevExpress.Utils.Controls.ControlBase.WndProc(Message& m)
at
System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&
m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,
Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&
msg)
at
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)
at
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32
reason, ApplicationContext context)
at
System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,
ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Inteevo.SingleInstanceApp.SingleInstance.Execute(String[] args) in
C:\Data\CustomerProjects\Inteevo\Libraries\Inteevo.SingleInstanceApp\SingleInstance.cs:line
26
at
System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr
md, Object[] args, Object server, Int32 methodPtr, Boolean
fExecuteInContext, Object[]& outArgs)
at
System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(RuntimeMethodHandle
md, Object[] args, Object server, Int32 methodPtr, Boolean
fExecuteInContext, Object[]& outArgs)
at
System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage
msg, Int32 methodPtr, Boolean fExecuteInContext)
InnerException:
 
I did decompile it in the past, pretty deep stuff with use of lots of
classes/methods marked "internal".
 
Back
Top