What I want?
I want to call up the Open with dialog that is only used to specify the format file association and will not open the file.
Look like this in Win10:
And look like this in Win11:
In system settings, you can modify the default application to display the open with dialog.
Existing third-party software implementation: Bandizip can do it!
What I tried?
Call the obsoleted Win32 API
MSDN doc says that starting in Windows 10, it is not possible to call SHOpenWithDialog
to set the file association for the specified format.
Call the system command line
When I tried to invoke the following two commands, neither of the "Open With" dialog boxes were able to set the file association, and will open the file.
OpenWith.exe "%1"
rundll32.exe shell32.dll,OpenAs_RunDLL "%1"
%1 is a full file path.
Use openas Verb
I tried to start a process with openas
verb whether with calling CreateProcess or ShellExecuteEx, I think they do the same thing in the end. The "Open With" dialog will displayed with a check box named "Always open with this application" as-if clicking "Open With" from a file's context menu. But that will open the file, and an exception is thrown for an extension with no file association set.
- CreateProcess
public static void ShowOpenWithDialog(string extension)
{
string tempPath = $"{Path.GetTempPath()}{Guid.NewGuid()}{extension}";
File.WriteAllText(tempPath, "");
using(Process process = new Process())
{
process.StartInfo = new ProcessStartInfo
{
UseShellExecute = true,
FileName = tempPath,
Verb = "openas"
};
process.Start();
}
File.Delete(tempPath);
}
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;
}
[DllImport("shell32.dll")]
static extern bool ShellExecuteEx(ref ShellExecuteInfo lpExecInfo);
const uint SW_NORMAL = 1;
static void ShowOpenWithDialog()
{
string tempPath = $"{Path.GetTempPath()}{Guid.NewGuid()}{extension}";
File.WriteAllText(tempPath, "");
var sei = new ShellExecuteInfo
{
sei.Size = Marshal.SizeOf(sei),
sei.Verb = "openas",
sei.File = tempPath,
sei.Show = SW_NORMAL,
};
ShellExecuteEx(ref sei);
}
Call Launcher.LaunchFileAsync in UWP
Launch the default app for a file - Open With launch
I found that I can call up the open with dialog through this method, but the effect is no different from the above method.
async void DefaultLaunch()
{
// Path to the file in the app package to launch
string imageFile = @"images\test.png";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFile);
if (file != null)
{
// Set the option to show the picker
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = true;
// Launch the retrieved file
bool success = await Windows.System.Launcher.LaunchFileAsync(file, options);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
else
{
// Could not find file
}
}