Older Version
Newer Version
Alyce
Feb 21, 2012
Safe Directories for File Writing
-Safe Directories for File Writing | UAC and Files | Safe Directories | Special Variables | Trailing Backslash in DefaultDir$ | My Docments | Trailing Backslash | Temporary Files and Folders
For an eBook or printed book on using the API with Liberty BASIC, see:
APIs for Liberty BASIC
UAC and Files
User Account Control in versions of Windows starting with Windows Vista prohibits programs from writing files to many disk locations unless the program is run "as administrator". The reason for this restriction is as follows, quoted from the Wikidpedia article:Safe Directories
Do not attempt to write files in the folder from which your program is running. The "Program Files" folder is not available for normal file writing operations and attempts to write files there will generate errors.Instead, write files to the user's "My Documents" folder, temporary folder, or application data folder.
Special Variables
Applications write data to a user's data folder. Application data includes information needed by the program, such as data files and initialization files.The following quote from the Liberty BASIC helpfile explains how to use the special variables DefaultDir$ (user's data) and StartupDir$ (installation folder)
- As a Liberty BASIC programmer you may sometimes need to know the location of the Liberty BASIC application and also the location of User Data . To make this easy, Liberty BASIC programs have access to two global variables.
Trailing Backslash in DefaultDir$
The special variable StartupDir$ points to the folder from which a Liberty BASIC program is running. Do not use it to write files. StartupDir$ includes a trailing backslash.To access the user's data folder, write files to DefaultDir$. The special variable DefaultDir$ does not include a trailing backslash. In your code, check for a trailing backslash and add it if it doesn't exist, as in the following example.
print DefaultDir$ 'no trailing backslash
print StartupDir$ 'has trailing backslash
if right$(DefaultDir$,1)<>"\" then
DefaultDir$=DefaultDir$+"\"
end if
print DefaultDir$
'write a file:
open DefaultDir$+"mytestfile.txt" for output as #f
print #f, "Test"
close #f
My Docments
Windows has long included a folder called "My Documents" which is meant to be the location where users create and save files. You can retrieve this location with the API from shell32.dll called SHGetSpecialFolderLocation , using a value of 5 for the desired folder. This is the value assigned to the "My Documents" folder. An additional API is required to retrieve the folder name. It is SHGetPathFromIDListA . Both API calls are wrapped in a function:Function GetSpecialfolder$(CSIDL)
'CSIDL.PERSONAL = 5 : My Docments = GetSpecialfolder$(CSIDL.PERSONAL)
struct IDL,cb As Long, abID As short
calldll #shell32, "SHGetSpecialFolderLocation",_
0 as long, CSIDL as long, IDL as struct, ret as long
if ret=0 then
Path$ = Space$(512)
id=IDL.cb.struct
calldll #shell32, "SHGetPathFromIDListA",id as long, Path$ as ptr, ret as long
GetSpecialfolder$ = Left$(Path$, InStr(Path$, Chr$(0)) - 1)
else
GetSpecialfolder$ = "Error"
end if
End Function
Trailing Backslash
The folder name for "My Docments" does not include a trailing backslash. To assure that the backslash is included in the folder name, check for it and append it if it is not there. Here is a demo that retrieves the location of "My Docments", adds a trailing backslash, and writes a test file there.CSIDL.PERSONAL = 5 'My Docments Folder
myDocuments$ = GetSpecialfolder$(CSIDL.PERSONAL)
print "My Documents folder location is: "
print myDocuments$
if right$(myDocuments$,1)<>"\" then
myDocuments$=myDocuments$+"\"
end if
open myDocuments$ + "testxxxx.txt" for output as #f
print #f, "Test"
close #f
end
Function GetSpecialfolder$(CSIDL)
struct IDL,cb As Long, abID As short
calldll #shell32, "SHGetSpecialFolderLocation",_
0 as long, CSIDL as long, IDL as struct, ret as long
if ret=0 then
Path$ = Space$(512)
id=IDL.cb.struct
calldll #shell32, "SHGetPathFromIDListA",id as long, Path$ as ptr, ret as long
GetSpecialfolder$ = Left$(Path$, InStr(Path$, Chr$(0)) - 1)
else
GetSpecialfolder$ = "Error"
end if
End Function
Temporary Files and Folders
To assure that your program writes temporary files to the Windows folder reserved for temporary files, use GetTempPathA and GetTempFileNameA. These functions are explained here:GetTempPathA
GetTempFileNameA
yourPrefix$ = "xxx" 'prefix you choose
TempFileName$ = GetTempFileName$(yourPrefix$)
print "Temporary File Name is ";TempFileName$
end
function GetTempFileName$(prefix$)
TempPath$=GetTempPath$()
TempFile$ = space$(256)+chr$(0)
calldll #kernel32, "GetTempFileNameA",_
TempPath$ as ptr,_ 'directory for temp file
prefix$ as ptr,_ 'desired prefix for temp filename
0 as ulong,_ '0=file created,nonzero=you must create file
TempFile$ as ptr,_ 'string buffer to hold qualified path and filename
result as ulong 'nonzero=success
end function
Function GetTempPath$()
CallDLL #kernel32, "GetTempPathA",_
0 as long,_
_NULL as long,_
length as long
buf$ = space$(length)
CallDLL #kernel32, "GetTempPathA",_
length as long,_
buf$ as ptr,_
ret as long
GetTempPath$ = buf$
End Function
Safe Directories for File Writing | UAC and Files | Safe Directories | Special Variables | Trailing Backslash in DefaultDir$ | My Docments | Trailing Backslash | Temporary Files and Folders