能否让Python可执行文件获取快捷方式所在目录作为工作目录?
实现带自定义工作目录的快捷方式(cxFreeze + MSI)
完全可行!用cxFreeze的MSI打包功能就能直接实现,不用额外折腾工具。下面分两种常见场景给你具体方案:
场景1:固定快捷位置(桌面/开始菜单)
如果只是希望安装时创建的快捷方式(比如桌面、开始菜单文件夹)所在目录作为程序的工作目录,直接在setup.py里配置快捷方式的working_dir即可,这是最省心的方法。
修改setup.py配置
首先,在你的打包脚本里添加快捷方式的定义,重点是shortcut_table中的working_dir参数——用Windows Installer的内置属性来指向快捷方式所在的目录:
import sys from cx_Freeze import setup, Executable # 定义可执行文件 base = "Win32GUI" if sys.platform == "win32" else None # GUI程序用这个,控制台程序可以去掉 main_exe = Executable( script="你的主脚本.py", base=base, target_name="ExcelToPDF.exe" # 生成的EXE文件名 ) # 打包配置 setup( name="Excel转PDF工具", version="1.0", description="批量将Excel文件转为PDF报告", executables=[main_exe], options={ "bdist_msi": { "add_to_path": False, # 配置快捷方式表 "shortcut_table": [ # 桌面快捷方式 { "directory": "DesktopFolder", # 把快捷方式放在桌面 "name": "Excel转PDF工具", "target": "[TARGETDIR]ExcelToPDF.exe", # 指向安装目录里的EXE "working_dir": "[DesktopFolder]", # 工作目录设为桌面(快捷方式所在目录) "icon": "your_icon.ico" # 可选:给快捷方式加个图标 }, # 开始菜单快捷方式 { "directory": "ProgramMenuFolder\\Excel转PDF工具", # 开始菜单里的专属文件夹 "name": "Excel转PDF工具", "target": "[TARGETDIR]ExcelToPDF.exe", "working_dir": "[ProgramMenuFolder]Excel转PDF工具", # 工作目录设为开始菜单的工具文件夹 "icon": "your_icon.ico" } ] }, # 可选:如果是GUI程序,隐藏控制台窗口 "build_exe": { "include_files": [] # 这里可以添加依赖的资源文件,比如模板、图标等 } } )
这里的[DesktopFolder]和[ProgramMenuFolder]是Windows Installer的内置变量,会自动解析为系统对应的桌面/开始菜单路径。打包后生成的快捷方式,其“起始位置”会被设置为自身所在的目录,用户点击时,程序的工作目录就是这个路径。
在Python脚本中使用工作目录
不需要额外传参!Python的os.getcwd()或pathlib.Path.cwd()会直接返回快捷方式设置的工作目录,你直接用它来遍历文件就行:
import os from pathlib import Path # 获取当前工作目录(也就是快捷方式所在的目录) work_dir = Path.cwd() # 遍历目录下的所有Excel文件 for excel_file in work_dir.glob("*.xlsx"): print(f"正在处理:{excel_file.name}") # 你的PDF生成逻辑...
场景2:支持任意位置的快捷方式
如果希望用户可以把快捷方式复制到任意文件夹,点击时程序的工作目录自动变成该文件夹的路径,就需要在脚本里解析快捷方式自身的位置。这时候要用到Windows的COM API来读取快捷文件的信息。
修改Python脚本
添加一个函数来获取快捷方式的所在目录,同时处理直接运行EXE的情况:
import os import sys from pathlib import Path import win32com.client def get_working_dir_from_shortcut(): shell = win32com.client.Dispatch("WScript.Shell") try: # 尝试解析当前进程的启动快捷方式 shortcut = shell.CreateShortCut(sys.argv[0]) # 返回快捷方式文件所在的目录 return Path(shortcut.FullName).parent except Exception: # 如果不是从快捷方式启动(比如直接双击EXE),返回当前工作目录 return Path.cwd() # 设置程序的工作目录 work_dir = get_working_dir_from_shortcut() os.chdir(work_dir) # 后续的Excel处理逻辑...
更新setup.py打包配置
因为用到了win32com.client,需要把pywin32模块包含进安装包:
在setup()的options里添加build_exe的配置:
"build_exe": { "includes": ["win32com.client"], "packages": ["win32com"], "include_files": [] }
注意事项
- 测试时,记得先卸载之前的旧版本MSI,避免配置冲突。
- 如果是GUI程序,一定要设置
base="Win32GUI",不然运行时会弹出多余的控制台窗口。 - 如果你的程序依赖其他资源文件(比如PDF模板、图标),要在
build_exe的include_files里指定,确保它们被打包到安装目录。
内容的提问来源于stack exchange,提问作者Usagi




