Sign in to follow this  
Followers 0
KaFu

Enforce Single Instance of Program via WM_COPYDATA

10 posts in this topic

#1 ·  Posted (edited)

For an example on how to send and receive data between different instances of the same script and which passes commandline parameters to the first instance via WM_COPYDATA take a look at post 2.

Just a short snippet which came to my mind as the _Singleton() standard UDF failed on my work-notebook for me (CreateMutexW returns winapi-error 126 - "The specified module could not be found" :evil:, I just assume it interferes with one of the 72 ;) processes running).

#cs ----------------------------------------------------------------------------

    AutoIt Version: 3.3.0.0
    Author:         KaFu

    Script Function:
    _EnforceSingleInstance() function, Standard _Singleton() UDF failed on some machines for me

#ce ----------------------------------------------------------------------------

_EnforceSingleInstance('e15ff08b-84ac-472a-89bf-5f92db683165') ; any 'unique' string; created with http://www.guidgen.com/Index.aspx

MsgBox(0, "", "Test")

Func _EnforceSingleInstance($GUID_Program)
    If $GUID_Program = "" Then Return SetError(1,'',1)
    if IsHWnd(WinGetHandle($GUID_Program)) then
        MsgBox(0,"Test","Second instance, will exit now...")
        Exit
    EndIf
    AutoItWinSetTitle($GUID_Program)
    Return WinGetHandle($GUID_Program)
EndFunc   ;==>_EnforceSingleInstance

Should work as long as the key is really 'unique' (as unique as it gets :evil: ), and script is not complied as CUI (I'm not sure but I assume then there is no default AutoItWin).

Edited by KaFu

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

And while playing around... here is a version which passes commandline parameters to first instance via WM_COPYDATA before exiting...

Compile and start multiple times with different commandline parameters to see whats happening...

#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$hwnd_AutoIt = _EnforceSingleInstance('e15ff08b-84ac-472a-89bf-5f92db683165') ; any 'unique' string; created with http://www.guidgen.com/Index.aspx
Opt("TrayIconHide", 1)

$hGUI = GUICreate("My GUI " & $hwnd_AutoIt,300,300,Default,Default) ; will create a dialog box that when displayed is centered
$label = GUICtrlCreateLabel($CmdLineRaw,10,10,300,100)
GUISetState(@SW_SHOW) ; will display an empty dialog box

ControlSetText($hwnd_AutoIt,'',ControlGetHandle($hwnd_AutoIt,'','Edit1'),$hGUI) ; to pass hWnd of main GUI to AutoIt default GUI
GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA")

While 1
    sleep(10)
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
GUIDelete()

Func _EnforceSingleInstance($GUID_Program = "")
    If $GUID_Program = "" Then Return
    $hwnd = WinGetHandle($GUID_Program)
    If IsHWnd($hwnd) Then
        $hwnd_Target = ControlGetText($hwnd,'',ControlGetHandle($hwnd,'','Edit1'))
        WM_COPYDATA_SendData(HWnd($hwnd_Target), $CmdLineRaw)
        Exit
    EndIf
    AutoItWinSetTitle($GUID_Program)
    Return WinGetHandle($GUID_Program)
EndFunc   ;==>_EnforceSingleInstance

Func WM_COPYDATA($hWnd, $MsgID, $wParam, $lParam)
    ; http://www.autoitscript.com/forum/index.php?showtopic=105861&view=findpost&p=747887
    ; Melba23, based on code from Yashied
    Local $tCOPYDATA = DllStructCreate("ulong_ptr;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    $msg = DllStructGetData($tMsg, 1)
    if $msg = " " then
        GUICtrlSetData($label, "")
    else
        GUICtrlSetData($label, DllStructGetData($tMsg, 1))
    endif
    Return 0
EndFunc   ;==>WM_COPYDATA

Func WM_COPYDATA_SendData($hWnd, $sData)
    If Not IsHWnd($hWnd) Then Return 0
    if $sData = "" then $sData = " "
    Local $tCOPYDATA, $tMsg
    $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    $tCOPYDATA = DllStructCreate("ulong_ptr;dword;ptr")
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    $Ret = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA))
    If (@error) Or ($Ret[0] = -1) Then Return 0
    Return 1
EndFunc   ;==>WM_COPYDATA_SendData
Edited by KaFu

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Why do you set a default parameter when in the next line you are enforcing the user not to enter a use the default parameter anyway?

Edited by Manadar

Share this post


Link to post
Share on other sites

Why do you set a default parameter when in the next line you are enforcing the user not to enter a use the default parameter anyway?

Lazyness, copy&paste... corrected...

Share this post


Link to post
Share on other sites

Hey, this is a pretty neat workaround. I didn't even know about the 'AutoItWinSetTitle' function! Go figure. I like the WM_COPYDATA use too - I had intended on writing something that would pass parameters to an already-running program in the future. Now i don't have to do the work :(

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Hey, this is a pretty neat workaround.

Thanks for the praise :), nice to hear, especially from you :(.

This is how I balance the access to the Sqlite DB between searching and reporting instance in SMF (two instances of smf.exe running at the same time to give instant access to results).

And btw, a 4 star rating for this post? Someone didn't seem understand what's going on here :) ...

Edited by KaFu

Share this post


Link to post
Share on other sites

I posted on the General Help and Support about getting your example of WM_COPYDATA to work in x64 and Yashied kindly replied with a solution, replace the following instances of "dword;dword;ptr" to "ulong_ptr;dword;ptr".

Here is the post.


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Very interesting! WM_COPYDATA implementation should be a part of standard includes and documented in a help file.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0