Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept MS Windows 'SendTo' menu calls?

SCENARIO

I manage and organize many files during the day, the SendTo is the most used feature that I use on Windows.

PROBLEM

By default, when the user clicks an item/link of the contextmenu to send the files, the O.S does not show any kind of advise/notifier indicating that the files are copying to the selected destination.

I consider it a very wrong design issue because for big files its OK ...a progressbar will be shown, but if the files are to small it will not show any progressbar/visual indicator so is not possible to ensure that the files are copied (without manual effort) because I'm human and I could click outside the SendTo contextmenu by error.

So, I would like to develop a personal mini-tool that will help me to optimize my time showing me a notifier window wherever on the screen when I send/copy files using the SendTo feature from the contextmenu, and only the SendTo feature.

QUESTION

In just simple words, I want to detect a copy/send operation from SendTo menu to ensure that the click was done properly on the menu item (and not outside the menu), by also providing additional basic info such as the source folder, the destination folder, and the amount of files or the filepaths.

Any ideas to start developing this tool in the right direction?.

I will be grateful for a code example in C# or else VB.Net, preferably this last.

APPROACH

Since I don't know how to start doing this I mean which could be the easiest or the efficient way to intercept those SendTo calls, firstly I thought to hook the CopyFile or CopyFileEx API functions, but they do not provide the information that I need because that function will be called in any kind of copy operation and not only when I use the SendTo Feature, so I'm lost.

I'm not sure if I should investigate more about internal calls, or maybe investigate more about the windows contextmenu itself instead of messing with function hooks and ugly things that I could avoid.

My main idea is to develop a hidden WinForms (or else a windows service) that stays in background waiting for when I use the SendTo feature (when I click on an item of the SendTo menu) and then show any kind of visual indicator on the screen to ensure that I properly clicked that menu-item and maybe inform about the amount of files that I'm moving and where I'm moving them.

RESEARCH

Here is a code example that I think it demostrates how to instantiate the SendTo com object to create your own?, but its written in c++ and I'm not sure if the example is helpful because my intention is not to replace the SendTo menu but I'll keep this useful info here it it serves for something else:

How to add(enable) standard "Send To" context menu option in a namespace extension

The KNOWNFOLDERID constants docs gives some useful info about the SendTo folder, again I'm not sure if this could help maybe for a read/access monitoring approach?, I just keep the info here:

GUID: {8983036C-27C0-404B-8F08-102D10DCFD74}

Default Path: %APPDATA%\Microsoft\Windows\SendTo

Legacy Default Path: %USERPROFILE%\SendTo

In the Shell Extension Handlers docs there is a Copy hook handler which I don't know if it has relation with the SendTo's COM component and if that could help me in some way, the same ignorance for IContextMenu::InvokeCommand method reference which maybe I could intercept it to identify a SendTo invocation?

By the moment I feel like flying blind.

I recently found this A managed "Send To" menu class but again its a example written in C/C++ (I think is the same source before) which I don't understand at all and again I'm not sure if that could help me because I repeat that replacing SendTo is not what I have in mind (just because I don't know how to properly do it avoiding all possible risks, I prefer to still let Windows logic copy/send the files, I just want to detect the copy operation to retrieve info)

EXPECTED RESULTS AND USAGE

Step 1:

Select a random file and use the SendTo menu (in my language, Spanish, the command name is 'Enviar a')

enter image description here

Step 2:

Let the .net application's logic (working in background) intercept the SendTo operation to retrieve info.

(I only need help with this step)

Step 3:

Display the info somewhere over the screen to ensure that the SendTo operation was performed, to ensure that I properly clicked the SendTo item (My Link).

enter image description here

(That popup is just a simulation, I don't know any way to retrieve all that info)

like image 291
ElektroStudios Avatar asked Apr 09 '15 18:04

ElektroStudios


People also ask

What is SendTo folder?

The Windows 'Send to' menu is a handy way to send files to a specific folder, application, or other destination. But you're not stuck with the menu as is. By Lance Whitney. Updated October 5, 2022.

How do you edit SendTo?

To delete or add locations, hit Windows Key+R and type: shell:sendto and hit Enter. The “SendTo” folder will open, and from here, you can delete locations that you'd never use and add more modern places. To get rid of a place, just right-click and hit Delete. To add a location, drag its shortcut into the SentTo folder.

What does send to in Windows do?

The "Send to" menu has been a cool and useful feature in Windows for generations. Use it to send, copy, or print an individual file to a specific location, device, application, or other item.


1 Answers

It's really simple to do once you understand what SendTo really does, and it doesn't involves COM or shell extensions at all. Basically, the send to menu is populated with the content of the SendTo folder of the user profile (C:\Users\\AppData\Roaming\Microsoft\Windows\SendTo by default in Windows 6.x).

When clicked, if the option is a shortcut to a folder it will copy the files there, but if there is a shortcut to a program (or a program executable itself) it will run that program, passing the paths of the selected files as command-line arguments.

From there, it's really trivial to make some program that simply takes paths as arguments, present some kind of notification and then copies the files or do whatever you want with them.

A quick and dirty example could be as follow (in C#, but could be done with anything else really):

private static void Main(string[] args)
{
    if(MessageBox.Show("Are you sure you want to copy files?", "Copy files", MessageBoxButtons.YesNo) == DialogResult.No) return;

    foreach (string file in args)
        File.Copy(file, Path.Combine("c:\\temp", Path.GetFileName(file));
}

This just ask for confirmation for copying a bunch of files. Note that this really doesn't "intercepts" the send to menu, but rather handles it completely, so it's the program responsability to do any meaningful action. A more serious implementation could use the built-in Windows copy dialog and display some screen with progress or anything else, that's up to your needs.

It could also take some more parameters on the command line. When you place a shortcut in the SendTo folder, the destination could add some more parameters that will be passed as the first ones (before the file names). For example the destination of the shortcut can read c:\program files\copyfiles.exe c:\temp to pass the destination folder instead of hardcoding. The called program must then interpret the first parameter as the destination path and subsequent ones as the source files.

like image 61
Alejandro Avatar answered Oct 21 '22 05:10

Alejandro