OK, so I'm doing the Vista conversion for my frmaework today. My aim is to get a special folder with high scores and other shared data that different Vista users can all read and write to (when UAC is turned on, which it is by default)
So far I've written the following test code (thanks to GfK for the GetSpecialFolder code):
***Note that I'm compiling this as a non-GUI app so that I can see the print commands in the console window. Do this in the BMax IDE by going to Program/Build Options and making sure that Build GUI App is turned off.***
Here's what I've found out so far, which confirms previous discussion on the topic:
Note that you need to have set folder options to view Hidden and System files otherwise you won't see the Application Data folder on the C drive.
- Log on as a Standard or Admin user. We'll call this User 1.
- Run the code. The code does this:
.....Creates a sub-folder in CSIDL_COMMON_APPDATA in code.
.....Creates a text file in that subfolder in code and writes some text into it.
- Log on as another user (Standard or Admin). We'll call this User 2.
- Go into the new subfolder and open the text file - note how you can read it fine.
- Type some more text and then save it. Note how it will not save! This is because you don't have write permissions to anything under the sub-folder created by User 1!
- Note that you can delete the file however, try it now. Weird - I'd call "deleting" a form or "writing".
- Now run the same code which creates the folder and file. Note how it doesn't say it created a new folder (makes sense) and how it says it successfully creates the text file. BUT look in the folder where you previously deleted the text file. It's not there! That's because the code was unable to write to that subfolder because it still belongs to User1 and thus it has "Virtualised" the text file in: Users\User2\AppData\Local\VirtualStore\ProgramData\GreyAlienGames\MyGames. This is what Vista does so that the app doesn't crash. Problem is that the file is in totally the wrong place for games which may want to share common information like high scores with other users (family members).
So far I've written the following test code (thanks to GfK for the GetSpecialFolder code):
Strict Extern "Win32" Function SHGetSpecialFolderLocation(hwndOwner, nFolder, pIdl:Byte Ptr) Function SHGetPathFromIDList( pidList ,lpBuffer:Byte Ptr) End Extern Const CSIDL_DESKTOP = $0 Const CSIDL_INTERNET = $1 Const CSIDL_PROGRAMS = $2 Const CSIDL_CONTROLS = $3 Const CSIDL_PRINTERS = $4 Const CSIDL_PERSONAL = $5 Const CSIDL_FAVORITES = $6 Const CSIDL_STARTUP = $7 Const CSIDL_RECENT = $8 Const CSIDL_SENDTO = $9 Const CSIDL_BITBUCKET = $A Const CSIDL_STARTMENU = $B Const CSIDL_DESKTOPDIRECTORY = $10 Const CSIDL_DRIVES = $11 Const CSIDL_NETWORK = $12 Const CSIDL_NETHOOD = $13 Const CSIDL_FONTS = $14 Const CSIDL_TEMPLATES = $15 Const CSIDL_COMMON_STARTMENU = $16 Const CSIDL_COMMON_PROGRAMS = $17 Const CSIDL_COMMON_STARTUP = $18 Const CSIDL_COMMON_DESKTOPDIRECTORY = $19 Const CSIDL_APPDATA = $1A Const CSIDL_PRINTHOOD = $1B Const CSIDL_LOCAL_APPDATA = $1C Const CSIDL_ALTSTARTUP = $1D Const CSIDL_COMMON_ALTSTARTUP = $1E Const CSIDL_COMMON_FAVORITES = $1F Const CSIDL_INTERNET_CACHE = $20 Const CSIDL_COOKIES = $21 Const CSIDL_HISTORY = $22 Const CSIDL_COMMON_APPDATA = $23 Function GetSpecialFolder:String(folder_id) Local idl:TBank = CreateBank (8) Local pathbank:TBank = CreateBank (260) If SHGetSpecialFolderLocation(0,folder_id,BankBuf(idl)) = 0 SHGetPathFromIDList PeekInt( idl,0), BankBuf(pathbank) Return String.FromCString(pathbank.Buf()) + "" EndIf End Function 'Get the correct path Local path$ = GetSpecialFolder(CSIDL_COMMON_APPDATA)+"Grey Alien Games\My Game" Print path 'If the path does not exist, create it. If ReadDir(path) = 0 Then Print "Folder Created="+CreateDir(path,True) 'create subfolders EndIf Local f:TStream = WriteStream(path+"test.txt") If f Then Print "Text File Created" WriteString(f,"testing123") CloseStream(f) EndIf While Not KeyHit(Key_Escape) Wend
***Note that I'm compiling this as a non-GUI app so that I can see the print commands in the console window. Do this in the BMax IDE by going to Program/Build Options and making sure that Build GUI App is turned off.***
Here's what I've found out so far, which confirms previous discussion on the topic:
Note that you need to have set folder options to view Hidden and System files otherwise you won't see the Application Data folder on the C drive.
- Log on as a Standard or Admin user. We'll call this User 1.
- Run the code. The code does this:
.....Creates a sub-folder in CSIDL_COMMON_APPDATA in code.
.....Creates a text file in that subfolder in code and writes some text into it.
- Log on as another user (Standard or Admin). We'll call this User 2.
- Go into the new subfolder and open the text file - note how you can read it fine.
- Type some more text and then save it. Note how it will not save! This is because you don't have write permissions to anything under the sub-folder created by User 1!
- Note that you can delete the file however, try it now. Weird - I'd call "deleting" a form or "writing".
- Now run the same code which creates the folder and file. Note how it doesn't say it created a new folder (makes sense) and how it says it successfully creates the text file. BUT look in the folder where you previously deleted the text file. It's not there! That's because the code was unable to write to that subfolder because it still belongs to User1 and thus it has "Virtualised" the text file in: Users\User2\AppData\Local\VirtualStore\ProgramData\GreyAlienGames\MyGames. This is what Vista does so that the app doesn't crash. Problem is that the file is in totally the wrong place for games which may want to share common information like high scores with other users (family members).