Bizarre FolderBrowserDialog behaviour - c#

I'm supporting an old version of a C# application, running on .NET 3.5. We've found an issue with the FolderBrowserDialog on Windows Vista (either 32 or 64-bit).
Basically what happened is that the dialog would appear, but only the root Desktop node would be shown, not even able to expand it to show anything else. Obviously, that's impossible to use.
After a huge amount of trial and error I eventually managed to get something useable, by setting the RootFolder property before the rest of the setup:
FolderBrowserDialog browsePath = new FolderBrowserDialog();
browsePath.RootFolder = Environment.SpecialFolder.MyComputer;
browsePath.SelectedPath = this.textBoxTo.Text;
browsePath.Description = TextResources.OutputTargetCaption;
browsePath.ShowNewFolderButton = true;
if(browsePath.ShowDialog(this) == DialogResult.OK)
{
this.textBoxTo.Text = UpdateLocation(browsePath.SelectedPath);
}
This almost works; however, I've got the bizarre issue that then the SelectedPath (by definition the contents of textBoxTo) is a path to within the current user's home directory, it won't automatically browse to that path, instead just showing the My Computer node expanded to one level. It's perfectly fine for any other path.
I'm sure your first guess would be a permissions issue, as was my intuition. It doesn't appear to be, this issue occurs running normally and as an Administrator, for both standard and Administrator accounts. It's a clean install, of course, no weird permissions or anything.
This is pretty annoying when all of our defaults are within the current user's directory!
Note: This only happens within the application; it's not reproducible with a small test application, as far as I've seen.
Any ideas on what could be causing this?
Update: Screenies:
This is the behaviour I want (obtainted from a little test app)
This is what I get with the default property
This is what I get by setting the root to My Computer
Note: The last image had the same SelectedPath set as the expected image...

I had a similar problem. In Windows Vista and Windows 7 the following code:
browsePath.RootFolder = Environment.SpecialFolder.MyComputer;
returns the Desktop. If you look in Windows Explorer, the root of the tree is Desktop, not My Computer like it was in Windows XP.
To solve this problem use this instead:
browsePath.RootFolder = #"C:\";
Every Windows computer has a C:\ drive, so this will solve your problem.
I hope this helps you.

If you're only accessing the users private folders, use
browsePath.RootFolder = Environment.SpecialFolder.Personal
Only the specified folder and any subfolders that are beneath it will
appear in the dialog box and be selectable. The SelectedPath property,
along with RootFolder, determines what the selected folder will be
when the dialog box is displayed, as long as SelectedPath is an
absolute path that is a subfolder of RootFolder (or more accurately,
points to a subfolder of the shell namespace represented by
RootFolder).
In short, you can not input someones private folder as a startup selectedPath unless RootFolder is inside the current users private folder already.
For details, see: http://msdn.microsoft.com/en-us/library/system.windows.forms.folderbrowserdialog.rootfolder.aspx

VB.NET code
Dim fdb As New FolderBrowserDialog
With fdb
'.RootFolder = Environment.SpecialFolder.MyComputer
'this folder don't exists in vista, the my computer folder was renamed to computer (in spanish "mi pc" to "equipo")
'try with another initial folder
.RootFolder = Environment.SpecialFolder.Desktop
'You can set the desktop as home directory because users typically already have shortcuts or the left side menu to navigate
Dim dr As DialogResult = .ShowDialog
If _
dr = DialogResult.OK Or _
dr = DialogResult.Yes Then _
If IO.Directory.Exists(.SelectedPath) = True Then _
Me.textBoxTo.Text = UpdateLocation(.SelectedPath)
End With
basically, try another directory and make sure the chosen directory exists.
if you're still having problems, is probably due to some fault in the system.

Related

How to open a file's folder? C# [duplicate]

I saw the other topic and I'm having another problem. The process is starting (saw at task manager) but the folder is not opening on my screen. What's wrong?
System.Diagnostics.Process.Start("explorer.exe", #"c:\teste");
Have you made sure that the folder "c:\teste" exists? If it doesn't, explorer will open showing some default folder (in my case "C:\Users\[user name]\Documents").
Update
I have tried the following variations:
// opens the folder in explorer
Process.Start(#"c:\temp");
// opens the folder in explorer
Process.Start("explorer.exe", #"c:\temp");
// throws exception
Process.Start(#"c:\does_not_exist");
// opens explorer, showing some other folder)
Process.Start("explorer.exe", #"c:\does_not_exist");
If none of these (well, except the one that throws an exception) work on your computer, I don't think that the problem lies in the code, but in the environment. If that is the case, I would try one (or both) of the following:
Open the Run dialog, enter "explorer.exe" and hit enter
Open a command prompt, type "explorer.exe" and hit enter
Just for completeness, if all you want to do is to open a folder, use this:
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo() {
FileName = "C:\\teste\\",
UseShellExecute = true,
Verb = "open"
});
Ensure FileName ends with Path.DirectorySeparatorChar to make it unambiguously point to a folder. (Thanks to #binki.)
This solution won't work for opening a folder and selecting an item, since there doesn't seem a verb for that.
If you want to select the file or folder you can use the following:
Process.Start("explorer.exe", "/select, c:\\teste");
You're using the # symbol, which removes the need for escaping your backslashes.
Remove the # or replace \\ with \
You don't need the double backslash when using unescaped strings:
System.Diagnostics.Process.Start("explorer.exe",#"c:\teste");
You should use one of the System.Diagnostics.Process.Start() overloads. It's quite simple!
If you don't place the filename of the process you want to run (explorer.exe), the system will recognize it as a valid folder path and try to attach it to the already running Explorer process. In this case, if the folder is already open, Explorer will do nothing.
If you place the filename of the process (as you did), the system will try to run a new instance of the process, passing the second string as a parameter. If the string is a valid folder, it is opened on the newly created process, if not, the new process will do nothing.
I don't know how invalid folder paths are treated by the process in any case. Using System.IO.Directory.Exists() should be enough to ensure that.
Use an overloaded version of the method that takes a ProcessStartInfo instance and set the ProcessWindowStyle property to a value that works for you.
You're escaping the backslash when the at sign does that for you.
System.Diagnostics.Process.Start("explorer.exe",#"c:\teste");
System.Diagnostics.Process.Start("explorer.exe",#"c:\teste");
This code works fine from the VS2010 environment and opens the local folder properly, but if you host the same application in IIS and try to open then it will fail for sure.
Ive just had this issue, and i found out why. my reason isnt listed here so anyone else who gets this issue and none of these fix it.
If you run Visual Studio as another user and attempt to use Process.Start it will run in that users context and you will not see it on your screen.
Does it open correctly when you run "explorer.exe c:\teste" from your start menu? How long have you been trying this? I see a similar behavior when my machine has a lot of processes and when I open a new process(sets say IE)..it starts in the task manager but does not show up in the front end. Have you tried a restart?
The following code should open a new explorer instance
class sample{
static void Main()
{
System.Diagnostics.Process.Start("explorer.exe",#"c:\teste");
}
}
Do you have a lot of applications running when you are trying this?
I encounter weird behavior at work sometimes because my system runs out of GDI Handles as I have so many windows open (our apps use alot).
When this happens, windows and context menus no long appear until I close something to free up some GDI handles.
The default limit in XP and Vista is 10000.
It is not uncommon for my DevStudio to have 1500 GDI handles, so if you have a couple of copies of Dev studio open, it can eat them up pretty quickly. You can add a column in TaskManager to see how many handles are being used by each process.
There is a registry tweak you can do to increase the limit.
For more information see http://msdn.microsoft.com/en-us/library/ms724291(VS.85).aspx
System.Diagnostics.Process.Start("explorer.exe",#"c:\teste");
Just change the path or declare it in a string

FolderBrowserDialog on company network to select subfolder

In my WPF app the user needs to select a folder, which path is in the company network. I use the System.Windows.Forms.FolderBrowserDialog and the following code gets executed on a button click event:
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.SelectedPath = "\\\\company.net\\data\\_Confidential";
DialogResult result = fbd.ShowDialog();
When the FolderBrowserDialog opens, the system automatically scans for other network devices and that causes the following problem:
The network tree gets filled with other devices and causes my SelectedPath to scroll away. This is pretty annoying when a user starts searching for a special subfolder, because he has to scroll down or his selection clicks can hit a newly added device (lost focus).
How can i avoid this problem?
Thoughts:
Can I extend/overwrite the System.Environment.SpecialFolder Enum and
set fbd.RootFolder = System.Environment.SpecialFolder.MySepcialNetworkPath;
Should I access the network folder with another dialog/control?
Should I remove the "Browse..." Button in my View and instead scan the whole \\\\company.net\\data\\_Confidential path and provide a combobox/other selection control(e.g. own subfolder-tree)?
The FolderBrowserDialog is 'adopting' your PC settings depending on how your Network Discovery is configured on your PC/network. By doing so your folder browsing experience will be consistent over other applications.
Although what you see is default behavior of the FolderBrowserDialog, you may also look at this: https://stackoverflow.com/a/15440926/5793786 Solved an issue somewhat similar to yours #Frank
While I was searching for the same problem I came across this thread:
How to use OpenFileDialog to select a folder?
Where the user uses a "CommonOpenFileDialog" available in the Nuget Package "WindowsAPICodePack-Shell".
This solved my issue, though it uses the OpenFileDialog interface.
Then the network drive can just be browsed.

Finding Install path of a program

I am new to C# and I have made a simple Windows Forms Application that basically updates the persons files for a game.
They have to manually move and delete certain folders just to change version every time. I have successfully accomplished this.
However before I start giving it out I really should improve it. I know I need to change the name of the processes and remove my descriptions ETC.
I have stumbled onto an error and instead of me taking a guess I think it is best to get an opinion from a more experienced person about how to do this.
I am going to use Inno Setup to make the installer for my application, this way I can be sure it will go into their program files 32 and 64 bit. So I know this will be in program files.
So now I am wondering if I have done this the correct way or not? I was using this format to find their program files:
string programFilesFolder = Environment.GetEnvironmentVariable("PROGRAMFILES(X86)") ?? Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
However, would this work on all windows systems(XP, Vista, Win7, Win8) and is it completely accurate? I was going to use the above, and then use this:
string PATCHSELECTOR = Path.Combine(programFiles, #"PATCH SELECTOR");
if (Directory.Exists(PATCHSELECTOR))
{
string GamereliteFolder = Path.Combine(programFiles, #"GAMERELITE~1");
if (Directory.Exists(GamereliteFolder))
And then I move the files using the string method. If the file exists it is deleted before I copy the file over from PATCH SELECTOR to GAMERELITE.
Also will windows XP support using the .exe with an assembly resource embedded which is making the program need to be ran as administrator? I previously was making the assembly work through UAC however that wouldnt always work if they have UAC off or if it is XP so I thought I would try the admin assembly instead.
Can anyone possibly give me some insight, ideas or links?
For executables (not sure for websites & web application) this returns the directory where the executable lives (it's actually the base path where the framework will probe for Assemblies to load, 99% of the the that's the same thing).
System.AppDomain.CurrentDomain.BaseDirectory
This method works for any executable located in a folder which is defined in the windows PATH variable:
private string LocateEXE(String fileName)
{
string path = Environment.GetEnvironmentVariable("path");
string[] folders = path.Split(';');
foreach (var folder in folders)
{
if (File.Exists(Path.Combine(folder, fileName)))
{
return Path.Combine(folder, fileName);
}
}
return String.Empty;
}
Usage:
string pathToEXE = LocateEXE("Example.exe");
Reference:
how to find the execution path of a installed software
How can I get another application's installation path programmatically?
Couple things:
Among the already stated answers, Assembly.GetExecutingAssembly().Location will also give you the full file path of the currently "executing" Assembly. (Alternatively, GetCurrentAssembly)
If I'm reading your question correctly, you're trying to find both your own location as well as another application's. I would highly recommend seeing if the other application has a registry key that specifies the exact location - it'll make your copy step WAY more stable.

Select the default path of the FolderBrowserDialog in c# wpf

I am currently working on a C# WPF project. I have a FolderBrowserDialog in the System.Windows.Forms namespace. I am creating an instance of the dialog with a variable named dlg and assigning the selected path to My Documents by using the following line of code:
dlg.SelectedPath = Environment.SpecialFolder.MyDocuments.ToString();
However, this doesn't seem to make much difference. I then tried doing the same thing but with the root path but this just seems to make it that it will set the root as My Documents and you can't get out of My Documents, i.e. to C:\ or Desktop.
How can I set a default path but still allowing access to all available areas of the drive, e.g. default path to be My Documents but allow the user to go outside of My Documents to C:\ or desktop.
Thanks for any help you can provide.
You are assigning the wrong value to SelectedPath. By setting Environment.SpecialFolder.MyDocuments.ToString(), you are setting the string "MyDocuments" (or "Personal" as it has the same value in the Environment.SpecialFolder enum) to the SelectedPath. This cannot be found as it is not a valid path, so nothing gets selected.
You need to lookup the path of the special folder using Environment.GetFolderPath():
dlg.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
This will set the path of the special folder, which the folder browse dialog will select when it opens.

Why do i get E_ACCESSDENIED when reading public shortcuts through Shell32?

I'm trying to read the targets of all desktop shortcuts in a C# 4 application. The shortcuts on a windows desktop can come from more that one location, depending on whether the shortcut is created for all users or just the current user. In this specific case I'm trying to read a shortcut from the public desktop, e.g. from C:\Users\Public\Desktop\shortcut.lnk.
The code is like this (path is a string contaning the path to the lnk file):
var shell = new Shell32.ShellClass();
var folder = shell.NameSpace(Path.GetDirectoryName(path));
var folderItem = folder.ParseName(Path.GetFileName(path));
if (folderItem != null)
{
var link = (Shell32.ShellLinkObject)folderItem.GetLink;
The last line throws an System.UnauthorizedAccessException, indicating that it's not allowed to read the shortcut file's contents. I have tried on shortcut files on the user's private desktop (c:\Users\username\Desktop) and that works fine.
So, my questions are:
(1) why is my application not allowed to /read/ the shortcut from code, when I can clearly read the contents as a user?
(2) is there a way to get around this? Maybe using a special manifest file for the application?
And, by the way, my OS is Windows 7, 64-bit.
be well
-h-
Yes, you cannot get access to the .lnk file in that folder by default. You are creating a COM object that allows you to modify the .lnk properties. And that requires an administrator level account with UAC turned off.
Yes, you can fix that with a manifest.

Categories