Winapi Windows 8中的ShellExecuteEx wierd行为

Winapi Windows 8中的ShellExecuteEx wierd行为,winapi,visual-c++,windows-8,Winapi,Visual C++,Windows 8,下面的无扩展名文件代码将弹出一个对话框,如下所示,列出可用于打开该文件的应用程序。此行为仅在Windows-8中可见。对话框中列出的应用程序来自HKEY_LOCAL_MACHINE\SOFTWARE\Classes*\OpenWithList。是否有任何方法可以抑制此对话框并获得类似于旧平台的行为 -卡提克 SHELLEXECUTEINFO shinfo; unsigned long mask = SEE_MASK_FLAG_NO_UI; memset(&shinfo,0,si

下面的无扩展名文件代码将弹出一个对话框,如下所示,列出可用于打开该文件的应用程序。此行为仅在Windows-8中可见。对话框中列出的应用程序来自HKEY_LOCAL_MACHINE\SOFTWARE\Classes*\OpenWithList。是否有任何方法可以抑制此对话框并获得类似于旧平台的行为

-卡提克

    SHELLEXECUTEINFO shinfo;
unsigned long  mask = SEE_MASK_FLAG_NO_UI;
memset(&shinfo,0,sizeof(shinfo));
shinfo.cbSize = sizeof(shinfo);
shinfo.fMask = SEE_MASK_FLAG_DDEWAIT | mask;
shinfo.hwnd = NULL;
shinfo.lpVerb = "open";
shinfo.lpFile = prog;
shinfo.lpParameters = NULL;
shinfo.lpDirectory = 0;
shinfo.fMask = SEE_MASK_FLAG_NO_UI;
shinfo.nShow = SW_SHOWDEFAULT;

rc = ShellExecuteEx(&shinfo);

我怀疑,对于没有扩展名的文件,Windows 8上没有与“打开”相关的默认操作。我在Windows7上使用您的代码(无论如何,是Delphi版本)确认了这一点

运行将
shinfo.lpverb
设置为“打开”的代码会导致
ShellExecuteEx
返回
FALSE
,并且
GetLastError
确实返回了
错误\u无关联
。但是,将
lpVerb
更改为NULL(Delphi中为nil)会显示标准的Win7Open With对话框,就像您的代码在Windows 8上所做的那样

以下是用于测试的代码的修改版本:

SHELLEXECUTEINFO shinfo;
memset(&shinfo, 0, sizeof(shinfo));
shinfo.cbSize = sizeof(shinfo);
shinfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
shinfo.lpVerb = NULL;
shinfo.lpFile = prog;
shinfo.hwnd = NULL; 
shinfo.lpParameters = NULL;
shinfo.lpDirectory = 0;
shinfo.nShow = SW_SHOWDEFAULT;

rc = ShellExecuteEx(&shinfo);

这是我的测试德尔福代码比较(你的C++代码的一个相当直译):

快速更改代码以将“open”替换为NULL,因为
lpVerb
应该会确认


在Win8的资源管理器中右键单击一个没有扩展名的文件,并选中上下文菜单顶部的bold默认操作,也可以很容易地确认我的怀疑。如果没有粗体选项,或者它不是打开的,那么我的猜测是正确的。

你希望它做什么?如果双击没有扩展名的文件,在资源管理器中会出现什么行为?(在Win7中,我得到一个“打开方式”对话框,因为对于未知类型的文件,不能有默认的应用程序,如果我选择一个像记事本这样的应用程序,它将不允许我将其指定为始终用于此类型文件的程序。)使用“打开”动词,你应该会得到一个错误“error\u NO\u ASSOCIATION”。这是您在低于windows 8的平台中看到的行为。你自己试着运行代码,让我知道你的观察结果。我只是做了一个快速测试(Delphi,不是C++)。一旦我将掩码更正为单个
请参阅\u mask\u FLAG\u NO\u UI或请参阅\u mask\u FLAG\u DDEWAIT
,在Win7上运行它将返回false,GetLastError()将显示
错误\u NO\u关联
。但是,将
lpVerb
更改为NULL而不是“打开”将显示“打开方式”对话框。我怀疑Win8中没有默认的“打开”动词用于没有扩展名的文件。如果在资源管理器中右键单击没有扩展名的文件,上下文菜单顶部的粗体(默认)选项是什么?谢谢Ken的实验。我认为Win 8中的粗体选项为“打开”。你知道有没有一种方法可以让你得到以前的错误行为?我看MSDN没有任何关于Win 8行为变化的说明。这让我大吃一惊。你一点也不应该感到惊讶;有许多文件类型没有默认的“打开”选项(这就是为什么我怀疑其原因)。我不确定你一开始想要完成什么,所以我不能建议解决办法。您还没有解释为什么要尝试启动一个没有扩展名的文件。在我看来,在启动文件之前,检查文件是否有一个扩展,并且适当地处理缺少的扩展是比较容易的。首先,没有“打开”动词的其他文件类型的例子:最近的Adobe Reader席席,它将默认选项改为“用Adobe Reader XI打开”,这会导致ShellExecuteEx使用“open”动词失败。我没有可用的WIn8机器,因此我无法帮助找出如何获得您想要的行为。
var
  shInfo: TShellExecuteInfo;

  FillChar(shInfo, SizeOf(shInfo), 0);   // Same result as memset()
  shInfo.cbSize := SizeOf(shInfo);
  shInfo.fMask := SEE_MASK_FLAG_NO_UI or SEE_MASK_FLAG_DDEWAIT;
  shInfo.Wnd := 0;                       
  shInfo.lpVerb := nil;                  // Also tested with 'open'
  shInfo.lpDirectory := 'D:\TempFiles';  // Path to my no-extension file
  shInfo.lpFile := 'datafile';           // My test file with no ext
  shInfo.nShow := SW_SHOWDEFAULT;
  if not ShellExecuteEx(@shInfo) then
    ShowMessage(SysErrorMessage(GetLastError)); // Readable error message