Saving Files Under Windows

achrist at easystreet.com achrist at easystreet.com
Fri Jun 13 17:08:53 EDT 2003


Just for the sake of discussion, and because this is a Python 
newsgroup, here's my code based on comments here, etc:

The two functions for clients to call are GetSharedOutputDir()
and GetUserOutputDir().  If you are running on a pre-Win2K 
OS, you've got to create a function GetRegistryAppDataDir() to
return wherever the installer or equivalent thought the data
should go.  Presumably this will work ok, because if the user
moves the data, they will also change the registry setting (maybe).
For win2K or newer, we read the Shell Folders and go from there.

BTW, notice how good MS is about making "CurrentVersion" one word
and "Shell Folders" two words, just to brighten up our day with a
little variety.  

Comments very welcome,


Al


# -------------------Code Follows --------------------------  

import os
import os.path
import win32api
import win32con
import whatever.else.you.need


def GetSharedOutputDir(appName="MyApp"):
    if OsIsPreWin2K():
        return GetAppSharedDataSubdir()
    else:
        return GetRegistrySharedDataSubdir(appName)

def GetUserOutputDir(appName="MyApp", userName=""):
    if not userName:
        try:
            userName = win32api.GetUserName()
        except:
            userName = ""
    if userName:
        if OsIsPreWin2K():
            return GetAppUserDataSubdir(userName, appName)
        else:
            return GetRegistryUserDataSubdir(userName, appName)
    else:
        return GetSharedOutputDir(appName)

#================================================================
# None of the functions below here should be called by the client
#================================================================

def OsIsPreWin2K():
    try:
        versionInfo = win32api.GetVersionEx()
        return versionInfo[0] <= 4
    except:
        return True

def GetAppSharedDataSubdir():
    try:
        # Installer can create application data path
        # Smart user can change this registry value to move their data
        # Write Function GetRegistryAppDataDir() to run on pre-Win2k
        dirName = GetRegistryAppDataDir()
        if dirName:
            if not os.path.exists(dirName):
                os.makedirs(dirName)
            if not os.path.isdir(dirName):
                return os.getcwd()
        else:
            return os.getcwd()
    except:
        return os.getcwd()

def OpenRegistryKey( registrySection, regKeys ):
    if regKeys:
        theKey = win32api.RegOpenKeyEx(registrySection, regKeys[0],
                                0,   # Reserved, Must Be Zero
                                win32con.KEY_READ   # Privileges
Requested
                                )
        for subKey in regKeys[1:]:
            theKey = win32api.RegOpenKeyEx(theKey, subKey,
                                0,   # Reserved, Must Be Zero
                                win32con.KEY_READ   # Privileges
Requested
                                )
        return theKey
    else:
        return None

def GetRegistrySharedDataSubdir(appName):
    try:
        registryKeyHandle = OpenRegistryKey(
                                    win32con.HKEY_LOCAL_MACHINE,
                                    [   "Software",
                                        "Microsoft",
                                        "Windows" ,
                                        "CurrentVersion",
                                        "Explorer",
                                        "Shell Folders" ]
                                )
        (valueObject, valueType ) = win32api.RegQueryValueEx(
                                         registryKeyHandle,
                                         "Common AppData"
                                        )
        if 1 == valueType:
            answer = valueObject
        else:
            answer = `valueObject`
        if not answer.strip():
            return GetStandardWindowsSharedDataDirectory(appName)
        else:
            answer = os.path.join( answer, appName )
        if not os.path.exists(answer):
            os.makedirs(answer)
        return answer
    except:
        return GetStandardWindowsSharedDataDirectory(appName)

def GetStandardWindowsSharedDataDirectory(appName):
    try:
        answer = "C:\\Documents and Settings"
        answer = os.path.join( answer, "\\All Users" )
        answer = os.path.join( answer, "\\Application Data")
        answer = os.path.join( answer, appName )
        if not os.path.exists(answer):
            os.makedirs(answer)
        return answer
    except:
        return os.getcwd()

def GetAppUserDataSubdir(userName, appName):
    try:
        # Installer can create application data path
        # Smart user can change this registry value to move their data
        # Write Function GetRegistryAppDataDir() to run on pre-Win2k
        dirName = GetRegistryAppDataDir()
        if not dirName:
            dirName = os.getcwd()
        if dirName:
            if not os.path.exists(dirName):
                os.makedirs(dirName)
            if not os.path.isdir(dirName):
                dirName = os.getcwd()
            dirName = os.path.join(dirName, userName)
            if not os.path.exists(dirName):
                os.makedirs(dirName)
            if not os.path.isdir(dirName):
                dirName = os.getcwd()
            return dirName
        else:
            return os.getcwd()
    except:
        return os.getcwd()

def GetRegistryUserDataSubdir(userName, appName):
    try:
        dirName = GetRegistryUserDataValue("AppData")
        if not dirName:
            dirName = GetRegistryUserDataValue("Personal")
        if not dirName:
            dirName = GetRegistryUserDataValue("Local AppData")
        if not dirName.strip():
            return GetStandardWindowsUserDataDirectory(appName,
userName)
        else:
            dirName = os.path.join( dirName, appName )
        if not os.path.exists(dirName):
            os.makedirs(dirName)
        return dirName
    except:
        return GetStandardWindowsUserDataDirectory(appName, userName)

def GetRegistryUserDataValue(valueName):
    try:
        registryKeyHandle = OpenRegistryKey(
                                    win32con.HKEY_CURRENT_USER,
                                    [   "Software",
                                        "Microsoft",
                                        "Windows" ,
                                        "CurrentVersion",
                                        "Explorer",
                                        "Shell Folders" ]
                                )
        (valueObject, valueType ) = win32api.RegQueryValueEx(
                                         registryKeyHandle,
                                         valueName
                                        )
        if 1 == valueType:
            answer = valueObject
        else:
            answer = `valueObject`
        if not os.path.exists(answer):
            os.makedirs(answer)
        return answer
    except:
        return ""

def GetStandardWindowsUserDataDirectory(appName, userName):
    try:
        answer = "C:\\Documents and Settings"
        answer = os.path.join( answer, userName )
        answer = os.path.join( answer, "\\Application Data")
        answer = os.path.join( answer, appName )
        if not os.path.exists(answer):
            os.makedirs(answer)
        return answer
    except:
        return os.getcwd()




More information about the Python-list mailing list