Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中将SHGetFileInfo与shgfiu PIDL一起使用_Python_Windows_Shell_Ctypes_Activepython - Fatal编程技术网

如何在python中将SHGetFileInfo与shgfiu PIDL一起使用

如何在python中将SHGetFileInfo与shgfiu PIDL一起使用,python,windows,shell,ctypes,activepython,Python,Windows,Shell,Ctypes,Activepython,我正在尝试使用SHGetFileInfo检索文件信息(特别是关于图标的信息)。实际上,我没有文件的完整路径,我只有pidl 下面的代码返回(0L,(0,0,0,,,''),我的问题是为什么 from win32com.shell import shell, shellcon def get_info(): desktop = shell.SHGetDesktopFolder() eaten, desktop_pidl, attr = desktop.ParseDisplayNam

我正在尝试使用SHGetFileInfo检索文件信息(特别是关于图标的信息)。实际上,我没有文件的完整路径,我只有pidl

下面的代码返回
(0L,(0,0,0,,,'')
,我的问题是为什么

from win32com.shell import shell, shellcon
def get_info():
    desktop = shell.SHGetDesktopFolder()
    eaten, desktop_pidl, attr = desktop.ParseDisplayName(None, None, r"C:\Users\Ella\Desktop")
    return shell.SHGetFileInfo(desktop_pidl, 0, shellcon.SHGFI_PIDL | shellcon.SHGFI_SYSICONINDEX | shellcon.SHGFI_ICON | shellcon.SHGFI_DISPLAYNAME)
另一方面,由于某些原因,下面的代码确实有效(它使用完整路径而不是pidl):

谢谢

您在中发现了一个bug。如果在标志中设置了
SHGFI_PIDL
,它将调用
PyObject_AsPIDL
,并将结果存储到
PIDL_或_name
,但它错误地将
name
传递到
SHGetFileInfo
,在这种情况下,这是初始的
NULL
值。有关更多详细信息,请参见下文


您询问了如何在
shell32上设置断点!SHGetFileInfoW
。没有简单的答案。相反,请允许我分享一下我为测试这一点所做的概述。希望这至少能让你开始

测试环境:

  • 64位Windows 7 SP1(6.1.7601)
  • (确保已安装调试程序)
  • (和调试文件)
  • (hg.exe,非龟甲)
设置shell环境

“C:\Program Files\Microsoft SDK\Windows\v7.1\Bin\SetEnv.Cmd”
设置MSSdk=%WindowsSDKDir%
设置SYMDIR=C:\Symbols
设置SYMSRV=http://msdl.microsoft.com/download/symbols    
设置\u NT\u SYMBOL\u PATH=symsrv*symsrv.dll*%SYMDIR%*%symsrv%
路径C:\Program Files\Windows调试工具(x64);%路径%
路径C:\Program Files\Mercurial;%路径%
创建一个Python虚拟环境

py-3.4-m venv——符号链接测试
venv
不链接.pdb文件,因此在for循环中手动获取这些文件

set PYDIR=“%ProgramW6432%\Python34”
设置CMD=mklink“测试\脚本\%~nxf”“%f”
对于(*.pdb)中的/R%PYDIR%%f,执行@%CMD%
激活虚拟环境

test\Scripts\activate
克隆PyWin32 repo。构建并安装版本219

设置HGSRV=http://pywin32.hg.sourceforge.net
hg克隆%HGSRV%/hgroot/pywin32/pywin32
cd pywin32
hg-up b219
我编辑了setup.py以注释掉与建筑相关的所有内容
win32com.mapi
。我的设置甚至没有所需的标题, 当我得到它们时,在建造 WIN64的扩展

构建并安装软件包

python setup3.py安装
在控制台调试器cdb.exe下运行Python

cdb-xi ld python Microsoft(R)Windows调试器版本6.12.0002.633 AMD64 版权所有(c)微软公司。版权所有。 命令行:python 符号搜索路径为:symsrv*symsrv.dll*C:\Symbols* http://msdl.microsoft.com/download/symbols 可执行搜索路径为: (d50.1174):中断指令异常-代码8000003(第一次机会) ntdll!LdrpDoDebuggerBreak+0x30: 00000000`770bcb70 cc int 3 0:000>bp外壳32!SHGetFileInfoW 0:000>g Python 3.4.2(v3.4.2:AB2C023A94322014年10月6日22:16:31) win32上的[MSC v.1600 64位(AMD64)] 有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。 上述命令行中的选项
-xi ld
设置一个过滤器,以忽略打印加载的模块。有很多教程和“备忘单”在线使用微软的调试器,如WinDbg,cdb和kd。调试器都使用相同的引擎,因此它们支持一组通用的调试命令


附加的调试器在
shell32!上设置了断点!SHGetFileInfoW
。触发断点时,调试器将捕获控制台。Windows控制台为数不多的补救功能之一是其每个应用程序的输入历史记录和别名。这使得在同一控制台窗口中跳入和跳出调试器和调试对象时调用命令非常方便

导入操作系统 >>>从win32com.shell导入shell,shellcon >>>打印(外壳文件) C:\Temp\test\lib\site packages\win32comext\shell\shell.pyd >>>path=os.path.expanduser(r'~\Desktop\Desktop.ini') >>>pidl=shell.SHParseDisplayName(路径,0,无)[0] >>>flags=(shellcon.SHGFI_PIDL| …shellcon.SHGFI\u系统索引| …shellcon.SHGFI_图标| …shellcon.SHGFI\u显示名称) >>>SHGetFileInfo(pidl,0,标志)
断点0命中
炮弹32!SHGetFileInfoW:
000007fe`fd692290 fff3推送rbx
0:000>k5
***警告:无法验证的校验和
C:\Temp\test\lib\site packages\win32comext\shell\shell.pyd
子SP重新寻址呼叫站点
00000000`003ff2d8 00000000`5f44c5e8外壳32!SHGetFileInfoW
00000000`003FF2E000000000`5f5af8bd外壳!PySHGetFileInfo+0xf8
00000000`003ff610 00000000`5f62385b蟒蛇34!PyCFunction_调用+0x12d
00000000`003FF64000000000`5f625c89蟒蛇34!调用函数+0x2ab
00000000`003ff6a0 00000000`5f62770c蟒蛇34!PyEval_EvalFrameEx+0x2279
0:000>r rcx
rcx=0000000000000000
0:000>g
(0, (0, 0, 0, '', ''))
在Windows x64 ABI中,函数的第一个参数在寄存器
rcx
中传递。我们从文档中知道,这应该是
PIDL
,但实际上
NULL
正在被传递。显然这是一个错误。堆栈跟踪归咎于。下面是一段有问题的代码:

if(标志和SHGFI\u-PIDL){
ok=PyObject\u AsPIDL(obName和pidl,FALSE);
pidl_或_name=(TCHAR*)pidl;
}否则{
ok=PyWinObject\u AsTCHAR(对象名和名称,FALSE);
pidl_或_name=名称;
}
如果(!ok)
返回NULL;
SHFILEINFO;
memset(&info,0,sizeof(info));
info.dwAttributes=info\u attrs;
PY_接口_预制;
DWORD_PTR dw=SHGetFileInfo(名称、属性和信息、大小(信息)、标志);
错误是将
name
作为第一个参数传递,而不是
pidl\u或\u name


问题被标记为ctypes。依我看,如果使用ctypes是值得的,elimi
from win32com.shell import shell, shellcon
def get_info2():
    return shell.SHGetFileInfo(r"C:\Users\Ella\Desktop", 0, shellcon.SHGFI_SYSICONINDEX | shellcon.SHGFI_ICON | shellcon.SHGFI_DISPLAYNAME)