1

I have an application that can be run from Explorer, and passes the selected directory to the application. So I can use the following code:

private void frmMain_Shown(object sender, EventArgs e)
    {
        //open the dir
        DirectoryInfo d = new DirectoryInfo(cmdArgs);
        SelectDirectoryInTree(d);
    }

This however fails if the user selects a Special Folder. The path returned for these folders is different. So, for example, if the user selects Libraries\Documents folder, (or any other folder in there) the returned DirectoryInfo is ::{xxxxx-xxxx-xxxxx-xxx-xxxxx}\Documents.library-ms

The specific exception:

System.ArgumentException: The path is not of a legal form.
   at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength)
   at System.IO.Path.GetFullPathInternal(String path)
   at System.IO.DirectoryInfo.Init(String path, Boolean checkHost)
   at System.IO.DirectoryInfo..ctor(String path)
   at FindIt.frmMain.frmMain_Shown(Object sender, EventArgs e) in d:\C#\+Other\FindIt\frmMain.cs:line 476
   at System.Windows.Forms.Form.OnShown(EventArgs e)
   at System.Windows.Forms.Form.CallShownEvent()
   at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
   at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
   at System.Windows.Forms.Control.InvokeMarshaledCallbacks()

Whats the simplest way to get the correct folder supplied by the explorer shell?

Simon
  • 9,197
  • 13
  • 72
  • 115
  • Have you tried FullName property of the DirectoryInfo? http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.fullname(v=vs.110).aspx Documentation says it will return the full path of the directory or file. – Stelios Adamantidis Jan 24 '14 at 07:46
  • It doesn't work, as the `DirectoryInfo` constructor throws an exception – Simon Jan 24 '14 at 07:53
  • Then please edit your question and be little bit more specific and include the exception type and details. From the question, I supposed that `DirectoryInfo` constructor was ok and you had problem in `SelectDirectoryInTree()`. – Stelios Adamantidis Jan 24 '14 at 08:02

4 Answers4

2

Have you considered using the Windows API Code Pack? It contains a number of functions for the Windows Shell.

The User Libraries Folder is a special folder, and as such, it has a special parsing name,

::{031E4825-7B94-4DC3-B131-E946B44C8DD5}

If you were to copy and paste the above into your explorer or into the run command you would get the user libraries folder.

Enumerating over those folders with the Shell interfaces, you would be able to retrieve all folders and files inside each of the libraries, and each of them would resolve to an on-disk location. In reality, each folder and file in each library will each resolve to a parsing location which is usually the physical (or in some cases, network) location of the file and folder in question.

As far as enumerating all the files in a library is concerned, however, you need to use the shell API, because of the special kind of folders they are (libraries combine several physical locations into one "virtual" location.)

You should learn about parsing names. There's a lot of interesting things you can do with the system once you have something's parsing name, including bringing up property sheets with ShellExecuteEx (which is a function in the Win32 Api).

There is a sample program in the Windows API Code Pack called "KnownFolders Browser" it should elucidate many things regarding the shell for you.

Nathan M
  • 873
  • 5
  • 18
  • Thanks Nathan, this looks promising, I can't try it right now but when I have a decent internet connection to download it I will. I can see all these CLSID's in the registry, that may be another option – Simon Jan 24 '14 at 11:18
  • Well, now, I do not know if the CLSID is the same as the parsing name. The Special folder constant for the Recycle Bin, for example, is not the same as its parsing name. – Nathan M Jan 24 '14 at 11:28
2

This is for future people since this is so old. I followed Nathan's suggestion and posted a full solution with code using Windows API Code Pack at this other StackOverflow question that was wanting something similar. Take a look!

Community
  • 1
  • 1
mdiehl13
  • 472
  • 6
  • 19
0

The Libraries in Windows 7 are not actual folders, but rather collections of physical folders. Because of that there is no way to convert to a standard c:\foldername structure.

mageos
  • 1,216
  • 7
  • 15
  • 1
    Thanks, but I don't beleive you. There must be a way to get the actual location. – Simon Jan 24 '14 at 08:12
  • Right click the Library in Explorer. When you do you will see that you can add any number of physical folders to the Library and how Windows should optimize the merging of the files in the selected folders. – mageos Jan 24 '14 at 09:06
  • Mageos is right, I provided a link to a full-code solution that returns a list of all folders added to the library. For example, my Documents library includes 2 folders: the full c:\foldername path to shared documents and user documents – mdiehl13 Jul 06 '15 at 20:31
0

You could check if that folder is a special folder and resolve it accordingly:

System.Environment.SpecialFolder

http://msdn.microsoft.com/en-us/library/system.environment.specialfolder%28v=vs.110%29.aspx

Environment.GetFolderPath(Environment.SpecialFolder)

http://msdn.microsoft.com/en-us/library/14tx8hby%28v=vs.110%29.aspx

toATwork
  • 1,335
  • 16
  • 34
  • Yes but as you can see, he has a string and not the convenient enum that you provided. So somehow he will have to parse the string and "guess" what the proper enum is. – Stelios Adamantidis Jan 24 '14 at 10:39
  • That is quite easy, just iterate all special folder as mentioned here: http://stackoverflow.com/a/7131428/2243584 – toATwork Jan 24 '14 at 10:48
  • I don't see the connection. In the linked post, there is a `DirectoryInfo`. In this example you don't have the `DirectoryInfo` you want to construct it and you have to do it with the weird path provided in the question. – Stelios Adamantidis Jan 24 '14 at 11:12
  • I added a solution (with full working code) that shows how to get a list of all of the folders inside these libraries, given a string like: `::{xxxxx-xxxx-xxxxx-xxx-xxxxx}\Documents.library-ms` – mdiehl13 Jul 06 '15 at 20:30