Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.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
Delphi 为什么';t AssocQueryString是否查找与图像扩展相关联的可执行文件?_Delphi_Winapi_Windows 10_File Type_File Association - Fatal编程技术网

Delphi 为什么';t AssocQueryString是否查找与图像扩展相关联的可执行文件?

Delphi 为什么';t AssocQueryString是否查找与图像扩展相关联的可执行文件?,delphi,winapi,windows-10,file-type,file-association,Delphi,Winapi,Windows 10,File Type,File Association,我使用AssocQueryString来获取与某些扩展相关联的可执行文件。 它适用于扩展名“.pdf”和“.txt”,但我注意到,对于我尝试过的所有图像扩展名(“.bmp”、“.png”、“.jpg”、“.ico”),它都不会返回任何内容 更多信息: 它也适用于图像扩展,但仅当请求与“编辑”而不是“打开”关联的可执行文件时 双击bmp文件会导致使用默认的Windows 10照片查看器打开该文件 更新 目前,我的代码是: var Buffer: array [0..1024] of Char;

我使用AssocQueryString来获取与某些扩展相关联的可执行文件。 它适用于扩展名“.pdf”和“.txt”,但我注意到,对于我尝试过的所有图像扩展名(“.bmp”、“.png”、“.jpg”、“.ico”),它都不会返回任何内容

更多信息:

它也适用于图像扩展,但仅当请求与“编辑”而不是“打开”关联的可执行文件时

双击bmp文件会导致使用默认的Windows 10照片查看器打开该文件

更新

目前,我的代码是:

var
  Buffer: array [0..1024] of Char;
  BufSize: DWord;
  Res: HResult;
begin
  BufSize := Length(Buffer);
  Res := AssocQueryString(
    ASSOCF_REMAPRUNDLL or ASSOCF_NOTRUNCATE,
    (*ASSOCSTR_DELEGATEEXECUTE missing on Delphi 2007*) 18,
    '.bmp',
    nil,
    Buffer,
    @BufSize
  );
  If Res = S_OK then
    ShowMessage(Buffer)
  else
    ShowMessage('Error ' + IntToStr(Res) + sLineBreak + SysErrorMessage(Res));
它显示“{4ED3A719-CEA8-4BD9-910D-E252F997AFC2}”。。如何在Win7上看到相同的结果?(dll或可执行文件名)
此外,我注意到,将“.bmp”更改为不存在(如“.abcde”)后,返回类似的结果。。为此,我甚至不知道是否有关联的程序。

如注释中所述,您的计算机对图像文件扩展名的注册不是使用应用程序打开文件,而是使用Rundll32调用的DLL

根据文件:

ASSOCSTR_可执行文件
来自Shell谓词命令字符串的可执行文件。例如,此字符串作为子项的(默认)值,例如
HKEY\u CLASSES\u ROOT\ApplicationName\shell\Open\command
如果命令使用Rundll.exe,请在IQueryAssociations::GetString的flags参数中设置ASSOCF_REMAPRUNDLL标志以检索目标可执行文件

小心
并非所有应用程序关联都有可执行文件。不要假设可执行文件始终存在

根据文件:

ASSOCF_REMAPRUNDLL
指示
IQueryAssociations
方法忽略
Rundll.exe
并返回有关其目标的信息。通常,
IQueryAssociations
方法返回命令字符串中第一个
.exe
.dll
的信息。如果命令使用
Rundll.exe
,则设置此标志会告诉方法忽略
Rundll.exe
,并返回有关其目标的信息

另外,在调用
AssocQueryString()
时,请尝试将
pszExtra
参数设置为NULL,而不是特定的动词

另外,请注意
AssocQueryString()
最后一个参数的文档:

cchOut[输入,输出]
类型:德沃德*

指向一个值的指针,该值在调用函数时设置为pszOut缓冲区中的字符数。当函数成功返回时,该值设置为实际放入缓冲区的字符数

您正在将
BufSize
变量设置为字节计数而不是字符计数。您的代码假设
Sizeof(Char)
为1,但只有在Delphi2007及更早版本中才是如此。在Delphi2009及更高版本中,
Sizeof(Char)
改为2

并始终检查返回值是否存在错误

试试这个:

var
  Buffer: array [0..1024] of Char;
  BufSize: DWord;
  Res: HResult;
begin
  BufSize := Length(Buffer);
  Res := AssocQueryString(
    ASSOCF_REMAPRUNDLL or ASSOCF_NOTRUNCATE,
    ASSOCSTR_EXECUTABLE,
    '.bmp',
    nil,
    Buffer,
    @BufSize
  );
  If Res = S_OK then
    ShowMessage(Buffer)
  else
    ShowMessage('Error ' + IntToStr(Res));
end;
或者:

var
  Buffer: string;
  BufSize: DWord;
  Res: HResult;
begin
  BufSize := 0;
  Res := AssocQueryString(
    ASSOCF_REMAPRUNDLL or ASSOCF_NOTRUNCATE,
    ASSOCSTR_EXECUTABLE,
    '.bmp',
    nil,
    nil,
    @BufSize
  );
  if Res = S_FALSE then
  begin
    SetLength(Buffer, BufSize-1);
    Res := AssocQueryString(
      ASSOCF_REMAPRUNDLL or ASSOCF_NOTRUNCATE,
      ASSOCSTR_EXECUTABLE,
      '.bmp',
      nil,
      PChar(Buffer),
      @BufSize
    );
  end;
  If Res = S_OK then
    ShowMessage(Buffer)
  else
    ShowMessage('Error ' + IntToStr(Res));
end;

系统上的图像文件会返回什么?@IInspectable:结果为31(SE_ERR_NOASSOC->“指定的文件类型与可执行文件没有关联。”->)。如果将
pszExtra
参数留空(pass
nil
而不是
'open'
),您将看到.bmp扩展名实际上与PhotoViewer.dll关联,而不是一个可执行文件(至少在Win7 64上-我怀疑在Win10上类似)
assoc.bmp
从命令提示符显示它是一个Paint.Picture,根据
ftype Paint.Picture
它与
rundl32 PhotoViewer.dll
@KenWhite关联:我确认在Windows 10上“assoc.bmp”也显示“Paint.Picture”。我尝试将nil作为pszExtra参数传递,但结果仍然是一个空字符串。您想如何处理这些信息?非常感谢您的建议和文档引用。我尝试过你的解决方案,但在这两种情况下,AssocQueryString在我的系统上返回-2147023741。你是对的。也许我误解了一些东西,但您的两个代码示例都设置了ASSOCF\u REMAPRUNDLL标志。如果我双击一个“.bmp”文件,它就会用Windows10照片查看器打开。为什么AssocQueryString仍然返回错误\u NO\u关联?@ExDev:代码在Win7上运行良好,它会按预期返回
PhotoViewer.dll
。当我在Win10上运行完全相同的代码时,它失败了。我注意到Win10上的
.bmp
没有
open
动词(只有
edit
printto
)。正如文档所说,关联不一定有可执行文件。但是,
ASSOCSTR\u DELEGATEEXECUTE
适用于Win10上的
.bmp
(尽管其谓词没有显式的
DELEGATEEXECUTE
值),并且返回的CLSID属于“关联启动执行命令”COM对象,因此,行为上的差异可能与使用
IExecuteCommand
vs命令ilne有关。我通过添加当前代码更新了我的问题。它返回“{4ED3A719-CEA8-4BD9-910D-E252F997AFC2}”。代码中有什么错误吗?我的意思是,我能得到与Win7相同的结果吗?('PhotoViewer.dll')@ExDev我仍然想知道:您想对关联信息做什么?
var
  Buffer: string;
  BufSize: DWord;
  Res: HResult;
begin
  BufSize := 0;
  Res := AssocQueryString(
    ASSOCF_REMAPRUNDLL or ASSOCF_NOTRUNCATE,
    ASSOCSTR_EXECUTABLE,
    '.bmp',
    nil,
    nil,
    @BufSize
  );
  if Res = S_FALSE then
  begin
    SetLength(Buffer, BufSize-1);
    Res := AssocQueryString(
      ASSOCF_REMAPRUNDLL or ASSOCF_NOTRUNCATE,
      ASSOCSTR_EXECUTABLE,
      '.bmp',
      nil,
      PChar(Buffer),
      @BufSize
    );
  end;
  If Res = S_OK then
    ShowMessage(Buffer)
  else
    ShowMessage('Error ' + IntToStr(Res));
end;