WPF file to file drag and drop - c#

I would like to have a function for my application such that dragging any file in Windows Explorer to a file having the correct format for my application adds that first file to the second, like with WinZip, 7-zip etc. Example, if I drag a file onto another zip file, it initiates the default application for Zip (in my case 7-zip) and adds it to the zip archive I drop it onto.
I've tried searching for a way to do this on Google, but I don't know what this type of function would be called or the correct keywords I should use. Referencing drag and drop, shell extensions etc. all points me to dragging a file from the Shell into my application or vice versa which I know how to do. Can anyone point me in the direction of what I should be searching for, or even better has some example code/tutorial on how to achieve this?

Well, searching for Shell extensions was correct. There is a github project that makes it easy to create shell extensions in .Net: https://github.com/dwmkerr/sharpshell
One of them is a drop handler, and that is what you're looking for if I understand your question right. There are some tutorials on how to use SharpShell on CodeProject, this one specific for the drop handler: http://www.codeproject.com/Articles/529515/NET-Shell-Extensions-Shell-Drop-Handlers

Related

Drag and Drop from ListView to Explorer [duplicate]

This question already has answers here:
Drag Drop from .NET application to Explorer
(2 answers)
Closed 7 years ago.
My goal is to able to drag an item from a ListView to Explorer. The way I'm trying to accomplish this is somewhat different though. From searching Google and around this site, I couldn't really find anything that would help me or pertained closely enough to what I'm trying to do. I can barely comprehend some of the examples because I don't understand enough about these drag and drop operations.
Specifically, the control that I'm trying to drag items from is a TreeListView from the ObjectListView library. The control is populated with nodes that represent the structure inside a archive-like compressed file. Entries are parsed into two different objects representing a file and a directory. Both of these models inherit an interface. When extracting these files normally, I use a Form that I instantiate with a collection of nodes and the target path that they will be extracted to as the parameters. It then takes care of extraction. This is so that I can show the overall and singular progress of each file.
Subscribing to the ItemDrag event, I know that I need to call DoDragDrop. When doing this, I need to be able to instantiate the extraction form only after the drop (when the user releases the mouse) into Explorer, and also be able to retrieve the path in which the items were dragged.
For some reason, this seems a lot more complicated than it should be. Any sort of advice or suggestions would be very helpful.
I'm not sure what format Explorer expects in the drag object, but this process might work for you.
When you begin the drag, pre-extract the selected files to some temp
directory
Build a DataObject which contains the paths of the files you have extracted in the format expected by Explorer
Use your DataObject in the DoDragDrop call
When the user drops on Explorer, the files should get copied from the temp directory to the drop target
Track all of your extracted files and cleanup when the application exists (id desired)
Hope this helps.
Edit (after some research):
I believe if you use
new DataObject(DataFormats.FileDrop, files)
where files is a string[] of the filenames to be copied (the ones you put in the temp directory), you shouold have the correct DataObject for implementation.
Haven't had a chance to write a prototype yet to test. Good Luck!

visual c# button opens file without specifying drive

I work for an IT company where we all carry around flash drives that have our most used programs on them.In my spare time I am hoping to create a "main menu" item that is kind of a fun and convenient way to access these files. I am working on creating this using Visual Studio 2013 and using visual C# windows forms. I have come across a snag however that I can't seem to find a workaround for. I am by no means fluent in C#, but I need to have a button on the windows form open a file without specifying what drive it comes from. I understand that I have to specify a path, but as these will be stored on the flash drives of myself and my coworkers I cannot foresee that the path will always begin with E:. Depending on what USB slot the drive is plugged into it could be N: or F: or the like. I have provided an example below:
Using what I currently know I am opening files using this line of code:
System.Diagnostics.Process.Start("C:/Users/Myname/Desktop/Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
Is there any way possible I can have the file open simply from
System.Diagnostics.Process.Start("Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
or something of that nature?
Thanks in advance.
There must have been some mis-communication when I asked my question previously. what I am looking to do is open an executable file via a button click on the windows form using a relative path. I am not able to specify the absolute path because the application will be run from a flash drive and therefore will change depending on what USB slot it is currently inserted into.
What I am hoping to accomplish is insert a line of code that will allow me to open an executable file that is located in the \bin\debug folder along with the application itself. I have a picture for clarification but apparently do not have enough reputation to post it. Thank you and sorry for the earlier confusion.
Usually you can just use Environment.GetFolderPath (MSDN) to give you what you need. It doesn't do absolutely everything, but if you need Desktop and the like, that is plenty.
Depending on the target version of .Net, the SpecialFolders exposed are not all there. It may turn out that you need more than they provide, but in your case it doesn't sound like it.
If there is more you need that is not covered in the default, check out this project. I'm sure there are others like it, but it does a little more than the default BCL version, using the API directly. It is at least something to read and learn (and translate from vb.. use an online translator, very quick). I haven't looked at it, but it seems like you are learning this c#/.net thingy, so it might be helpful
This article is about accessing Windows special folders.
These folders include your “Favorites”, “Cookies”, system libraries and the like.
Here is code, including a large number of constant definitions, plus documentation,
allowing access to and creation of these folders.

Replace save file dialog opened by any program by a customized save file dialog

I am working on a Version Control/File Sync System for Windows. It would be great to have a checkbox at the bottom of the classical save file dialog with the option to check/uncheck for my file versioning.
Is it possible to listen for opened save file dialogs by any program (word etc.) and replace/override that dialog with a customized one (with an additional checkbox)?
If the checkbox is checked, another window should pop-up where the user could enter some additional metadata. After that the data is stored in a local database.
I already worked with the approach by dmihailescu (link provided) but it's very complex and I do not know how to modify that example to listen for opened save file dialogs by other programs.
http://www.codeproject.com/Articles/19566/Extend-OpenFileDialog-and-SaveFileDialog-the-easy?msg=4779306#xx4779306xx
Another approach is to use the FileSystemWatcher but that's very expensive to watch the whole system and it's not very comfortable because the user has to be asked for any created file if he/she wants to version control it.
I hope someone could help me to solve that problem or has some additional tips / approaches.
Thank you.
Edit: Use-case
A user has to write a documentation and creates a new word-doc. When he/she clicks the Save as menu entry of word, my customized save file dialog should pop-up with a checkbox at the bottom, if this file should be versioned or not. If the checkbox is "active" a new window should appear where the user could enter additional metadata. After that the data should be stored in local database.
In my case, only the metadata (like the path etc.) should be stored in the database. Let's suppose a user stores the same file in two different directotries (one file is "older" and one file is the current one). If the user opens an older version of this file, my system should recognize that a "newer" one is already stored in another place and synchronize those files.
That should just be a very easy example.
You have two pieces of functionality: save and version-control. Both of the tasks are actually rather complicated. Therefore you shouldn't mix them. You better off using standard Windows API to save file and do not change that. Think about how you'd support several different Windows releases and how painful that would be.
I assume you have your own UI, and do not integrate with, say, Windows Explorer (like Tortoise Svn or Dropbox). In this case you can do version-control magic first and then just save the end file using standard API.
If you do integrate with Windows Explorer, I suggest you to have a look at Tortoise svn source code.

How can I create a “Open with” list as in Explore in my own application

In my application the user can select reference to file, for example a image file. I would like to make button with a arrow that opens a list with the programs installed on the system witch can open this file type.
I know that I can get the program names from the registry "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts", but how can I filter the entries out that have no meaning - "DllHost.exe, miaui.exe, etc."
And how can I open the file with program that the user choose?
# Lars Tech If I look in registry "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" and then "OpenWithList" for the extension ".jpg" I see more entries that if if rigt click on jpg file and choose Open With ( see my first images) and I only want those.
And yes there is program's entries that I properly self have added, but that have no meaning to a jpg file. And Windows can filter them out so will I.
I think you can use this article to validate and find out which of them are applicable and valid in your application
If running on Vista or better, you can use
'SHOpenWithDialog'
http://msdn.microsoft.com/en-us/library/bb762234(v=vs.85).aspx
- it's quite straightforward...
Jens

How can you detect when files are dropped into Windows Explorer?

I have a WinForms app that has a TreeView. The user can drag files from WindowsExplorer to the TreeView, and then they can drag the files back into WindowsExplorer which in affect copies the files to wherever the files were dropped. What I'm trying to do is, if the files already exist in the directory where the files are being dropped, I want to rename the files/folders being copied in ahead of time, so that there's no collision.
Here's how I'm copying files into WindowsExplorer. On the treeView's ItemDrag, I loop through the nodes of the selected node, and then package that into an array. Then, I use this code:
var dataObject = new DataObject(DataFormats.FileDrop, files.ToArray());
dataObject.SetData(DataFormats.StringFormat, dataObject);
DoDragDrop(dataObject, DragDropEffects.Copy);
This works well, but once it ships off to Windows Explorer, it's out of my hands. How can I find out when and where the files are being copied TO and intercept that to make changes? Is this possible?
Explorer Drag & Drop is an excellent article doing what you are trying to achieve.
EDIT2: It seems that there's a C++ article available for the same on CodeProject. But I was unable to find a way of how to do it using C#.
AFAIK, there is no way to know drop target (in your case destination folder). You can look into CFSTR_FILENAMEMAP shell clipboard format, but still in this case you can only provide name mappings before (or in process) of drag-n-drop.
Also note, that default DataObject in .net has limited shell support. So if you need to use mentioned above format, you need to write your own IDataObject implementation (or take someone's implementation, good example with lot shell drag-n-drop related stuff can be found here)
Instead of putting the file names into the dataobject, create a temporary file with a unique/easily distinguishable name and place that file name into the data object's drop list instead (That file could be empty or contain some information you might need). Use a FileSystemWatcher (watching an entire drive) to detect the drop (set the filter to the temporary file name, set IncludeSubDirectories to true, and set Path to root directory of drive to watch.) Initiate the DoDragDrop. Once the unique/easily distinguishable file is dropped, the FileSystemWatcher can tell you where it was dropped and you can do whatever you need to do (e.g. delete the dropped temporary file and replace with the ones you originally wanted to drop. It is a far-from-perfect solution but might help. Better still, it might give someone an idea to come up with a better one!)
One downside is that you don't really know in which drive someone might drop the file and you may have to set up a watcher for several drives. And if you miss a drive (or a network path) then problems .....! Remember to dispose of the watchers after the drop.
There has to be a better way though. e.g. consider when you drag a file from a zip folder. The file is only extracted after the drop.
i don't think that is possible.

Categories