Lupo73 Posted June 28, 2010 Posted June 28, 2010 In one of my apps (DropIt, available on SourceForge) I have added a system context menu integration to send files to the software by right-click on them and selecting "Send to DropIt". The feature works fine with one file, but if I select several files and than right-click and try to send them to DropIt, the software starts one time per file and system crash if too many files are sent. There is a way to fix it and allow to send many files at once? Thanks! SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders.
KaFu Posted June 28, 2010 Posted June 28, 2010 Take a look at my example about passing commandline parameters to first instance via WM_COPYDATA before exiting. Only allow one instance of you program at a time and add the files via the wm_copydata message to a working-queue. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2025-May-18) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
Lupo73 Posted June 30, 2010 Author Posted June 30, 2010 Thanks for the report.. I'll check this solution soon.. SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders.
Lupo73 Posted July 2, 2010 Author Posted July 2, 2010 (edited) It could be the solution, but is a little obscure for me.. how can I implement it in a script that receive parameters normally from $CmdLine? I have attached my software code to show you how it is designed, not to have the solution (this is the hard/good aspect of programming), but to have some tips to proceed. thanks!DropIt.au3 Edited July 2, 2010 by Lupo73 SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders.
KaFu Posted July 2, 2010 Posted July 2, 2010 I'll take a look tomorrow or Sunday (code sample looks complex, needs a little more time), too late tonight . OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2025-May-18) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
KaFu Posted July 3, 2010 Posted July 3, 2010 (edited) So, what behavior do you expect? I think two scenarios can occur. DropIt is not running and is started by the "Send to DropIt" command, or DropIt is already running and the "Send to DropIt" command needs to be routed to the running instance. Are both scenarios valid? Edit: So where's the regwrite part for the "Send to DropIt" command? Need that one to test too Edited July 3, 2010 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2025-May-18) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
Lupo73 Posted July 5, 2010 Author Posted July 5, 2010 The software is designed to work fine as portable program. So the registration in Context menu and in SendTo menu are made in the installer version only, during installation (so from the installer itself, not by the software). I could consider to add them also as options (as I made in my other app ArcThemALL!), if you think it is needed. The problem is that users reported me that the program starts N times, if I try to send N files to it through context menu (I don't know if the problem occurs also using sendto, but I think so). So I'd like to fix it in both my apps. SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders.
KaFu Posted July 5, 2010 Posted July 5, 2010 (edited) First of all, multiple selection of files sended via contextmenu to commandline should result in a $CmdLineRaw something like shown below.MsgBox(0,"",$CmdLineRaw) ClipPut($CmdLineRaw) ; "C:\Program Files\WinRAR\Zip.SFX" "C:\Program Files\WinRAR\Zip64.SFX" "C:\Program Files\WinRAR\zipnew.dat"You're reading the commandline input with this$temp = $CmdLine[0]thus only capturing the very first element. You should relocate the working code using the commandline parameters to a function (line ~1073 - 1104, e.g. _func_CmdLine). Stringsplit the $CmdLineRaw into an $aProfilLocation array to process in a loop for multiple selections.Insert a call to the _EnforceSingleInstance() function exactly where the _func_CmdLine() was located before.Take a look at my example in post #2 above.In the _EnforceSingleInstance() the part "If IsHWnd($hwnd) Then" checks, whether there is already an instance running. You have to add a wm_copydata message queue and rename the default autoit gui with a unique UUID (use mentioned page to generate one). In the function WM_COPYDATA() add a second call to _func_CmdLine($msg). These are the parts you'll need to add to you script:expandcollapse popupGlobal $sCmdLineRaw Func _Main() ;..... ImTarget() GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES_UNICODE_FUNC") GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND") $prof = Refresh($sIniPr, $profiles) $hwnd_AutoIt = _EnforceSingleInstance('261f3b38-e935-4229-9afc-01933cc7392b') ; any 'unique' string; created with http://www.guidgen.com/Index.aspx ControlSetText($hwnd_AutoIt, '', ControlGetHandle($hwnd_AutoIt, '', 'Edit1'), $hGUI) ; to pass hWnd of main GUI to AutoIt default GUI, this is you main guis hwnd GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA") While 1 ; Your main working loop If $sCmdLineRaw Then ; received via WM_COPYDATA $sCmdLineRaw = "" _func_CmdLine($sCmdLineRaw) EndIf WEnd ;..... ;..... EndFunc ;==>_Main Func _EnforceSingleInstance($GUID_Program = "") If $GUID_Program = "" Then Return $hwnd = WinGetHandle($GUID_Program) If IsHWnd($hwnd) Then ; second instance exists, forward data and exit $hwnd_Target = ControlGetText($hwnd, '', ControlGetHandle($hwnd, '', 'Edit1')) ; grab target hWnd from default AutoIt GUI Edit control WM_COPYDATA_SendData(HWnd($hwnd_Target), $CmdLineRaw) Exit EndIf _func_CmdLine($CmdLineRaw) ; this is first instance, process commandline immediatly 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("dword;dword;ptr", $lParam) Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3)) $msg = DllStructGetData($tMsg, 1) $sCmdLineRaw = $msg ; assign received data to global variable to process in the main loop 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("dword;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 Func _func_CmdLine($sCmdLineRaw) $aProfilLocation = StringSplit($sCmdLineRaw.... ;.... ; Add loop to process multiple inputs EndFunc ;==>_func_CmdLineThe first call to _func_CmdLine($CmdLineRaw) processes the input if you're program is closed and the first instance is called. If there is already an instance of your program running, the $CmdLineRaw parameter is transfered to that instance via wm_copydata and the new instance exits. The first instance receives the $CmdLineRaw via wm_copydata an processed it via _func_CmdLine($msg)...Ahhhh, too easy, isn't it ...Edit: While I think about it, better assign the received data to a global variable in WM_COPYDATA and return from function as fast as possible. Process the received results in the main loop. Adjusted the code above a little. Best to place the _EnforceSingleInstance() call directly after your call to Refresh(), as $hGUI is already defined then. Edited July 6, 2010 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2025-May-18) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
Lupo73 Posted July 6, 2010 Author Posted July 6, 2010 I'm testing it... You can see that in my code is already present a "Checking of multiple instances" that, if the option is enabled, close the new instance if another one is open. So I may need to modify it to work with your code too. To do a test I have firstly added a MsgBox to write the $CmdLineRaw received by the software and if I select N files and send them to DropIt with context menu: - if my multiple instances blocker is enabled, only one instance is started and only one file is in $CmdLineRaw parameter - if it is disabled, N instances are started and only one file per instance is in $CmdLineRaw parameter So in both cases the $CmdLineRaw not contains N parameters, but only one parameter each instance started and I need to start a first instance and send other parameters to it. I can't understand if it is what your code does. Note also that lines 1073-1104 are used to detect if the first parameter is a command to start the software with a specified profile and I need to keep this feature in the eventual recoding. Thanks! SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders.
KaFu Posted July 6, 2010 Posted July 6, 2010 (edited) Lets see ... - So in both cases the $CmdLineRaw not contains N parameters - if the first parameter is a command to Okay, thought it was like I posted above with N parameters (has something to do with which switches you used to created the contextmenu I guess). Additionally it's a "command" / unqualified filename by default, not a full filename (as I assumed ). What does the contextmenu return? A full filename I guess. First I would two Global arrays, containing possible profile filenames to process (org and buffer). Because the Commandline switch (no full filename+path) and Contextmenu (full filename+path) switch's are different, you'll have to deal with how to add them to the array additionally. First thing to do, maybe check with something like FileExists() and if not, try if your own profile pattern matches, then add to processing array. Best to create a separate function to deal with the addition to the processing array. In the_EnforceSingleInstance() function, the first instance should add directly to the processing array, all subsequent pass the data via wm_copydata to the first instance and exit. The first instance appends the received data to the processing buffer array (to prevent interfering with the processing itself). Relocate your processing function to the main loop. Loop through it, as long as 1 element exits in the array (maybe [0] should be a counter of elements). If an element has been processed, delete it from the array. Last thing to add to the main loop is a check if the buffer array contains an element, and if so copy it to processing array and delete it from buffer. This will start the processing function again. Edit: Rewrote it a little, sry ... Edited July 6, 2010 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2025-May-18) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
Lupo73 Posted July 7, 2010 Author Posted July 7, 2010 Sorry, but it is very complex for me.. The array that contains profile names is $profiles. Note also that from context menu are automatically sent parameters as full filename+path, but also with commandline the software can receive: full filename+path, filename+relative path, profile name (as "-profilename" as first parameter). I can't create the mechanism you have in mind, but it seems well structured.. can you write me an example of it? thanks! I know this forum is for this kind of requests, but here there are programmers like me that like to collaborate to their works.. so I try: I'd like to improve also other aspects of DropIt (for example adding support to PNG target images), but I'm not a so advanced programmer and I'm looking for someone interested in this project.. it is on SourceForge and fully open source.. now it's good, but could became better.. if it could interest you.. SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now