sinistlor Posted September 21, 2009 Share Posted September 21, 2009 (edited) I am attempting to create a portable desktop. I want the script to replace the user's desktop suddenly with a custom folder they can carry around on a thumb drive. The reason being that I know my users are going to be lazy and I want them to be able to just store files on the desktop but be able to carry those files around with them. The Microsoft powertoy TweakUI changes where the special folder location of the desktop points to (once you make the change in TweakUI, one simply has to send a refresh to the desktop to have the change go live). My question is specifically how can I make AutoIt do exactly the same thing? I am totally new to scripting and especially new to using DLL's so I know very little about the windows shell or structures or pointers so please help me out! I know I can accomplish what I want to do by simply changing the registry values indicating the desktop location and then restart explorer.exe but this is crude and ungraceful. I think I have a general framework for what must happen. I think I am using the shell32.dll functions ILCreateFromPath and SHParseDisplayName to create the thing I need to pass to the 0x00020000 eventID of the SHChangeNotify function. I'm not sure if I need to add some registry changing function as well? This is what I have so far. As far as I can tell, the only part of this that works is the part that sends a simple refresh to the desktop. Please be careful running the following code as it is dysfunctional and may cause explorer to hang! #include-once #include <Constants.au3> DllOpen("shell32.dll") ;Create pidl for old desktop $OldDesktop = "C:\Documents and Settings\Administrator\Desktop" $oldppidl = DllCall("shell32.dll", "ptr", "ILCreateFromPath", "wstr", $OldDesktop) $structureToMake = "int_ptr pbc;int_ptr ppidl;uint sfgaoIn;uint psfgaoOut" $oldpdn = DllStructCreate($structureToMake) DllStructSetData($oldpdn,"pbc",0) DllStructSetData($oldpdn,"ppidl",$oldppidl) DllStructSetData($oldpdn,"sfgaoIn",0) DllStructSetData($oldpdn,"psfgaoOut",0) $oldret = DllCall("shell32.dll", "int", "SHParseDisplayname", "wstr", $OldDesktop, "ptr", DllStructGetData($oldpdn,"pbc"), "ptr", DllStructGetData($oldpdn,"ppidl"), "int", DllStructGetData($oldpdn,"sfgaoIn"), "ptr", DllStructGetData($oldpdn,"psfgaoOut")) ;Create pidl for new desktop $NewDesktop = "E:\PortableDesktop" $newppidl = DllCall("shell32.dll", "ptr", "ILCreateFromPath", "wstr", $NewDesktop) $newpdn = DllStructCreate($structureToMake) DllStructSetData($newpdn,"pbc",0) DllStructSetData($newpdn,"ppidl",$newppidl) DllStructSetData($newpdn,"sfgaoIn",0) DllStructSetData($newpdn,"psfgaoOut",0) $newret = DllCall("shell32.dll", "int", "SHParseDisplayname", "wstr", $NewDesktop, "ptr", DllStructGetData($newpdn,"pbc"), "ptr", DllStructGetData($newpdn,"ppidl"), "int", DllStructGetData($newpdn,"sfgaoIn"), "ptr", DllStructGetData($newpdn,"psfgaoOut")) ;Notify the shell to change the desktop folder. This is attempting to do what TweakUI does DllCall("shell32.dll", "none", "SHChangeNotify", "long", 0x00020000, "uint", 0x1000, "ptr", $oldret, "ptr", $newret) ;Send simple refresh to desktop. (Like hitting F5) DllCall("shell32.dll", "none", "SHChangeNotify", "long", 0x8000000, "uint", 0x1000, "ptr", 0, "ptr", 0) DllClose("shell32.dll") Ok as a clue, I believe this C# code does what I want. I am not familiar with C# and so this is like hieroglyphics to me. I did not write this, I found it on the web elsewhere: SHChangeNotify with SHCNE_RENAMEFOLDER doing this. 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); } Edited September 21, 2009 by sinistlor Link to comment Share on other sites More sharing options...
jvanegmond Posted September 21, 2009 Share Posted September 21, 2009 There has been posted something like this before:http://www.autoitscript.com/forum/index.php?showtopic=84641http://www.autoitscript.com/forum/index.php?showtopic=8781http://www.autoitscript.com/forum/index.php?showtopic=51122http://www.autoitscript.com/forum/index.php?showtopic=49635&mode=threaded&pid=374329 github.com/jvanegmond Link to comment Share on other sites More sharing options...
sinistlor Posted September 21, 2009 Author Share Posted September 21, 2009 There has been posted something like this before: http://www.autoitscript.com/forum/index.php?showtopic=84641 http://www.autoitscript.com/forum/index.php?showtopic=8781 http://www.autoitscript.com/forum/index.php?showtopic=51122 http://www.autoitscript.com/forum/index.php?showtopic=49635&mode=threaded&pid=374329 Thank you for the response! I checked out all those links and they all seem to have the same issue. F5-style refresh is not enough! I've already figured out how to send the F5-style refresh, which from reading those posts above seems to still be an unsolved issue for some people so I'll include how to do that right here: ;Send simple refresh to desktop (Like hitting F5 on desktop) DllOpen("shell32.dll") DllCall("shell32.dll", "none", "SHChangeNotify", "long", 0x8000000, "uint", 0x1000, "ptr", 0, "ptr", 0) DllClose("shell32.dll") Let's solve this once and for all, for all those people who wanna change the user's desktop environment and don't wanna kill explorer.exe! I know we can figure this out. Link to comment Share on other sites More sharing options...
jvanegmond Posted September 21, 2009 Share Posted September 21, 2009 Doing a F5 style refresh is not all that the pages describe. Especially the first topic described a whole range of methods to refresh the desktop. github.com/jvanegmond Link to comment Share on other sites More sharing options...
sinistlor Posted September 21, 2009 Author Share Posted September 21, 2009 Doing a F5 style refresh is not all that the pages describe. Especially the first topic described a whole range of methods to refresh the desktop.The first post appears as though it never was solved. That poster had the same issue where it seemed like restarting explorer was the only answer. But I know it is possible to change the desktop folder easily because TweakUI does it perfectly (only requiring an additional F5-style send, which again is not a problem). Though the poster said none of the solutions worked for them, I will go ahead and try them myself just to make sure. Link to comment Share on other sites More sharing options...
jvanegmond Posted September 21, 2009 Share Posted September 21, 2009 That's a very smart thing to do. You're not trying the same thing as the OP, so one of the posted solutions that have not worked for him may work for you. Good luck. github.com/jvanegmond Link to comment Share on other sites More sharing options...
sinistlor Posted September 26, 2009 Author Share Posted September 26, 2009 (edited) That's a very smart thing to do. You're not trying the same thing as the OP, so one of the posted solutions that have not worked for him may work for you. Good luck.So I gave up. I am just going to kill explorer to refresh the desktop location. I guess what I want to do is beyond the scope of AutoIt. Thanks anyway. Edited September 26, 2009 by sinistlor Link to comment Share on other sites More sharing options...
jvanegmond Posted September 27, 2009 Share Posted September 27, 2009 The C# example in the first post can probably be translated into AutoIt.. It's just a lot of work, I guess. 8) github.com/jvanegmond Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now