tamo wrote: ↑
12 Jul 2019, 08:42
Just adding "\" sometimes works, sometimes fails.
I finally got to the bottom of this.
So the first time an application opens a FileSelectFile, Windows saves the starting directory parameter to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\FirstFolder
Then, if your app opens a FileSelectFile with the above starting directory, Windows will instead give you the most recent path that the user previously selected, which is stored in HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRU
I am able to reproduce this behaviour in ahk, so it appears to function exactly as Windows describes in the documentation.
Appending "\" or other things like "\\\" or ".\" to the starting directory alone won't work because it can't always circumvent this logic, regardless of how clever you try to be, because there will always be a possible scenario where the application could select the registry's "FirstFolder" value, since the value gets stored between app launches. i.e even your app's very first FileSelectFile starting directory will be compared to the registry value from the previous run, so it doesn't "start fresh" each time, and so you can't know for sure what the FirstFolder value is without keeping a copy between each time the application runs.
Therefore the only ways to overcome it require read/write/deleting external files on disk, which is quite disappointing, but appears to be necessary to get around this problem.
The first time your app opens a FileSelectFile, store your own private copy of the starting directory on disk. Every time you call FileSelectFile, check if it the starting directory matches the one you saved to disk, and if it does, append "\" to it.
Same as above, but instead of reading it from your own private copy, read it straight from the registry. Iterate through each value inside the FirstFolder regkey and find the one which contains the full path to your script's executable, and that should be the one for your app.
Same as above, but just delete your app's registry value instead of checking to see if it matches.
If you are feeling lazy, just delete the entire "FirstFolder" key every time you use FileSelectFile. This will delete "FirstFolder" for all apps on the system. But who cares? The behaviour is retarded and shouldn't exist in the first place
However it won't fix it properly for other apps because they could open and close their own dialogues and then the problem returns for those apps until your app happens to delete the key again.
I was leaning towards solution 3 because it's quite easy, but solution 1 should be more reliable since you have your own copy of FirstFolder and aren't relying on assumptions about Windows registry. eg. different versions of Windows or languages might change the formatting of the key value, or antivirus software might block you from deleting reg keys altogether, or a future version of Windows might change the regkey path.
So I will probably go with solution 1.
If anyone can figure out a clever way to fudge the FileSelectFile starting directory without relying on any disk read/write/delete operations, I'd love to hear it!
Note: I am aware that you can pass FileSelectFile a file path instead of a directory, but that's not quite good enough for me as I want the dialogue's text input to start off blank (especially when the user just wants to open a file; for saving a file, pre-inputting something like "untitled.ext" might be acceptable). i.e I want a complete solution, not half-measure, and it has to be 100% reliable!
edit: and I've just realised Solution 1 won't be 100% reliable because the user could move the app to another location on disk, which would then get its own reg value, which might not match your private value that you previously stored. So you would need to store a copy of the previous A_ScriptDir and if it changes then do what exactly? What if the user had moved it to that location before, then it might still be wrong since we can't assume that it started fresh. Maybe interacting with the registry might be necessary after all...
edit2: I will probably go with solution 1 but append to file a series of records "A_ScriptDir has FirstFolder" so we know which location has which firstfolder. Essentially making our own copy of what Windows itself stores in the registry so we can avoid having to interact with the registry and whatever problems that might entail.