Single instance on a Smartphone (not true with .NET)

G

Guest

Hi everyone,

I'm currently designing a VB.NET application for a Smartphone. The
Smartphone itself will prevent you from starting multiple instances of the
same application. Which is true only if your application is fully loaded in
memory. By clicking on the application icon repeatedly multiple instances of
the application will be started and they will run until you close them.

I tried to use Named Mutex and FindWindow but nothing works. I can still
start multiple instances of the same VB.NET application. How can I prevent
multiple instances in a VB.NET application running on a Smarthpone?

One more question, is it normal that an empty application takes up to 3
seconds to start?
 
C

Chris Tacke, eMVP

The reason it loads is likely because you'e started teh second instance
before the runtime has checked in the first. You said a named mutex isn't
working? I don't see how that's possible since one instance is going to get
to create it first, and subsequent instances will only get the existing one.
Can you show your mutex code?

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate
 
G

Guest

Hi Chris,

I know it doesn't make any sense and to answer your question I'm using the
example everyone is talking about on this forum:

http://www.gotdotnet.com/userfiles/jonwells/OneInstance.zip

And the following code has been added to my application:

Private oOneInstance AS OneInstance = Nothing
...

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
oOneInstance = New OneInstance(Me)
End Sub

Thanks for your time Chris.

Sylvain Fortin
 
A

Alex Feinman [MVP]

The way .NET runtime maintains a single instance relies on the hidden window
of a class #NETCF_AGL_PARK with the title set to the application .exe path.
Until this window is instantiated, the next instance will launch as if the
app was not yet running. This should explain what you are seeing.

The larger your application becomes, the longer it takes to load it (simply
load into memory and JIT - I'm not talking about your .NET code), making
this window also larger. The only way around it I can think of is to use a
small and efficient launcher, which would check for your app to be already
running by enumerating the precesses
 
G

Guest

Hi Alex,

That's exactly what I thought, but if you read my first post, you'll see
that I'm asking if it's normal for an empty application (single form, no
menu, etc.) to take up to 3 seconds to load.

With that kind of load time on a .NET application startup, there's no way to
do anything about my multiple instance problem. But there's maybe a work
around. Can I build that small and efficient launcher application using
embedded Microsoft Visual C++ 4 and count the number of processes running in
this application?

Thanks for your time Alex.

Sylvain Fortin
 
A

Alex Feinman [MVP]

Sorry, missed the "empty" part. No, I don't think 3 sec for an enpty app is
reasonable. On the other hand on current smartphones (like C500) try
pressing Start and then 4, 8 (on my menu 4 is Settings, 8 is Calendar and 8
in Settings is Home Screen). YOu get Calendar. The whole thing is pretty
slow. I'm not even sure if making a C++ launcher will provide a definitive
answer
 
G

Guest

Even if it took 3 minutes or 3 hours for the app to load I still fail to
understand how if 2 apps compete for the same mutex, how they both can be
getting it. Something's not right.

-Chris
 
G

Guest

Hi everyone,

Sergey, I already tried the SPSingleInstance.zip example and I'm still able
to run multiple instances of my application. I agree with all of you guys
about “named mutexâ€, it's not the first time I'm using this technique to
insure I only have one instance of my application but this time it’s not
working and it doesn’t make any sense.

Alex, The device is a Motorola MPx220 and starting the calendar takes less
than 1 second. Most of the applications on the Smartphone have a load time of
less than 1 second.

Thanks for your time everyone, I really appreciate it.

Sylvain Fortin
 
G

Guest

Hi Chris,

CreateMutex() always return a different number which looked like a valid
handle... But I verified the return value of GetLastError() and it returns 6
(ERROR_INVALID_HANDLE) at every call. Any idea?

Thanks for you time.

Sylvain Fortin
 
C

Chris Tacke, eMVP

I've not looked at the pattenr object, but can you simply pull the
CreateMutex into your app's Main and run it there? Do the following
pseudocode:

if(CreateMutex("MutexName") == true)
{
if(GetLastError == ERROR_ALREADY_EXISTS)
MessageBox("Already Running");
else
MessageBox("First Instance");
}

Make sure your mutex handle's scope is such that it won't get destroyed
until your app closes, where you should call CloseHandle.

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate
 
G

Guest

Hi Chris,

I wanted to confirm that I'm doing the right thing in a standard windows
application. So I created an empty windows application and I added the
following to test the "named mutex" code:

....

Private Const ERROR_ALREADY_EXISTS As Integer = 183

<DllImport("Kernel32.dll")> _
Private Shared Function GetLastError() As Integer
End Function

<DllImport("Kernel32.dll", EntryPoint:="CreateMutexW")> _
Private Shared Function CreateMutex(ByVal lpMutexAttributes As IntPtr,
ByVal InitialOwner As Boolean, ByVal MutexName As String) As Integer
End Function

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Dim nResult As Integer

If CreateMutex(IntPtr.Zero, True, "TestMutex") <> 0 Then
nResult = GetLastError()
If (nResult = ERROR_ALREADY_EXISTS) Then
MessageBox.Show(String.Format("Already Running - {0}", nResult))
Else
MessageBox.Show(String.Format("First Instance - {0}", nResult))
End If
End If
End Sub

....


In the standard windows application, everything worked has expected. So I
did the same thing with an empty smartdevice application and I added exactly
the same code except for the DLLImport, changed Kernel32.dll to CoreDLL.dll
to make it work on the smartphone. Same result... It didn't work and
GetLastError() returned 6 (ERROR_INVALID_HANDLE) at every calls. Any idea
what I did wrong?

Thanks for your time Chris.

Regards,

Sylvain Fortin
 
C

Chris Tacke, eMVP

Don't call GetLastError, instead use System.Marshal.GetLastWin32Error() and
see if the result changes.

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate
 
G

Guest

Hi Chris,

I changed the code like you told me to do and used
Marshal.GetLastWin32Error() instead. Marshal.GetLastWin32Error() always
return 0 and the application still think that CreateMutex() was successful in
creating the mutex (First instance).

Thanks for your time.

Regards,

Sylvain Fortin
 
G

Guest

Hi Sergey,

I made the following changes after reading your post and it's working now:

<DllImport("CoreDLL.dll", EntryPoint:="CreateMutexW", SetLastError:=True)> _
Private Shared Function CreateMutex(ByVal lpMutexAttributes As IntPtr, ByVal
InitialOwner As Boolean, ByVal MutexName As String) As Integer
End Function

Thanks to everyone who participate to this thread, I really appreciate the
time you spent helping me, everything works now, thanks!

Regards,

Sylvain Fortin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top