如何让pywin32适配PyInstaller生成可执行文件?解决属性错误
AttributeError: 'pywintypes.datetime' object has no attribute 'astimezone' When Packing pywin32 Code with PyInstaller I've run into this exact issue before when working with pywin32 and PyInstaller's onefile mode. The error pops up because PyInstaller fails to automatically detect and include some underlying dependencies that pywintypes.datetime relies on for the astimezone method. Here are a few proven fixes to resolve this:
Solution 1: Add Hidden Imports to Your PyInstaller Command
The quickest fix is to explicitly tell PyInstaller to include the missing modules when you run the pack command. Update your打包 command to:
pyinstaller --onefile --console --hidden-import pywintypes --hidden-import win32timezone test.py
This forces PyInstaller to bundle the win32timezone module (which provides the astimezone method for pywintypes.datetime) and ensures all dependencies are present in the executable.
Solution 2: Modify the .spec File
If you prefer more control over the build process using a spec file:
- Generate the spec file if you haven't already:
pyinstaller --onefile --console test.py - Open the generated
test.specfile in a text editor. - Locate the
Analysissection and update thehiddenimportslist to include the required modules:a = Analysis( ['test.py'], pathex=[], binaries=[], datas=[], hiddenimports=['pywintypes', 'win32timezone'], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, ) - Re-build the executable using the spec file:
pyinstaller test.spec
Solution 3: Explicitly Import Dependencies in Your Code
Another way to make PyInstaller detect the missing modules is to add an explicit import in your code. Just add this line at the top of your test.py:
import win32timezone
PyInstaller's dependency scanner will pick up this import and include the necessary modules automatically, eliminating the attribute error.
Solution 4: Adjust Time Conversion Logic (Alternative)
If the above fixes don't work for some reason, you can tweak how you convert the timestamp to a pywintypes.Time object. Using Python's built-in datetime module to mediate the conversion can bypass the issue:
from datetime import datetime import pywintypes, win32file, win32con, ntsecuritycon import os def changeFileCTime(fname, createdNewtime): # Convert timestamp to datetime first, then to pywintypes.Time dt_obj = datetime.fromtimestamp(createdNewtime) wintime = pywintypes.Time(dt_obj) winfile = win32file.CreateFile(fname, ntsecuritycon.FILE_WRITE_ATTRIBUTES, 0, None, win32con.OPEN_EXISTING, 0, None) win32file.SetFileTime(winfile, wintime, None, None) winfile.close() # Rest of your code remains the same
Why This Happens
The root cause is that PyInstaller's automatic dependency detection doesn't always catch all the modules that pywin32's types rely on. The astimezone method for pywintypes.datetime is actually provided by the win32timezone module, which isn't flagged as a required import when scanning your code. By explicitly including it (either via command line, spec file, or code import), you ensure it's bundled with your executable.
内容的提问来源于stack exchange,提问作者gatkkalra

