Post by Frank HeindörferHallo Matthias,
Post by Matthias KrachWie komme ich an diese Information ?
Verwende doch in der Deiner Anwendung einen globalen Mutex.
Damit sollte es klappen.
(Hinweis: Auch WinXP ist ein Terminalserver - ein sogenannter
Single-TS. Das Umschalten zwischen den einzelnen Sitzung wird
"Fast-User-Switching" genannt.)
http://windowsxp.devx.com/articles/fus/default.asp
http://support.microsoft.com/default.aspx?scid=kb;de;310153#Task4
Tschüs Frank
Hallo Frank,
vielen Dnak für Deine Hilfe.
Nach Studium der beiden Links habe ich nach Mutex und VB6 gegoogelt und
den
nachfolgenden Code gefunden und in meine Anwendung eingebaut, leider
ohne Erfolg.
Der Code lautet:(Hoffentlich ist er auch nach dem Senden noch lesbar -
Zeilenumbruch-)
'***********************************************************************
*******
'******This code is downloaded from this page:
'****** <http://www.Planet-Source-Code.com/vb/default.asp?lngCId=56211
&lngWId=1>
'****** Author: Isbat Sakib
'****** Email: ***@hotmail.com <mailto:***@hotmail.com>
'Just start your app from the Sub Main. And at the end of your app, call
MutexCleanUp Sub.
'Now what is a mutex? A mutex object is a synchronization object whose
state is set to
'signaled when it is not owned by any thread, and nonsignaled when it is
owned. Only one
'thread at a time can own a mutex object, whose name comes from the fact
that it is
'useful in coordinating mutually exclusive access to a shared resource.
Now, how this
'method of avoiding multiple instances works is explained in the
comments below. Enjoy.
'The API functions and constantfor mutex manipulation
Private Declare Function CreateMutex Lib "kernel32" Alias
"CreateMutexA" (ByVal
lpMutexAttributes As Long, ByVal bInitialOwner As Long, ByVal lpName As
String) As Long
Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As
Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal
hHandle As Long, ByVal
dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As
Long) As Long
Private Const WAIT_OBJECT_0 As Long = &H0
'These APIs are only used for showing the previous instance of the app.
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA"
(ByVal
lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long,
ByVal
nCmdShow As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As
Long) As Long
Private Const SW_RESTORE = 9
'This string should be as unique as possible but GENERALLY not more than
254 characters
'actually not more than the value of MAX_PATH constant as documented in
MSDN.
Private Const UniqueString As String =
"StringForAvoidingMultipleInstance"
'This variable will have the handle of the mutex
Private GMutex As Long
Sub Main()
'Dim OldHWnd As Long
If CheckAndCreateMutex Then 'No previous instance, so load the main
form.
MDI_THS_SicherungsTool.Show '<- meine eigentliche Anwendung
Else
'A previous instance exists. Find that window as
'the caption is known.
'OldHWnd = FindWindow(vbNullString, "THS-Sicherungstool") <- von mir
auskommentiert
'If OldHWnd <> 0 Then 'If the window is found,then show it and set focus
'to it whether it is minimized or not.
^----------------- von mir auskommentiert
'Call ShowWindow(OldHWnd, SW_RESTORE) <- von mir auskommentiert
'Call SetForegroundWindow(OldHWnd) <- von mir auskommentiert
'End If
End If
End Sub
Public Function CheckAndCreateMutex() As Boolean
GMutex = CreateMutex(0&, 1&, UniqueString) 'First, lets create the mutex
MsgBox "Mutex ist: " & GMutex & vbNewLine & UniqueString, vbOKOnly,
"Test"<-von mir
zwecks Test eingefügt
If GMutex = 0 Then 'Error occurred for some reason.
MsgBox "The mechanism to ensure only one instance of this app has failed
for unknown
reasons.", vbCritical, "Error"
CheckAndCreateMutex = True
Else
'Now this requires some explanation. The mutex has been created, but
does not
'belong to this specific application thread. This could be done by
setting the
'second parameter of CreateMutex function to 1, but I don't know why it
doesn't
'work in VB, though the same thing works perfectly in C++. So, another
work-around
'is here. The next function will only check if the mutex is signaled or
not as the
'second parameter is given zero. The mutex will be non-signaled if a
thread owns
'it already. Now calling once this function makes the calling thread the
owner of
'the mutex if it doesn't have an owner already.
If WaitForSingleObject(GMutex, 0&) = WAIT_OBJECT_0 Then 'The mutex is
signaled and
'no other thread owns it.
'But from now on, this thread
'will own the mutex.
CheckAndCreateMutex = True
MsgBox "Mutex wurde zugeordnet", vbOKOnly, "Test" <-von mir zwecks Test
eingefügt
Else 'Several other things might have happened.
'The mutex is may be non-signal, or it already
'has an owner, or the time-out for the
'function return is finished.
MsgBox "THS-Sicherungstool läuft bereits." & vbNewLine & "Mehrfacher
Aufruf ist nicht
zulässig.", vbInformation, "THS-Sicherungstool"
Call CloseHandle(GMutex) 'The already owned mutex has been opened
'by this thread. Well, now close the handle
'of it.
CheckAndCreateMutex = False
End If
End If
End Function
Public Sub MutexCleanUp()
Call ReleaseMutex(GMutex) 'A thread should release the mutex when no
longer
'needed.
End Sub
Zum Testen haben ich einen Server2003, ein Winxp Prof und ein W2k.
wenn ich nun am Server das PGM zwei mal aufrufen will, bekomme ich die
Meldung, daß das PGM bereits läuft -ist ok. Wenn ich das PGM aber einmal
am Server (Console) und einmal vom XP-Client oder W2k-Client in einer
Session des RDP-Clients (MSTSC.EXE) aufrufe, wird das PGM anstandslos
ein zweites Mal aufgerufen. Warum?
Die zugeardnete Kennung (GMutex) ist jeweils gleich, also sollte er doch
finden, daß die Anwendung bereits läuft.
Der Terminalserverdienst läuft im Administratonsmodus, beie Anmeldungen
laufen unter Administrator. Könnte das das Problem sein?
Es wäre schön, wenn Du mir da weiter helfen könntest. Vielen Dank.
--
MfG
Matthias Krach
aus Plettenberg