Sign in to follow this  
Followers 0
Kyan

Registry context menu, pass multiple files issue

12 posts in this topic

#1 ·  Posted (edited)

Hi, this problem is driving me nuts.

Every time I select more than one file>Context Menu>Select my context entry, it opens one instance for each file selected

How do I pass all the select files as parameters?

This guy had the same problem (see the given example 2)

I think it is somehow related to this https://msdn.microsoft.com/en-us/library/windows/desktop/hh127436(v=vs.85).aspxbut I can't find a way to make it work

===========

My registry keys:

to add them:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\TESTING]
@="TESTING"

[HKEY_CLASSES_ROOT\*\shell\TESTING\command]
@="cmd /c echo %1 %*&pause"

to remove it:

Windows Registry Editor Version 5.00

[-HKEY_CLASSES_ROOT\*\shell\TESTING]

==

If you select multiple files, right click and click in "TESTING" you will see it opens one instance for each file :s

EDIT: I also tried this

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\TESTING]
@="TESTING"
"Position"="Top"
"MultiSelectModel"="Player"

[HKEY_CLASSES_ROOT\*\shell\TESTING\command]
@="cmd /c echo %L&pause"
Edited by Kyan

Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

Share this post


Link to post
Share on other sites



when you select multiple items this way it will always process each file at a time

the only way you can achieve doing this at one time is using a send-to item getting all the ~dp1 files as parameters

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

From the MSDN link you posted I get the impession that is for COM interaction.  For using command I believe the way it works is that the program handles single instance behavior.  In other words, the shell opens a copy of the exe for every file selected, but you don't see it because the exe sees it has a command line argument, knows it has an instance already open, so it passes the argument to the open instance, then closes without creating a visible window.  If it is an editor and you open a zillion files then you may see it flicker as it opens, sees it has an arg, passes it to the first instance, then closes.

I had a similar issue with a program I wrote that calculates MD5 Sums for files.  I used a message only window for instance control.  But I found out when I selected a bunch of files in Explorer that by the time the first instance created the window, explorer already launched about a dozen copies of my program.  That method was too slow.  Usually a named mutex is used to declare an instance of the program as the "first instance."  Other copies launched later cannot create the mutex since the first copy already did and owns it etc..

See Named Kernel Objects

In my case the way to fix my program would be to create a named mutex first, then create the message only window so secondary instances can pass the arguments using messages to the window.  Unfortunately I lost the source code anyway.  :(

Edited by MilesAhead

Share this post


Link to post
Share on other sites

I provided a solution like 2 years ago. Search WM_COPYDATA, my username and multiple files. You will need to tweak it probably.


_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

#5 ·  Posted (edited)

@Deye, I guess is the easiest solution ^ ^

@MilesAhead Is this https://msdn.microsoft.com/en-us/library/System.Threading.Mutex(v=vs.110).aspx? Can it be used using autoit or vbs? didn't see any COM call :

@guinness I was using autoit to make a subrotine that renamed all the selected file to a new name with the specified text, but since autoit is a bit slow I saw vbscript as a good solution, less that 1kb of code, that can be directly start by the OS, but found this obstacle. 

Dim args: Set args = WScript.Arguments
if args.Count = 0 then WScript.Quit
Dim fso:   Set fso = CreateObject("Scripting.FileSystemObject")
toReplace = InputBox("Insert the text to be removed from the selected files (case sensitive)","File name text remover")
If (toReplace = Empty) Then WScript.Quit
path = fso.GetParentFolderName(args.Item(0))
For each item in args
    FileName = fso.GetBaseName(item)
    NewName = Replace(FileName,toReplace,"")
    Extension = fso.GetExtensionName(item)
    MsgBox FileName & vbCrLf & NewName 'TESTING 
    'fso.MoveFile item,path & "\" & NewName & "." & Extension 
Next
WScript.Quit

Gonna try using your udf, looks complicated  :sweating:

EDIT: Guinness, it works, but scary code :D I wonder if it can be translated to vbs  :ermm:

EDIT2: Deye, is so easy that I don't want to code for this anymore xD,(worked at the first attempt) thanks

qA3eDZZ.png

Edited by Kyan

Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

https://msdn.microsoft.com/en-us/library/f55ddskf(v=vs.110).aspx

That looks fine.  What I did to guarantee a unique name for kernel objects was to use a Guid generator.  Then paste it as a constant.  That ensures only instances of your application are trying to create a mutex with that name.  Don't use a method that generates a guid because it will be different for every instance that starts up.  You need to paste in a literal Guid string.

Example:

Mutex m = new Mutex(true, "e2b3cbc2-f4a5-405e-8b8d-b0d62ae7fc08");

To use AutoIt3 instead of ,NET DllCall can be used to call the WinAPI to create the mutex

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682411%28v=vs.85%29.aspx

Edited by MilesAhead

Share this post


Link to post
Share on other sites

What's the link (to my code)? As I can't find it.


_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

@guinness, here it is '?do=embed' frameborder='0' data-embedContent>>(from your signature)

@MilesAhead, and how do you know that GUID is unique since you're hardcoding it? After you successful created a mutex how does the new created instance passes the execution arguments/parameters? (I'm not understanding how it handles other threads and passes the arguments to the main thread)


Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Okay, but that's not exactly what I was talking about. Anyway good luck, the code is out there, you just need to find it.

Edit: This >>

But it needs some re-tweaking.

Edited by guinness
1 person likes this

_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

#10 ·  Posted (edited)

@guinness, here it is '?do=embed' frameborder='0' data-embedContent>>(from your signature)

@MilesAhead, and how do you know that GUID is unique since you're hardcoding it? After you successful created a mutex how does the new created instance passes the execution arguments/parameters? (I'm not understanding how it handles other threads and passes the arguments to the main thread)

 

IIt depends if you believe Microsoft has perfected generating unique identifiers.  I never had a name collision using one.  The idea is to create a Guid using a guid generator and use it as the name for a kernel object for one application.

How to pass the command tail info.. there are many ways.  They call it Interprocess Communication or IPC.  On Windows you can use a file, a named memory mapped file, WM_COPYDATA, shared memory etc..

This article may be of interest:

http://www.codeproject.com/Articles/2263/Single-Instance-App-with-Command-Line-Parameters

There are similar schemes for other programming languages.  I liked to use a named memory mapped file(again using a Guid string as the name) backed by the page store.  I only made it 4 KB.  But for most practical purposes that was enough to store the command tail.  The application instances wrote to the shared memory and read from it.  Just search for "single instance command line" and yo'll find many techniques.

Edit: the memory mapped file is in memory globally accessible in the system once you get a handle to it.  That's why I call it "shared memory."

Edited by MilesAhead

Share this post


Link to post
Share on other sites

I saw yesterday an example of IPC, but is as complicated as WM_COPYDATA. Looks easy using VB  :sorcerer: 

Thank you :)


Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

Share this post


Link to post
Share on other sites

WM_COPYDATA is an IPC method.  Which one to use depends on many factors.  But there's nothing wrong with using WM_COPYDATA until you feel the need for something different.  :)

In my MD5 Sum utility the message only window has its own thread.  Even if the main thread is busy calculating the MD5 for a multiGB file the message only window thread can still process the WM_COPYDATA to get the command line of an additional file path to process and add it to the queue.  Programming languages that are not truly multi-thread capable you have to beware of deadlock conditions, especially.the UI failing to respond.  Even through the program is not hung the user thinks it is because he clicks stuff and nothing seems to happen etc..

Enjoy.  :)

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