Fab*_*zio 2 delphi winapi file-type file-association windows-10
我正在使用AssocQueryString以获取与某些扩展相关联的可执行文件.它适用于".pdf"和".txt"之类的扩展,但我注意到它没有为我尝试的所有图像扩展返回任何内容(".bmp",".png",".jpg" ,".ic").
uses
ShLwApi, Windows, Dialogs;
const
// ASSOCF enumerated values mapped to integer constants
ASSOCF_INIT_NOREMAPCLSID = $00000001;
ASSOCF_INIT_BYEXENAME = $00000002;
ASSOCF_OPEN_BYEXENAME = $00000002;
ASSOCF_INIT_DEFAULTTOSTAR = $00000004;
ASSOCF_INIT_DEFAULTTOFOLDER = $00000008;
ASSOCF_NOUSERSETTINGS = $00000010;
ASSOCF_NOTRUNCATE = $00000020;
ASSOCF_VERIFY = $00000040;
ASSOCF_REMAPRUNDLL = $00000080;
ASSOCF_NOFIXUPS = $00000100;
ASSOCF_IGNOREBASECLASS = $00000200;
var
Buffer: array [0..1024] of char;
BufSize: DWord;
begin
BufSize := Sizeof(Buffer);
Buffer[0] := #0;
AssocQueryString(
ASSOCF_NOTRUNCATE,
ASSOCSTR_EXECUTABLE,
'.bmp',
'open',
Buffer,
@BufSize
);
ShowMessage(Buffer);
end;
Run Code Online (Sandbox Code Playgroud)
进一步的信息:
它也适用于图像扩展,但仅限于要求与"编辑"而不是"打开"相关联的可执行文件.
双击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));
Run Code Online (Sandbox Code Playgroud)
它显示"{4ED3A719-CEA8-4BD9-910D-E252F997AFC2}"..如何在Win7上看到相同的结果?(一个DLL或一个可执行文件名)此外,我注意到在将'.bmp'更改为一个不存在的(如'.abcde')后返回一个类似的结果..为此,我甚至不知道是否有一个相关的程序.
如评论中所述,您的计算机的图像文件扩展名注册不使用应用程序打开文件,而是使用Rundll32调用的DLL.
根据ASSOCSTR文件:
ASSOCSTR_EXECUTABLE
Shell动词命令字符串中的可执行文件.例如,找到此字符串作为子键的(默认)值,例如HKEY_CLASSES_ROOT\ApplicationName\shell\Open\command.如果该命令使用Rundll.exe,请在IQueryAssociations :: GetString的flags参数中设置ASSOCF_REMAPRUNDLL标志以检索目标可执行文件.注意
并非所有应用关联都具有可执行文件.不要假设可执行文件总是存在.
根据ASSOCF文件:
ASSOCF_REMAPRUNDLL
指示IQueryAssociations方法忽略Rundll.exe并返回有关其目标的信息.通常,IQueryAssociations方法返回有关第一个.exe或.dll命令字符串的信息.如果命令使用Rundll.exe,则设置此标志会告诉方法忽略Rundll.exe并返回有关其目标的信息.
此外,在调用时AssocQueryString(),尝试将pszExtra参数设置为NULL而不是特定的动词.
另外,请注意以下参数的文档AssocQueryString():
cchOut [in,out]
类型:DWORD*指向一个值的指针,该值在调用函数时设置为pszOut缓冲区中的字符数.当函数成功返回时,该值设置为实际放置在缓冲区中的字符数.
您将BufSize变量设置为字节数而不是字符数.您的代码假定Sizeof(Char)为1,但这仅适用于Delphi 2007及更早版本.在Delphi 2009及更高版本中,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;
Run Code Online (Sandbox Code Playgroud)
或者:
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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1711 次 |
| 最近记录: |