What are the Python 3 os commands to establish “writable data files and C-Drive paths” for a typical Windows 10 Application

前端 未结 1 1606
-上瘾入骨i
-上瘾入骨i 2020-12-21 21:03

What are the Python 3 os commands to establish \"writable data files and C-Drive paths\" for a typical Windows 10 Application. There are several parts to this question:

相关标签:
1条回答
  • 2020-12-21 21:22

    I suggest that you avoid storing files and directories directly in the user's profile folder (i.e. the UserProfile environment variable) or home folder (i.e. "%HomeDrive%%HomePath%"). This differs from the common practice in Unix for a home directory (if we're ignoring the XDG base-directory spec), but when in Redmond, do as the Microsofties do.

    Create a folder that's uniquely named for the application in one or more of the following locations: the local data folder (per-user), the roaming data folder (per-user), or the program data folder (per-machine). Note that these folders are hidden by default since generally users aren't meant to access them directly.

    Use a local data folder for caches. Use a roaming data folder for stateful user data and configuration. Use a program data folder for data and caches that aren't specific to a user. For example, a program like pip could use the program data folder to cache downloaded packages. (In practice, pip caches packages per user, but in principle it could cache per machine.)

    If your application uses a program data folder, make sure the folder grants all users permission to add and modify subfolders and files. If you create the folder lazily, you can add the permissions manually. See this answer for an example of how to modify file security.

    The environment variables for the local, roaming, and program data folders are, respectively, LocalAppData, AppData and ProgramData. In Windows XP the latter is "%AllUsersProfile%\Application Data", and maybe "Application Data" is localized. Generally you shouldn't use these environment variables in an application.

    Since most known/special folders are easily relocatable in Explorer, it's best to ask the shell for the current path by calling SHGetFolderPath or the newer SHGetKnownFolderPath function instead of using environment variables and default locations. You can use ctypes for this if you need to stay within Python's standard library. But it's easier to use PyWin32, which can be pip installed as the "pypiwin32" package.

    Here are some Known Folder GUIDs for data, documents, and media files:

                User                    System
    ProgramData                         FOLDERID_ProgramData
    Local       FOLDERID_LocalAppData
    Roaming     FOLDERID_RoamingAppData
    Desktop     FOLDERID_Desktop        FOLDERID_PublicDesktop
    Documents   FOLDERID_Documents      FOLDERID_PublicDocuments
    Downloads   FOLDERID_Downloads      FOLDERID_PublicDownloads
    Music       FOLDERID_Music          FOLDERID_PublicMusic
    Pictures    FOLDERID_Pictures       FOLDERID_PublicPictures
    Videos      FOLDERID_Videos         FOLDERID_PublicVideos
    

    Here are the corresponding CSIDL constants, except there isn't one for "Downloads":

                User                    System
    ProgramData                         CSIDL_COMMON_APPDATA
    Local       CSIDL_LOCAL_APPDATA
    Roaming     CSIDL_APPDATA
    Desktop     CSIDL_DESKTOP           CSIDL_COMMON_DESKTOPDIRECTORY
    Documents   CSIDL_PERSONAL          CSIDL_COMMON_DOCUMENTS
    Music       CSIDL_MYMUSIC           CSIDL_COMMON_MUSIC
    Pictures    CSIDL_MYPICTURES        CSIDL_COMMON_PICTURES
    Videos      CSIDL_MYVIDEO           CSIDL_COMMON_VIDEO
    

    SHGetKnownFolderPath isn't wrapped by PyWin32. I have another answer that calls it via ctypes. Alternatively, you can use PyWin32 to create a KnownFolderManager instance. For example:

    import pythoncom
    from win32com.shell import shell
    
    kf_mgr = pythoncom.CoCreateInstance(shell.CLSID_KnownFolderManager, None, 
                pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IKnownFolderManager)
    
    downloads_path = kf_mgr.GetFolder(shell.FOLDERID_Downloads).GetPath()
    

    Or call the legacy SHGetFolderPath function with a CSIDL constant. For example:

    from win32com.shell import shell, shellcon
    
    SHGFP_TYPE_CURRENT = 0
    SHGFP_TYPE_DEFAULT = 1
    
    local_data_path = shell.SHGetFolderPath(None, shellcon.CSIDL_LOCAL_APPDATA, 
                        None, SHGFP_TYPE_CURRENT)
    
    0 讨论(0)
提交回复
热议问题