9

I need to store files into the common desktop on Windows. The application is a very special application for exactly one special PC (device preparation), so it had to be easy for non-techie users to find and modify the configuration file. Now we switched to a domain, and because different people (with different accounts) should use the software, it has to be in a common place, seen by every user. So please don't ask why it's on the desktop ;)

Previously, I just used Environment.GetFolderPath(Environment.SpecialFolder.Desktop). There are several of the common folders in the SpecialFolder enumeration, but the common desktop seems not to be there. Am I missing something, or do I have to p/invoke SHGetSpecialFolderPath with CSIDL_COMMON_DESKTOPDIRECTORY?

mirabilos
  • 5,123
  • 2
  • 46
  • 72
OregonGhost
  • 23,359
  • 7
  • 71
  • 108
  • Now it gets dirty. Unfortunately, it seems I have by default no rights to write to the common desktop, which makes this complicated. Any suggestions for a better location? Remember that the user should be able to find the file, and all users need read/write access. The application should by XCOPY-deployed. – OregonGhost Aug 11 '09 at 09:11
  • While the original question stays valid (especially since it seems not be anywhere on SO), I think I'll have to go with common documents (or whatever the name on English systems is). That's still kind of findable by the user. Now let's just hope I have write access. Feel free to comment if you think that this is a good/bad idea. – OregonGhost Aug 11 '09 at 09:21
  • Why don't you store them in a machine scope isolated storage? – David Brunelle Mar 11 '10 at 20:26
  • @David Brunelle: I'll have a look, thanks. – OregonGhost Mar 12 '10 at 10:14
  • Damn. I knew I should put that in an answer instead. Could've get some vote... :o – David Brunelle Mar 12 '10 at 13:54
  • @David Brunelle: Though that might solve my underlying problem, it wouldn't be a correct answer to this question :) – OregonGhost Mar 15 '10 at 09:55
  • Wow, I can't believe there is not a better answer for this! – Josh Stodola Jun 15 '10 at 15:59
  • Note that in .NET 4.0, the `SpecialFolder` enumeration contains `CommonDesktopDirectory`, which is likely what I was asking for. Just too late ;) – OregonGhost Jun 15 '10 at 16:05

5 Answers5

2

I think you have to use the SHGetSpecialFolderPath API, since there is no enum value for "CommonDesktopDirectory". You can't explicitly use the value of CSIDL_COMMON_DESKTOPDIRECTORY and cast it to Environment.SpecialFolder, because the GetFolderPath method checks that the value is defined in the enum. Here's the code of the GetFolderPath method (from Reflector) :

public static string GetFolderPath(SpecialFolder folder)
{
    if (!Enum.IsDefined(typeof(SpecialFolder), folder))
    {
        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, GetResourceString("Arg_EnumIllegalVal"), new object[] { (int) folder }));
    }
    StringBuilder lpszPath = new StringBuilder(260);
    Win32Native.SHGetFolderPath(IntPtr.Zero, (int) folder, IntPtr.Zero, 0, lpszPath);
    string path = lpszPath.ToString();
    new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path).Demand();
    return path;
}

So you can easily copy and adapt the part that you need...

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • OK, I just wanted to be sure. Now that I had a look at the MSDN docs, there is a note that in Vista and later, you should use KNOWNFOLDERID instead of CLSID values. Does that also apply if my app must run on XP? – OregonGhost Aug 11 '09 at 09:01
  • No, I think it's for Vista only – Thomas Levesque Aug 11 '09 at 09:04
  • I'll likely go with another folder (see my comments to the question), but this is the best answer to the question, so I accepted it. Thanks for your prompt reply. – OregonGhost Aug 11 '09 at 09:22
0

For clarification - By common desktop do you mean C:\Documents and Settings\All Users\Desktop?

If yes, this is an ugly hack -

Dim c As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
Dim comDesktop As String = c.Substring(0, c.LastIndexOf("\")) + "\Desktop"
0

You can use Windows Script Host - WshShell.SpecialFolders

http://msdn.microsoft.com/en-us/library/0ea7b5xe(VS.85).aspx

Bogdan_Ch
  • 3,328
  • 4
  • 23
  • 39
0

First, add a reference to "Windows Script Host Object Model". You'll find this in the COM tab of the "Add References" dialog.

using IWshRuntimeLibrary;

object commonUserDesktop = "AllUsersDesktop";
WshShell shell = new WshShellClass();
string commonPath = shell.SpecialFolders.Item(ref commonUserDesktop).ToString();
Jim
  • 505
  • 3
  • 13
0

Another way (yes it is also ugly and will work probably only on Windows XP, not on Vista) is to read a value from registry

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders , Common Desktop

Bogdan_Ch
  • 3,328
  • 4
  • 23
  • 39
  • This is not only ugly, but a compatibility nightmare. If I remember correctly, it even was only in some CTP version of Windows, but since applications relied on it, it has to be in Windows for decades. – OregonGhost Aug 11 '09 at 09:14