I'm trying to find a way to reset the initial/default directory after closing an OpenFileDialog. Consider the following example:
using (OpenFileDialog openFile = new OpenFileDialog())
{
// Example: This opens in the 'Desktop' directory
// User navigates to 'Documents' directory in the Form before selecting a file
DialogResult result = openFile.ShowDialog();
if (result == DialogResult.OK) MessageBox.Show(openFile.FileName);
}
// Somewhere else, this code then runs
using (OpenFileDialog openFile = new OpenFileDialog())
{
// Problem: This now opens in 'Documents' directory. Not good!
// How to open using the same default directory (ie: Desktop)?
DialogResult result = openFile.ShowDialog();
if (result == DialogResult.OK) MessageBox.Show(openFile.FileName);
}
Just to be clear, 'Desktop' is just an example, I won't actually know the initial directory as it's stored in the registry (if I understand correctly).
I tried using the RestoreDirectory option. This did not seem to have any effect. From what I've read elsewhere it's supposed to reset the Environment.CurrentDirectory back to its original value, which sounds reasonable. However, I don't think OpenFileDialog even uses Environment.CurrentDirectory since the value is never changed, and never matches what OpenFileDialog opens with (unless I manually browse to it).
Is there anything I might be missing here? Does anyone know how to stop overwriting whichever directory variable OpenFileDialog uses as its default?
The default directory is stored in the following registry key on Windows 7.
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32
IIRC, this could be different on other OS's, so you might want to find out the exact directory depending on your OS version.
So what you could do is to grab that value when your application launches, and save it in the memory, and set that to OpenFileDialog.InitialDirectory every time before you open the dialog.
Related
I am writing a WPF / C# application, and would like to enable a user to select one (or multiple) files, or one (or multiple) folders, without having to select which option they use initially, but intentionally. In my opinion, the best way to acchieve this goal would be to have a standard FolderBrowserDialog, and as long as the user does not seelct a file, but browses to a path, clicking the open button should select that path.
Practically, this solution does not work, because OpenFileDialog does not allow empty selections, you can hit "open", but nothing will happen. There is one workaround descriped here which allows to enter a fake name like "Selected Folder." as filename. which can afterwards be filtered out, which is a workaround, but not a nice one:
http://www.codeproject.com/Articles/44914/Select-file-or-folder-from-the-same-dialog
This solution has two important weaknesses:
1.) you will have to filter for the fake name
2.) if you paste a filename manually, or select a file first, and then switch the selection to a folder instead, the fake name is not inserted automatically.
of course I am aware there is something like FolderBrowserDialog, which I omit using even if I only wanted to select folders and not files. The reason: this dialog has no possibility to paste paths from clipboard, and I find it annoying to navigate all the way, I rather copy paths from somewhere and paste them, which works perfectly fine in OpenFileDialog, but not in FolderBrowserDialog. Besides, FolderBrowserDialog does not allow to select files and folders.
I have googled a lot, but do not find satisfying solutions, although I am sure many people must obviously face this problem.
As mentioned, the most elegant way for me would be to make the OpenFileDialog simply allow empty Filename boxes when clicking Open - any way to acchieve this?
Thanks alot.
Letting a user select a directory OR a file using the same dialog is not practical nor intuitively possible.
However, if you want a solution for selecting a Folder, here it is :
If you don't want to create a custom dialog but still prefer a 100% WPF way and don't want to use separate DDLs, additional dependencies or outdated APIs, I came up with a very simple hack using WPF's Save As dialog for actually selecting a directory.
No using directive needed, you may simply copy-paste the code below !
It should still be very user-friendly and most people will never notice.
The idea comes from the fact that we can change the title of that dialog, hide files, and work around the resulting filename quite easily.
It is a big hack for sure, but maybe it will do the job just fine for your usage...
In this example I have a textbox object to contain the resulting path, but you may remove the related lines and use a return value if you wish...
// Create a "Save As" dialog for selecting a directory (HACK)
var dialog = new Microsoft.Win32.SaveFileDialog();
dialog.InitialDirectory = textbox.Text; // Use current value for initial dir
dialog.Title = "Select a Directory"; // instead of default "Save As"
dialog.Filter = "Directory|*.this.directory"; // Prevents displaying files
dialog.FileName = "select"; // Filename will then be "select.this.directory"
if (dialog.ShowDialog() == true) {
string path = dialog.FileName;
// Remove fake filename from resulting path
path = path.Replace("\\select.this.directory", "");
path = path.Replace(".this.directory", "");
// If user has changed the filename, create the new directory
if (!System.IO.Directory.Exists(path)) {
System.IO.Directory.CreateDirectory(path);
}
// Our final value is in path
textbox.Text = path;
}
The only issues with this hack are :
Acknowledge button still says "Save" instead of something like "Select directory", but in a case like mines I "Save" the directory selection so it still works...
Input field still says "File name" instead of "Directory name", but we can say that a directory is a type of file...
There is still a "Save as type" dropdown, but its value says "Directory (*.this.directory)", and the user cannot change it for something else, works for me...
Most people won't notice these, although I would definitely prefer using an official WPF way if microsoft would get their heads out of their asses, but until they do, that's my temporary fix.
I am trying to replicate the standard save file process where, if there already exists a file with the necessary file extension, it is pre-selected in the SaveFileDialog. In my program I am using SaveFileDialog to allow the user to select the path for the file on the system. Upon save, it will automatically open to the path that the last saved file was, but the user has to re-select it.
Here is where I think something like this would come into play in my code:
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = ".cct"; //The file extension
Nullable<bool> result = dlg.ShowDialog(); //Lets user select path
//**I'm guessing that the "pre-select" operation I am talking about
//would go here
directory = Path.GetDirectoryName(dlg.FileName); //Directory = File path on system
I have looked at the CheckFileExists property and it says that it "Gets or sets a value indicating whether a file dialog displays a warning if the user specifies a file name that does not exist." So it looks like it's more focused around checking whether or not the user enters a new file name.
How do I make it so that the previously saved file with the same extension is highlighted or selected in the SaveFileDialog if one is found upon save?
You can do a couple of things.
You could restore the path the user last saved with by setting dlg.RestoreDirectory = true.
Set the FileName before you show the dialog and it will automatically show that folder and insert the file name using dlg.FileName
http://msdn.microsoft.com/en-us/library/microsoft.win32.savefiledialog(v=vs.110).aspx
My program has a treeview which lists files from a remote computer. What I need to do is to copy these files from remote into one of my local folders. I wish that when I right click the file in treeview, a dialog box shows up for me to choose a folder, and then I click "OK" in the dialog box, my clicked file could be saved inside that folder.
Since the path of the files in remote is unc path, I'm using
File.Copy(string remote_address, string local_address)
to copy the files. As i said before I need a dialog window to choose folders. So I've tried using a FolderBowserDialog, however its SelectedPath property returns me only the path to the folder not including the folder's name! And I haven't found any property to return me the folder's name.
So my questions are:
If there's a way allowing me to use FolderBowserDialog, that I could get the full path of the location where I save my file?
If there's another method allowing me to copy or download the files from remote, like using SaveFileDialog. The problem is I don't know how to us it to do this.
The following should work:
var fbd = new FolderBrowserDialog();
if(fbd.ShowDialog() == DialogResult.OK)
{
var localPath= Path.Combine(fbd.SelectedPath, Path.GetFilename(remote_address));
File.Copy(remote_address, localPath);
}
I'm not sure which "SavePath" property you are referring to, as FolderBrowserDialog has no such property. The property you are looking for is called SelectedPath.
FolderBrowserDialog dlg = new FolderBrowserDialog();
dlg.ShowDialog();
string local_address = dlg.SelectedPath;
After you call the FolderBrowserDialog's ShowDialog() method it will return a variable indicating what button the user pressed (ie, Ok or Cancel)
after you make sure the user had used "Ok" to indicate they want to proceed with the operation, you can access the "SelectedPath" field which will give you the full local path they selected.
You can then get the final path by calling
System.IO.Path.Combine(fbd.SelectedPath,remoteFileName);
I'm assuming that fbd is your FolderBrowserDialog instance and remoteFileName should contain just the filename part of the remote file (eg. "MyFile.txt");
If you want to separate the filename from the full remote path, use
var remoteFileName = System.IO.Path.GetFileName(remotePath);
That being said, what a user would typically expect is not a folder browser dialog, but the save file dialog.
you can initialize the save file dialog with a filename, leaving the user to select a folder and possibly change the intended file name as well if they wish.
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = remoteFileName;
sfd.ShowDialog();
sfd.FileName // now contains the full path to the file that the user has selected
don't forget to take the result from the ShowDialog() call to make sure the user didn't cancel out of the save dailog!
I'm making a launcher to open all applications on my computer. But I do not know how to read the parameters of the opened file is a shortcut. I have tried using:
openFileDialog.DereferenceLinks = false; //and true
Can anyone help me? My code is here:
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog od = new OpenFileDialog();
od.DereferenceLinks = false;
od.Multiselect = false;
od.SupportMultiDottedExtensions = true;
if (od.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
if (System.IO.Path.GetExtension(od.FileName).ToLower().Equals(".lnk"))
{
MessageBox.Show(//xxxxxxx how to sho the parameter?); for example output c:\\.....\hl.exe -a -b -c -d -e 29332
}
}
}
I can't understand what the problem is here. You said you've already discovered the FileDialog.DereferenceLinks property, which does exactly what you want.
When it is set to true, the dialog box dereferences all shortcuts, returning the path of the item that they point to, rather than the path of the shortcut file itself. Only when it is set to false will you get files with a .lnk extension returned from the dialog.
So the code that you have just added to the question is wrong (or at least, makes things much more difficult for you than they need to be). It should look more like this:
OpenFileDialog od = new OpenFileDialog();
od.DereferenceLinks = true; // set this to true if you want the actual file
od.Multiselect = false;
od.SupportMultiDottedExtensions = true;
if (od.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// You will never get a path to a shortcut file (*.lnk) here.
Debug.Assert(!String.Equals(System.IO.Path.GetExtension(od.FileName),
".lnk",
StringComparison.OrdinalIgnoreCase));
// ... do something with the file
}
Otherwise, dereferencing shortcut files takes a fair bit of effort. You do so using the IShellLink COM interface, which I don't believe is wrapped explicitly by any part of the .NET BCL. You'll need to write the code to use it yourself. I can't imagine why you'd need to in this case.
That is what you'll have to do if you need to read the arguments from a shortcut file.
Set the OpenFileDialog.DereferenceLinks property to false so that you get shortcut files returned.
You probably also want to set the OpenFileDialog.Filter property to Shortcut files (*.lnk)|*.lnk in order to ensure that the user can only select shortcut files in the dialog.
Once the user has selected a shortcut file, create an IShellLink object for that file.
If that succeeds, use the GetPath method to obtain a string containing the path and file name of the shortcut file, and GetArguments method to obtain a string containing the command-line arguments associated with that shortcut file.
Finally, append the arguments string to the end of the path string.
You can either write the wrapper code to use the IShellLink COM interface from .NET yourself, search online to find one that's already been written (no guarantees about its quality, though), or add a reference to the ShellLinkObject class which is designed for scripting but still usable from .NET.
In FileOpen or FileSave dialogbox when I call them, they automatically go to the last opened path. This happens even if I close my application and open it. But how to get that path/file name to a textbox or variable?
it seems a bit weired but under Windows 7 it works with the folling:
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);
Try it and tell me if you need further help.
Presumably the information is stored somewhere in the depths of the registry (it's done by the unmanaged control to which OpenFileDialog is only a wrapper). The easiest would probably be to persist the path the last time the dialog was closed in your application somewhere where you can access it.
As mentioned here: What does the FileDialog.RestoreDirectory Property actually do?
They use the path from Environment.CurrentDirectory.
I am having a similar problem to Vicky, which goes as follows. I am developing in Visual Basic 2008 Express Edition under Vista Business SP2.
I have an application with an OpenFileDialog and a SaveFileDialog. When I call the OpenFileDialog on first running the application, it defaults to the directory from which the Application last opened/saved a file. However, this directory IS NOT "Environment.CurrentDirectory" which is set to "C:\Users\Brian\Documents\Visual Studio 2008\Projects\IFPM Analysis\IFPM Analysis\bin\Debug" and is not changed by either the OpenFileDialog or SaveFileDialog.
Later on in the Application, I call the SaveFileDialog, with the initial directory property (.InitialDirectory) set in the code to a default directory. When I subsequently call the OpenFileDialog, it defaults to the directory used by the SaveFileDialog. All the time, the value of "Environment.CurrentDirectory" is unchanged.
So, my question is, where is the directory that is being used by the OpenFileDialog and SaveFileDialog being stored? I assume it is something to do with the underlying FileDialog class, and I know persists even after the Application has been closed and restarted.
Ideally I want to be able to store the directory selected by the user from the OpenFileDialog and reset it after I have used the SaveFileDialog. While I can use the InitialDirectory property of the OpenFileDialog within the Application, this doesn't help me when I close the Application and restart it. Sadly, the typical user actions are:
start Application
open file with OpenFileDialog
save file with SaveFileDialog
leave Application
This means that when the user comes back to the Application, the default directory is the "wrong" one. I know that I can save the last used directory from the OpenFileDialog in my own configuration file so that it will persist outside of the Application, but that seems a little silly when Windows provides me with the same functionality, if only I knew where to look!
Any help gratefully received!
Thanks,
Brian.
The recent opened files list is stored in 2 places:
Recent Folder: The recent folder is usually located under C:\Documents and Settings[Your Profile]\Recent (The path is different under Windows Vista), and it contains shortcuts to the recently opened files.
Registry: Each time that a file is selected in save/open dialog-box, the filename is added to the files list under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU
This method can help you to get the list:
public static string GetLastOpenSaveFile(string extention)
{
RegistryKey regKey = Registry.CurrentUser;
string lastUsedFolder = string.Empty;
regKey = regKey.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU");
if (string.IsNullOrEmpty(extention))
extention = "html";
RegistryKey myKey = regKey.OpenSubKey(extention);
if (myKey == null && regKey.GetSubKeyNames().Length > 0)
myKey = regKey.OpenSubKey(regKey.GetSubKeyNames()[regKey.GetSubKeyNames().Length - 2]);
if (myKey != null)
{
string[] names = myKey.GetValueNames();
if (names != null && names.Length > 0)
{
lastUsedFolder = (string)myKey.GetValue(names[names.Length - 2]);
}
}
return lastUsedFolder;
}
Success!
Iordan