What are the Python 3 os commands to establish “wr

2019-07-27 02:15发布

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. My Python 3 program creates (multiple) data files as part of it's purpose. When my MSI installer installs into /Programs, my Python executable does not have permission to create and write data files. Thus, the first part of my question is: Do I need to change my Python 3 program to create data files in a specific directory (using the os capabilities) and could you give me an example.

  2. The second part of my question is simply: What os command options can assist me in discovering the windows 10 directories of a general Windows 10 PC (e.g. the home path, the AppData path, etc).

  3. Note that I am cx_Freezing to an MSI installer, so everything must be automated for a typical remote install from a cloud (google drive or GitHub) by the MSI installer, so keep that in mind when answering 1 and 2 above.

Attention: Here is the MSI Installer for this program: New WINDOWS 10 Contact Management Application.

https://drive.google.com/drive/folders/0Bz98wvqqw-1QRUNFcUJLU21yT1k

Thanks in advance for your programming knowledge and experience.

I appreciate your technical assistance and clarification.

1条回答
ら.Afraid
2楼-- · 2019-07-27 03:01

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)
查看更多
登录 后发表回答