如何使用 Python 获取用户头像的文件路径?

How to get the filepath of the user's profile picture using Python?

我想使用 Python 在 Windows 中获取用户个人资料图片的文件路径。

我找到了 the following approach in VB6:

Option Explicit
'KERNEL32
Private Declare Function GetVersion Lib "KERNEL32" () As Long
'SHELL32
Private Declare Function SHGetUserPicturePath Lib "SHELL32" Alias "#261" (ByVal pUserOrPicName As Long, ByVal sguppFlags As Long, ByVal pwszPicPath As Long, ByVal picPathLen As Long) As Long
Private Declare Function xp_SHGetUserPicturePath Lib "SHELL32" Alias "#233" (ByVal pUserOrPicName As Long, ByVal sguppFlags As Long, ByVal pwszPicPath As Long) As Long

Private Const SGUPP_CREATEPICTURESDIR = &H80000000

Public Function LoadUserTile() As IPictureDisp
    Dim sPath   As String

    sPath = String$(256, vbNullChar)

    Select Case (GetVersion() And &HFF)
        Case 5
            Call xp_SHGetUserPicturePath(0, SGUPP_CREATEPICTURESDIR, StrPtr(sPath))
        Case 6
            Call SHGetUserPicturePath(0, SGUPP_CREATEPICTURESDIR, StrPtr(sPath), 256)
    End Select

    sPath = Left$(sPath, InStr(1, sPath, vbNullChar) - 1)

    Set LoadUserTile = LoadPicture(sPath)
End Function

但我不知道如何使用 ctypes 将其转换为 Python,因为所使用的函数未在 MSDN 中记录。不过,我找到了 this alternative resource

我也试过访问 this folder:

%ProgramData%\Microsoft\User Account Pictures\Guest.bmp
%ProgramData%\Microsoft\User Account Pictures\User.bmp

但是存储的是默认的个人资料图片,而不是当前的。

使用这个:

import glob
import os
# Please change the <username> to your username
search_dir = "C:\Users\<username>\AppData\Roaming\Microsoft\Windows\AccountPictures\"
files = list(filter(os.path.isfile, glob.glob(search_dir + "*")))
files.sort(key=lambda x: os.path.getmtime(x))

因此,您将有一个 python 列表 files,其中包含按“创建日期”顺序排序的文件列表。您可以使用 files[0]

访问最新的帐户图片

I took some reference from this article

清单[Python.Docs]: ctypes - A foreign function library for Python.

[Airesoft.UnDoc]: SHGetUserPicturePath(以及引用的 SHGetUserPicturePathEx)包含确切需要的信息:

Copies the users account picture to a temporary directory and returns the path or returns various paths relating to user pictures

Syntax

HRESULT WINAPI SHGetUserPicturePath (
    LPCWSTR pwszPicOrUserName,
    DWORD sguppFlags,
    LPWSTR pwszPicPath,
    UINT picPathLen
)

尽管页面末尾的 table 将 Win 8.1 列为最新版本,它也适用于 Win 10.

备注:

  • 不用说,不属于 public API不应该依赖它(可能出于演示/学习目的除外),因为行为可能会改变或可能完全消失。 请勿在生产中使用此代码!

code00.py:

#!/usr/bin/env python

import sys
import ctypes as ct
from ctypes import wintypes as wt


SGUPP_DIRECTORY = 0x01
SGUPP_DEFAULTDIRECTORY = 0x02
SGUPP_CREATEPICTURESDIR = 0x80000000


def main(*argv):
    shell32 = ct.WinDLL("shell32.dll")
    SHGetUserPicturePathW = shell32[261]
    SHGetUserPicturePathW.argtypes = (wt.LPWSTR, wt.DWORD, wt.LPWSTR, wt.UINT)
    SHGetUserPicturePathW.restype = ct.c_long

    buf_len = 0xFF
    buf = ct.create_unicode_buffer(buf_len)
    flags = SGUPP_CREATEPICTURESDIR
    res = SHGetUserPicturePathW(None, flags, buf, buf_len)
    print("    SHGetUserPicturePathW returned {0:016X}\n    Path set to: [{1:s}]".format(res, buf.value))


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")),
                                                    64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

输出:

e:\Work\Dev\Whosebug\q059927534>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 064bit on win32

    SHGetUserPicturePathW returned 0000000000000000
    Path set to: [C:\Users\cfati\AppData\Local\Temp\cfati.bmp]

Done.

相关:[SO]: Get user picture.