I want to get the filepath of the user's profile picture in Windows using Python.
I've found 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
But I don't know how to translate it to Python using ctypes, as the functions used are not documented by the MSDN. I've found this alternative resource, though.
I've also tried to access this folder:
%ProgramData%\Microsoft\User Account Pictures\Guest.bmp
%ProgramData%\Microsoft\User Account Pictures\User.bmp
But there are stored the default profile pictures, not the current ones.
Listing [Python.Docs]: ctypes - A foreign function library for Python.
[Airesoft.UnDoc]: SHGetUserPicturePath (and the referenced SHGetUserPicturePathEx) contains the exact needed info:
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 )
Although the table at the end of the page lists Win 8.1 as the newest version, it also works on Win 10.
Notes:
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)
Output:
e:\Work\Dev\StackOverflow\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.
Related: [SO]: Get user picture.