Use the standard "overwrite" dialog with custom information - c#

I am writing a utility copying files to/from remote drives (eg SkyDrive). When I'm about to overwrite a file, I pop up a regular "file exists, do you want to overwrite Y/N" message box; is it possible to use the standard Windows file overwrite dialog instead? With the three options (copy and replace, don't copy, copy but keep both) and the more detailed size / date information? Or should I just write my own form to duplicate that? (To be honest, I've been searching for this for two days, it would probably have been much faster to just write my own.)
To clarify: I need to show up that dialog when I choose to - sometimes I don't want to show it and just want to overwrite the file.
If at all possible, I would prefer for this to work in C# / .NET; however, if only an unmanaged solution exists I'll take that too.

Yes, it is possible! I did this for Send to Dropbox a little add-on utility I wrote for Explorer to right click and send files to a dropbox folder.
Copy SHFileOperation.cs into your project, and you can invoke it like so:
ShellFileOperation.CopyItems(source, target);
source can have multiple files/directories. Each item must be enclosed in quotes (").
target is the destination directory.
Example:
ShellFileOperation.CopyItems("\"c:\\foo.txt\" \"c:\\bar.txt\"", "d:\\xyz");

Related

How to merge 2 zip files together into 1 zip

I am trying to make a custom launcher for Minecraft in C# but I have come across a bump.
I want to add something into it, Minecraft Forge, but the only way I could think of is to change the extension of minecraft.jar to minecraft.zip, extract the contents of the Minecraft Forge.zip and the minecraft.zip into the same folder and then zip that entire folder up into minecraft.jar.
However minecraft.jar has a file named aux.class so whenever my extract script (Made in java) tries to extract it, it simply says:
Unable to find file G:\Programming\C#\Console\Forge Installer\Forge Installer\bin\Debug\Merge\aux.class.
The only other way I can think of is to merge minecraft_forge.zip into minecraft.zip, I have spent around 2 hours looking on Google (watch as someone sees it within a couple of minutes) but it always shows me results for "How to zip multiple files", "How to make a zip file in C#" etc.
So I have come here looking for my answer, sorry if this is a lot to read but I always see comments on here saying "You didn't give enough information for us to help you with".
EDIT: The question in case it wasn't clear is: How am I able to put the contents of minecraft_forge.zip into minecraft.zip?
In your case, if you cannot unzip the files due to OS limitations, you need to "skip" unzipping temporary files to zip them. Instead, only handle input & output streams, as suggested in the answers found here: How can I add entries to an existing zip file in Java?
As you pointed out, "aux" is a protected keyword within windows and it does not matter what the file suffix may be; windows won't let you use it. Here are a couple of threads that discusses this in general.
Ref 1: Windows reserved words.
Ref 2: Windows reserved words.
If you are typing in commands to perform the copy or unzip, there is a chance you can get this to work by using a path prefix of the following \\.\ or \\?\. When I tested this, it worked with either a single or double back-slash following the period or question mark. Such that the following work:
\\.\c:\paths\etc
\\.\\c:\paths\etc
\\?\c:\path\etc
\\?\\c:\path\etc
I used the following command to test this. When trying to rename through windows explorer it gave a "The specified device name is invalid." error message. From the command line it worked just fine. I should point out, that once you create these files, you will have to manually delete them using the same technique. Windows Explorer reports that these text files which have a size of 0 bytes "is too large for the destination file system", ie... the recycle bin.
rename "\.\c:\temp\New Text Document.txt" aux.txt
del "\.\c:\temp\aux.txt"
As far as copying directly from zip or jar files, I tried this myself and it appeared to work. I used 7-zip and opened the jars directly using the "open archive..." windows explorer context menu. I then dragged-and-dropped the contents from forge.jar to the minecraft jar file. Since it is the minecraft jar file with the offending file name the chance of needing to create a temporary file on the filesystem is reduced. I did see someone mention that 7-zip may extract to a temporary file when copying between jars and zips.
7-zip reference on copying between archives
I should point out that my copy of minecraft jar (minecraft_server.1.8.7.jar) did not contain a file named aux.class. I also did not try to use the jar after the copy/merge. Nor did I spend too much time trying to figure out how well it merged the two contents since it appears like there may be a conflict with com\google\common\base\ since there are similar class name but with different $ variable suffixes on them.
I hope these two possible suggestions could give you some room to work with to find a solution for your needs... if you're still looking.

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

C#/WPF: Implementing Autosave

how could i implement autosave in C#? i felt that saving to the currently open file is a simple but i may not want to overwrite my previous file (or should i just do that? i think google docs saves/overwrite the document tho they have version control?). i thought of saving to another file, but where do i save to?
also i guess i will have to know if there's any autosave files to retrieve and after a explicit save, i should remove the autosave file associated with the current document
Current versions of Microsoft Office (for example) save to a "shadow copy" of the working file. Depending on how you want it to work, you can have writes applied to the shadow copy every n seconds or when certain types of actions are taken.
When the program is shut down, the original is deleted and the shadow copy is renamed to the original. There are lots of options and strategies within this technique that can be applied depending on your particular situation and requirements.
You should create a Temporary File for the autosave. If the User saves, you can delete the file, and if your app crashes and is restarted it can load the last autosaved state from the file.

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.

How to Display the Contents from StreamReader directly on Notepad?

Is there a way to display the contents from memory directly in a Notepad window?
I'm assuming that I understand your question. If the file already exists on the machine you can execute the following:
System.Diagnostics.Process.Start( "notepad.exe", "[PATH]\[FILE].txt");
If not then save the file locally and then run the above code.
Double-click on the file, making sure the association is set to Notepad.
If you want Notepad to show it without saving it to disk, you can open an instance of Notepad, get the handle for the window, then write the text directly into there. You will need to use Windows User APIs to do this.
The easiest way to accomplish this is to save the file and open it in notepad, however there are at least two other ways.
Open Notepad then copy what you want to the clipboard, then using DDE force Notepad to paste. This is bad, because it potentially overwrites what the user may have been doing in the clipboard.
The second way involves getting a window handle to the notepad Edit control, then doing a WM_SETTEXT to the window. This will not, however, work across privilege boundaries (such as for apps that run as administrator, but notepad runs as a normal user). This also involves getting down to Native level and doing P/Invokes. Not exactly an easy method.
Frankly, it's just easiest to save it to a file and load it.
Why do you need notepad to show some contents (which is in memory)?
If you are using winforms, you could put it in a textbox.
Sorry, if I have not understood your question correctly.
I would like to add to MrEdmundo's answer that the Isolated Storage is the right place to store the temporary txt file for Notepad.

Categories