ShellExecute equivalent in .NET
Process.Start.
Note that advanced uses (printing etc) require using a ProcessStartInfo and setting the Verb property.
ShellExecute vs. Process.Start
are there any advantages for using ShellExecute over Process.Start
First, you need to understand what ShellExecute
does. From ProcessStartInfo.UseShellExecute
:
When you use the operating system shell to start processes, you can
start any document (which is any registered file type associated with
an executable that has a default open action) and perform operations
on the file, such as printing, by using the Process object. When
UseShellExecute is false, you can start only executables by using the
Process object.
This means that it will allow you to open any file that has an assosicated file type, such as a given word document. Otherwise, you can only invoke executables. If you set this flag to true in ProcessStartInfo
, internally, Process.Start
will invoke the same WinAPI call:
public bool Start()
{
Close();
ProcessStartInfo startInfo = StartInfo;
if (startInfo.FileName.Length == 0)
throw new InvalidOperationException(SR.GetString(SR.FileNameMissing));
if (startInfo.UseShellExecute)
{
return StartWithShellExecuteEx(startInfo);
}
else
{
return StartWithCreateProcess(startInfo);
}
}
When you invoke ShellExecute
, you're using PInvoke to directly call WinAPI. With Process.Start, you're simply invoking the managed wrapper, which is usually more convenient to use.
C# equivalent to shell_exec
The MSDN documentation on Process.StandardOutput documentation shows an example
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
You might like to extract the standard error stream as well.
OSX equivalent of ShellExecute?
You can call system();
in any C++ application. On OSX, you can use the open command to launch things as if they were clicked on.
From the documentation for open:
The open command opens a file (or a directory or URL), just as if you had double-clicked the file's icon. If no application name is specified, the default application as determined via LaunchServices is used to open the specified files.
All together, it would look like:
string command = "open " + filePath;
system(command.c_str());
How to open a file/protocol with a specific (not default) class
There is no equivalent way of doing it in .NET. Your way of handling (using ShellExecuteEx) it is right way.
Want to execute a command in command prompt window
Create a batch file that contains your commands.
Then use Process.Start and ProcessStartInfo class to execute your batch.
ProcessStartInfo psi = new ProcessStartInfo(@"d:\datafeeds\yourbatch.cmd");
psi.WindowStyle = ProcessWindowStyle.Minimized;
psi.WorkingDirectory = @"d:\datafeeds";
Process.Start(psi);
ProcessStartInfo contains other useful properties See MSDN docs
Process and ProcessStartInfo require an using System.Diagnostics;
In this scenario (when you need to run command line tools) I prefer to use the batch approach instead of coding everything through the ProcessStartInfo properties. It will be more flexible when you have to change something and you have not the code available.
How to shellexecute a tempory installer file?
The error that the system is returning to you is ERROR_NO_ASSOCIATION
. Although you have not stated what extension filePath
has, it seems likely that it is not .exe
.
Were you to rename the downloaded file to have extension .exe
, then the call to ShellExecuteEx
would succeed. That's the hacky way to do it. The cleaner way is to use the lpClass
member of the SHELLEXECUTEINFO
struct to specify that you want the file to be treated as an executable. You can do that by adding the following to your code:
shExecInfo.fMask = SEE_MASK_CLASSNAME;
shExecInfo.lpClass = _T("exefile");
I'd write your code like this:
SHELLEXECUTEINFO shExecInfo = {0};
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shExecInfo.fMask = SEE_MASK_CLASSNAME;
shExecInfo.lpVerb = _T("runas");
shExecInfo.lpFile = filePath;
shExecInfo.nShow = SW_MAXIMIZE;
shExecInfo.lpClass = _T("exefile");
ShellExecuteEx(&shExecInfo);
Note the zero initialization so that we can omit explicit assignment for members that should be NULL
.
Related Topics
Switch Case in C# - a Constant Value Is Expected
How to Get a Uri of the Image Stored in the Resources
Checking User Name or User Email Already Exists
How to Read a Text File Without Locking It
Remove Text In-Between Delimiters in a String (Using a Regex)
Asynchronous Task.Whenall with Timeout
Textrenderer.Measuretext and Graphics.Measurestring Mismatch in Size
How to Include Quotes in a String
How to Bind Crystal Report to Manually Created Dataset
Shellexecute Equivalent in .Net
What's the Difference Between Returning Void and Returning a Task
Programmatically Get the Version Number of a Dll
How to Get the Width and Height of a Multi-Dimensional Array
Is Endinvoke() Optional, Sort-Of Optional, or Definitely Not Optional