在窗口七下,下面的命令显示一个对话框然后没有任何其他操作就终止了,为什么?
预期效果是启动相关程序Notepad++
或至少Notepad
RUNDLL32.EXE SHELL32.DLL,OpenAs_RunDLL D:\doc\toto.txt
在窗口七下,下面的命令显示一个对话框然后没有任何其他操作就终止了,为什么?
预期效果是启动相关程序Notepad++
或至少Notepad
RUNDLL32.EXE SHELL32.DLL,OpenAs_RunDLL D:\doc\toto.txt
首先,请注意这OpenAs_RunDLL
是一个未记录的入口点,因此期望它工作的唯一原因是它出现在 HKEY_CLASSES_ROOT 注册表中作为Open With
shell 动词的实现(至少在某些版本的 Windows 中)。
这仅意味着它可以在被适当的 shell 函数调用时工作。这并不意味着它一定会在任何任意上下文中工作。
在我的家用机器(Windows Vista)上,当通过“开始”菜单的“运行”对话框发出命令时,OpenAs_RunDLL
通过rundll32
作品调用(即使用选定的应用程序打开指定的文件),该对话框可以使用键盘快捷键打开Windows+R
。
从命令行控制台窗口发出时它不起作用,并且症状与您描述的相同:出现对话框,但未启动应用程序。这是完全合法的行为,因为您在不是为它设计的上下文中使用了未记录的入口点。
由于无法保证OpenAs_RunDLL
在未来的 Windows 版本中完全存在,因此结果很简单:不要使用它。改用支持的SHOpenWithDialog
API 函数,或使用ShellExecute
orShellExecuteEx
与openas
动词; 后者可能特别有用,因为它很容易通过 VBScript 之类的脚本语言来实现。
解决方案非常简单:cmde.exe start
这是嵌入命令的Java代码:
private void open( File file ) {
try {
final String cmd =
String.format( "cmd.exe /C start %s", file.getAbsolutePath());
Runtime.getRuntime().exec( cmd );
}
catch( final Throwable t ) {
t.printStackTrace();
}
}
选择时.project
显示以下对话框:
and when the radio button at the bottom is chosen the following dialog is shown:
这正是我想要的。
基于对类似问题的其他答案和CodeProject 中的代码:Calling the Open With dialog box from your application, using C# and PInvoke.net: SHOpenWithDialog (shell32)这是适用于我的代码
ShellHelper.OpenAs(mainForm.Handle, "path/to/file")
在 Windows XP 和 Windows Vista 及更高版本上。此代码仅使用记录的 API(否rundll32
)
public class ShellHelper
{
#region http://www.pinvoke.net/default.aspx/shell32/SHOpenWithDialog.html
[DllImport("shell32.dll", EntryPoint = "SHOpenWithDialog", CharSet = CharSet.Unicode)]
private static extern int SHOpenWithDialog(IntPtr hWndParent, ref tagOPENASINFO oOAI);
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773363(v=vs.85).aspx
private struct tagOPENASINFO
{
[MarshalAs(UnmanagedType.LPWStr)]
public string cszFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string cszClass;
[MarshalAs(UnmanagedType.I4)]
public tagOPEN_AS_INFO_FLAGS oaifInFlags;
}
[Flags]
private enum tagOPEN_AS_INFO_FLAGS
{
OAIF_ALLOW_REGISTRATION = 0x00000001, // Show "Always" checkbox
OAIF_REGISTER_EXT = 0x00000002, // Perform registration when user hits OK
OAIF_EXEC = 0x00000004, // Exec file after registering
OAIF_FORCE_REGISTRATION = 0x00000008, // Force the checkbox to be registration
OAIF_HIDE_REGISTRATION = 0x00000020, // Vista+: Hide the "always use this file" checkbox
OAIF_URL_PROTOCOL = 0x00000040, // Vista+: cszFile is actually a URI scheme; show handlers for that scheme
OAIF_FILE_IS_URI = 0x00000080 // Win8+: The location pointed to by the pcszFile parameter is given as a URI
}
private static void DoOpenFileWith(IntPtr hwndParent, string sFilename)
{
tagOPENASINFO oOAI = new tagOPENASINFO();
oOAI.cszFile = sFilename;
oOAI.cszClass = String.Empty;
oOAI.oaifInFlags = tagOPEN_AS_INFO_FLAGS.OAIF_ALLOW_REGISTRATION | tagOPEN_AS_INFO_FLAGS.OAIF_EXEC;
SHOpenWithDialog(hwndParent, ref oOAI);
}
#endregion
#region http://www.codeproject.com/Articles/13103/Calling-the-Open-With-dialog-box-from-your-applica
[Serializable]
private struct ShellExecuteInfo
{
public int Size;
public uint Mask;
public IntPtr hwnd;
public string Verb;
public string File;
public string Parameters;
public string Directory;
public uint Show;
public IntPtr InstApp;
public IntPtr IDList;
public string Class;
public IntPtr hkeyClass;
public uint HotKey;
public IntPtr Icon;
public IntPtr Monitor;
}
// Code For OpenWithDialog Box
[DllImport("shell32.dll", SetLastError = true)]
extern private static bool ShellExecuteEx(ref ShellExecuteInfo lpExecInfo);
private const uint SW_NORMAL = 1;
private static void OpenAsOld(IntPtr hwndParent, string file)
{
ShellExecuteInfo sei = new ShellExecuteInfo();
sei.Size = Marshal.SizeOf(sei);
sei.Verb = "openas";
sei.File = file;
sei.Show = SW_NORMAL;
sei.hwnd = hwndParent;
if (!ShellExecuteEx(ref sei))
throw new System.ComponentModel.Win32Exception();
}
#endregion
public static void OpenAs(IntPtr hWndParent, string file)
{
if (System.Environment.OSVersion.Version.Major > 5)
{
DoOpenFileWith(hWndParent, file);
}
else
{
OpenAsOld(hWndParent, file);
}
}
}