I am working on a combination productivity and source/version control app. One of the features i would like to add might sound crazy, but I would like to substitute the User's windows Desktop folder with the project files "Working Directory" That way, until the the software is exited, or the project is closed. The windows desktop, the easiest location to find regardless of what you are doing, will be your project folder (If only I had a magic desk that only showed me stuff I needed when I needed it :)

In windows vista and 7 its easy to accomplish this in explorer, in the properties for special folders like the desktop there is a location tab that allows you to change the folder, it works immediately and very well. With the exception of renaming the folder you set to Desktop, it works exactly how I would like it too.

But I can't seem to find out how to accomplish this programmatically. I have tried changing the "shell folder" HKCU registry entry, and although this works for everything but the literal desktop. I can't seem to get the actual desktop desktop to display the changes.

Anyone have any ideas?

Dani AI

Generated

Short summary and practical guidance (follow-ups to and )

Vista / Windows 7 (recommended)

  • Use the Known Folder API: call SHSetKnownFolderPath for the Desktop KNOWNFOLDERID to change the per-user Desktop location, then notify the shell so Explorer refreshes. Per-user changes normally do not require elevation; changing common (all-users) folders does. (learn.microsoft.com)

XP and older (fallbacks)

  • Older systems use the CSIDL/SHSetFolderPath path (SHSetFolderPath exists on XP and acts as the legacy wrapper to the newer API on Vista+). If you must support XP, prefer SHSetFolderPath where available; otherwise update the User Shell Folders registry entries and then tell the shell about the change. (learn.microsoft.com)

Notifying Explorer and PIDLs

  • Explorer caches namespace state: after changing a known-folder path you must call SHChangeNotify with an appropriate event (for example a rename/change event or an association update) so open Explorer windows pick up the new location. When sending SHCNE_RENAMEFOLDER you’ll normally build PIDLs for the old/new paths with SHParseDisplayName and pass those to SHChangeNotify. (learn.microsoft.com)

Common traps and troubleshooting

  • If XP code “sticks” or you cannot switch back, the usual causes are (1) Explorer caching/namespace semantics for the desktop (user + PublicDesktop are a merged view), (2) not freeing PIDLs returned by SHParseDisplayName, or (3) registry/shell values out of sync. Free PIDLs correctly (CoTaskMemFree / ILFree guidance) and update both the per-user and common paths when relevant; if Explorer still refuses to refresh, a restart of explorer.exe will clear caches. (learn.microsoft.com)

Notes: changing the Desktop location can confuse users and other apps (OneDrive, Folder Redirection, installers). For a less invasive alternative, consider exposing the working directory via a shell shortcut, virtual folder, or a temporary junction rather than remapping the user's Desktop persistently.

I seemed to have found my answer :) But I can only test on Windows 7 and vista because I don't have an XP Machine. Can someone with an XP machine test this snippet for me and tell me if it works.

class Program

    {

        public static class KnownFolder

        {

            public static Guid Desktop = new Guid("B4BFCC3A-DB2C-424C-B029-7FE99A87C641");

        }

 

        [DllImport("shell32.dll")]

        private extern static int SHSetKnownFolderPath(ref Guid folderId, uint flags, IntPtr token, [MarshalAs(UnmanagedType.LPWStr)] string path);

        [DllImport("Shell32.dll")]

        public static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

 

        static void Main(string[] args)

        {

            string newPath = @"path to new desktop folder";

            int flags = 0;

            SHSetKnownFolderPath(ref KnownFolder.Desktop, (uint)flags, IntPtr.Zero, newPath);

            SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);

        }

    }

Ok, it works in VISTA and SEVEN only. XP needs a different api, i found some code that seems to work

Resolved. SHChangeNotify with SHCNE_RENAMEFOLDER doing this. Thanks to all. Here is a source.
1) Define Pinvoke functions:

[DllImport("shell32.dll")]
public static extern Int32 SHParseDisplayName( [MarshalAs(UnmanagedType.LPWStr)] String pszName, 
IntPtr pbc, out IntPtr ppidl, UInt32 sfgaoIn,  out UInt32 psfgaoOut);

[DllImport("Shell32.dll")]
public static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

2) Method to notify system about new desktop folder path:

public static void ApplyNewDesktopPath(string OldDesktop, string NewDesktop)
{
     uint iAttribute;
     IntPtr oldPidl;
     IntPtr newPidl;
     SHParseDisplayName(OldDesktop, IntPtr.Zero, out oldPidl, 0, out iAttribute);
     SHParseDisplayName(NewDesktop, IntPtr.Zero, out newPidl, 0, out iAttribute);
     SHChangeNotify(0x00020000, 0x1000, oldPidl, newPidl);
}

3) Refresh desktop to show new content:

public static void RefreshDesktop()
{
    SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);
}

it will let me change the desktop folder, but won't let me change it back to the regular desktop. I have to kill explorer to get the refresh.

i think it might have to do with not releasing the pidls properly. i'm tring to figure it out, any ideas would be appreciated.

commented: :) useful! +11

OK, turns out that the problem is more to do with the desktop being the root of the namespace yadda yadda relative to the current desktop. It involves a bunch of relative paths, But I found another way.

I still have much testing to do to get the XP compatibility reliable enough to use, once I get it settled. I will post some snippets or a CodeProject article.

If anyone has any further information on this subject. Please do post it.

Did your solution work for this? If so, do you have some code you can post? Thanks very much in advance.

Did your solution work for this? If so, do you have some code you can post? Thanks very much in advance.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.