How to CreateMutex in Dolphin?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

How to CreateMutex in Dolphin?

talios@gmail.com
I've just hit a situation where I'd like to trap my installer from installing/uninstalling in the system if/when theres a named mutex running from my application.

Quoting from the InnoSetup documentation:

This directive is used to prevent the user from installing new versions of an application while the application is still running, and to prevent the user from uninstalling a running application. It specifies the names of one or more named mutexes (multiple mutexes are separated by commas), which Setup and Uninstall will check for at startup. If any exist, Setup/Uninstall will display the message: "[Setup or Uninstall] has detected that [AppName] is currently running. Please close all instances of it now, then click OK to continue, or Cancel to exit."

Use of this directive requires that you add code to your application which creates a mutex with the name you specify in this directive. Examples of creating a mutex in Delphi, C, and Visual Basic are shown below. The code should be executed during your application's startup.
Delphi:

CreateMutex(nil, False, 'MyProgramsMutexName');

C:

CreateMutex(NULL, FALSE, "MyProgramsMutexName");

Visual Basic (submitted by Peter Young):

'Place in Declarations section:
Private Declare Function CreateMutex Lib "kernel32" _
        Alias "CreateMutexA" _
       (ByVal lpMutexAttributes As Long, _
        ByVal bInitialOwner As Long, _
        ByVal lpName As String) As Long

'Place in startup code (Form_Load or Sub Main):
CreateMutex 0&, 0&, "MyProgramsMutexName"

It is not necessary to explicitly destroy the mutex object upon your application's termination; the system will do this automatically. Nor is it recommended that you do so, because ideally the mutex object should exist until the process completely terminates.
Note that mutex name comparison in Windows is case sensitive.
See the topic for CreateMutex in the MS SDK help for more information on mutexes.
However, I can't seem to find anything that matches/implements CreateMutex in Dolphin anywhere, the Mutex class doesn't quite seem to be what I'm after, and there doesn't seem to be anything in KernelLibrary, the closest thing I could find sounding like what I want being:

  KernelLibrary
    createEvent: aSECURITYATTRIBUTES bManualReset: aBoolManual
      bInitialState: aBoolState lpName: aStringPathName

Do I maybe have to import/declare this Win32 API function myself or?

Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

Sean Malloy-6
Mark,

> Do I maybe have to import/declare this Win32 API function myself or?

Yep.

Biggest help I have found, is having a copy of the Win32 ref (a .hlp file).
Makes for importing api calls much easier.

Define the required loose methods, and maybe even create a class called
NamedMutex or something...

Heres the Kernel call..

KernelLibrary>>createMutex: aSECURITYATTRIBUTES bInitialOwner: aBoolOwner
lpName: aStringName
"Answer a new Win32 Handle"
"HANDLE CreateMutex(

    LPSECURITY_ATTRIBUTES lpMutexAttributes, // pointer to security
attributes
    BOOL bInitialOwner, // flag for initial ownership
    LPCTSTR lpName  // pointer to mutex-object name
   );

"
<stdcall: handle CreateMutex lpvoid bool lpstr>
^self invalidCall

make sure you implement ReleaseMutex as well

KernelLibrary>>releaseMutex: aHandle
"Cleans up an existing mutex"
"BOOL ReleaseMutex(
    HANDLE hMutex // handle of mutex object
   );
"
<stdcall: bool ReleaseMutex handle>
^self invalidCall

I've uploaded the win32 api ref here if you don't already have it:

http://www.arcturus.com.au/win32.zip


Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

Blair McGlashan-3
"Sean Malloy" <[hidden email]> wrote in message
news:4151154a$[hidden email]...

> Mark,
>
>> Do I maybe have to import/declare this Win32 API function myself or?
>
> Yep.
>
> Biggest help I have found, is having a copy of the Win32 ref (a .hlp
> file).
> Makes for importing api calls much easier.
> ...

We use our own modified version of the Bruce McKinney´s "Hardcore Visual
Basic" Type Library Win32 API type library, and this allows one to generate
functions and structs automagically that typically require little, if any,
modification. This has a number of advantages; it typically saves time, it
is less tedious and error prone, the results are consistent and
reproduceable. You can download it from:

http://object-arts.com/Lib/Downloads/Misc/win32.zip

Its not complete, and because it was designed for VB5/6 (which do not
support unsigned integers) it may have some translations in it of the Win32
SDK header files that are not strictly correct. Our rebuilt version defines
a preprocessor flag that builds a sign aware version of the type-library and
contains some other modifications and extensions, but I can't guarantee it
will be correct in all cases so you should check the generated result
against the documentation on MSDN. Anyway if you want to extend it I have
also made available the IDL source and a VC6 project for building it. For
those that don't have VC6 it would be possible to build it using the MIDL
compiler in the freely downloadable Microsoft SDK.

http://object-arts.com/Lib/Downloads/Misc/win32lib.zip

In the type-library the Win32 API functions are grouped into "modules" that
correspond to the different Win32 DLLs in which their implementations
reside. These map onto different ExternalLibrary subclasses in Dolphin, e.g.
KernelLibrary for Kernel32.dll. The Active-X Component Wizard allows you to
generate a complete module definition, but normally this is more than one
wants so it is best to use a bit of script, e.g.

tlb := AXTypeLibraryAnalyzer open: 'win32.tlb'.
tlb prefix: ''.
module := (tlb at: 'Kernel').
funcs := LookupTable new addAll: (module functions collect: [:each | each
name -> each]); yourself.
#('CreateMutex' 'ReleaseMutex') do: [:each | module generateMethodWrappers:
(funcs at: each)].

I've pasted below the code that was generated from this, which as you will
see is virtually identical to that you've hand-written, with the exception
of the boolean parameter to CreateMutex (better your way).

Hope this is useful for the future,

Blair
-------------------------
!KernelLibrary methodsFor!

createMutex: lpMutexAttributes bInitialOwner: bInitialOwner lpName: lpName
 "Invoke the CreateMutex() function of the module wrapped by the receiver.
 Helpstring: Creates a named or unnamed mutex object

  HANDLE __stdcall CreateMutex(
   [in]void* lpMutexAttributes,
   long bInitialOwner,
   LPSTR lpName);"

 <stdcall: handle CreateMutexA  void* sdword lpstr>
 ^self invalidCall!

releaseMutex: hMutex
 "Invoke the ReleaseMutex() function of the module wrapped by the receiver.
 Helpstring: Releases the Mutex once

  long __stdcall ReleaseMutex(
   HANDLE hMutex);"

 <stdcall: sdword ReleaseMutex  handle>
 ^self invalidCall! !
!KernelLibrary categoriesFor: #createMutex:bInitialOwner:lpName:!**auto
generated**!public! !
!KernelLibrary categoriesFor: #releaseMutex:!**auto generated**!public! !



> Define the required loose methods, and maybe even create a class called
> NamedMutex or something...
>
> Heres the Kernel call..
>
> KernelLibrary>>createMutex: aSECURITYATTRIBUTES bInitialOwner: aBoolOwner
> lpName: aStringName
> "Answer a new Win32 Handle"
> "HANDLE CreateMutex(
>
>    LPSECURITY_ATTRIBUTES lpMutexAttributes, // pointer to security
> attributes
>    BOOL bInitialOwner, // flag for initial ownership
>    LPCTSTR lpName  // pointer to mutex-object name
>   );
>
> "
> <stdcall: handle CreateMutex lpvoid bool lpstr>
> ^self invalidCall
>
> make sure you implement ReleaseMutex as well
>
> KernelLibrary>>releaseMutex: aHandle
> "Cleans up an existing mutex"
> "BOOL ReleaseMutex(
>    HANDLE hMutex // handle of mutex object
>   );
> "
> <stdcall: bool ReleaseMutex handle>
> ^self invalidCall
>
> I've uploaded the win32 api ref here if you don't already have it:
>
> http://www.arcturus.com.au/win32.zip
>
>


Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

Sean Malloy-5
> We use our own modified version of the Bruce McKinney´s "Hardcore Visual
> Basic" Type Library Win32 API type library, and this allows one to
> generate functions and structs automagically that typically require
> little, if any, modification. This has a number of advantages; it
> typically saves time, it is less tedious and error prone, the results are
> consistent and reproduceable. You can download it from:


Thanks Blair, this will definitely save me time. I've lost some follicles
over Dolphin <> Win32 api calls in the last couple of months :)


Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

Don Rylander-3
In reply to this post by talios@gmail.com
Mark,

>"Mark Derricutt" <[hidden email]> wrote in message
news:cir1l3$[hidden email]...
>I've just hit a situation where I'd like to trap my installer from
installing/uninstalling in the system if/when >theres a named mutex running
from my application.
>[...]

If, on the other hand, you just want to make sure Outlook's not running
(assuming you're installing your Outlook add-in), you can just add:

     AppMutex=_outlook_mutex_

to the [Setup] section.

Don


Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

talios@gmail.com
Don Rylander wrote:

>     AppMutex=_outlook_mutex_
>  
>
I'd kiss and hug you Don, but that didn't seem to work :(  At least not
with Outlook 2002 SP3...

Will look at the code pasted by Sean and Blair and see if I can get that
working.


Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

talios@gmail.com
In reply to this post by Blair McGlashan-3
Blair McGlashan wrote:

>-------------------------
>!KernelLibrary methodsFor!
>
>createMutex: lpMutexAttributes bInitialOwner: bInitialOwner lpName: lpName
> "Invoke the CreateMutex() function of the module wrapped by the receiver.
> Helpstring: Creates a named or unnamed mutex object
>  
>
Hmmm, both Sean and Blair's hit me back with:

11:07:49 AM, Thursday, September 23, 2004: 'The specified procedure
could not be found. (16r7F: The specified procedure could not be found.)'
KernelLibrary(ExternalLibrary)>>invalidCall
KernelLibrary>>createMutex:bInitialOwner:lpName:
UndefinedObject>>{unbound}doIt
CompiledExpression>>value:
SmalltalkWorkspace>>evaluateRange:ifFail:debug:
SmalltalkWorkspace>>evaluateItIfFail:debug:
SmalltalkWorkspace>>evaluateItIfFail:
SmalltalkWorkspace>>inspectIt
Symbol>>forwardTo:
CommandDescription>>performAgainst:
[] in Command>>value
BlockClosure>>ifCurtailed:
BlockClosure>>ensure:
Command>>value
ShellView>>performCommand:
SmalltalkWorkspaceDocument(Shell)>>performCommand:
CommandQuery>>perform
DelegatingCommandPolicy(CommandPolicy)>>route:
[] in ShellView(View)>>onCommand:
BlockClosure>>ifCurtailed:
BlockClosure>>ensure:
Cursor>>showWhile:
ShellView(View)>>onCommand:
ShellView(View)>>wmCommand:wParam:lParam:
ShellView(View)>>dispatchMessage:wParam:lParam:
[] in InputState>>wndProc:message:wParam:lParam:cookie:
BlockClosure>>ifCurtailed:
ProcessorScheduler>>callback:evaluate:
InputState>>wndProc:message:wParam:lParam:cookie:
ShellView>>translateAccelerator:
ShellView>>preTranslateKeyboardInput:
ShellView(View)>>preTranslateMessage:
InputState>>preTranslateMessage:
InputState>>pumpMessage:
InputState>>loopWhile:
InputState>>mainLoop
[] in InputState>>forkMain
ExceptionHandler(ExceptionHandlerAbstract)>>markAndTry
[] in ExceptionHandler(ExceptionHandlerAbstract)>>try:
BlockClosure>>ifCurtailed:
BlockClosure>>ensure:
ExceptionHandler(ExceptionHandlerAbstract)>>try:
BlockClosure>>on:do:
[] in BlockClosure>>newProcess


Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

Sean Malloy-6
> Hmmm, both Sean and Blair's hit me back with:

Try changing the call from

<stdcall: handle CreateMutex ...>

to

<stdcall: handle CreateMutexA ...>

?


Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

Blair McGlashan-3
In reply to this post by talios@gmail.com
"Mark Derricutt" <[hidden email]> wrote in message
news:cit0mk$[hidden email]...

> Blair McGlashan wrote:
>
>>-------------------------
>>!KernelLibrary methodsFor!
>>
>>createMutex: lpMutexAttributes bInitialOwner: bInitialOwner lpName: lpName
>> "Invoke the CreateMutex() function of the module wrapped by the receiver.
>> Helpstring: Creates a named or unnamed mutex object
>>
> Hmmm, both Sean and Blair's hit me back with:
>
> 11:07:49 AM, Thursday, September 23, 2004: 'The specified procedure could
> not be found. (16r7F: The specified procedure could not be found.)'
> KernelLibrary(ExternalLibrary)>>invalidCall
> KernelLibrary>>createMutex:bInitialOwner:lpName:

The autogenerated method works for me?

On the whole you should find that methods autogenerated from the Win32
type-library will not have that sort of error because they are directly from
the SDK header files. They may have minor issues with the parameter types,
however, as in this case the second BOOL parameter is interpreted as a long
integer. This is strictly correct since the Win32 BOOL type is just an
integer, but it is more usefully defined as a 'bool' in Dolphin (as Sean has
done) to get automatic marshalling of Smalltalk Booleans.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: How to CreateMutex in Dolphin?

Blair McGlashan-3
In reply to this post by Sean Malloy-5
"Sean Malloy" <[hidden email]> wrote in message
news:[hidden email]...

>> We use our own modified version of the Bruce McKinney´s "Hardcore Visual
>> Basic" Type Library Win32 API type library, and this allows one to
>> generate functions and structs automagically that typically require
>> little, if any, modification. This has a number of advantages; it
>> typically saves time, it is less tedious and error prone, the results are
>> consistent and reproduceable. You can download it from:
>
>
> Thanks Blair, this will definitely save me time. I've lost some follicles
> over Dolphin <> Win32 api calls in the last couple of months :)

No problem. Let me know of any issues you find with it, as I will endeavour
to keep it up to date. I recommend redownloading next time you need to use
it to get the latest version. Maybe I should start a SourceForge project for
it though, as I won't be adding any large missing sections of the Win32 API
unless I have a need for it. The only thing is I'm not sure whether I'm
really permitted to distribute the source in amended form (or at all for
that matter). Better check the license.

Regards

Blair