Display the "Devices and Printers" window via C#? - c#

Using C#, how can I display the "Devices and Printers" window as shown in this screenshot?

An application can open the Control Panel programmatically by executing control.exe in a new process. MSDN states that the preferred method to invoke a control panel item is to use its canonical name, which is nonlocalized and stable across versions. Beginning with Windows Vista, each Control Panel item has a canonical name; MSDN provides a list for the standard Windows control panel items. This list indicates that the canonical name for the Devices and Printers item is Microsoft.DevicesAndPrinters.
Control panel items can be opened in a new process by invoking control.exe with the canonical name as a parameter (/name <canonical name or GUID>):
//note: assumes (using System.Diagnostics and System.IO)
string controlpath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.System),
"control.exe"); // path to %windir%\system32\control.exe
// (ensures the correct control.exe)
Process.Start(controlpath, "/name Microsoft.DevicesAndPrinters");

You can open the Devices & Printers window by running the command control printers in a Command Prompt.
Knowing that, you can run cmd with the /C argument to tell it to run that command:
Process.Start("cmd", "/C control printers");
If you'd prefer the Command Prompt not to show, you can use:
var Process = new Process();
var ProcessStartInfo = new ProcessStartInfo("cmd", "/C control printers");
ProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.StartInfo = ProcessStartInfo;
Process.Start();

Related

Writing and executing multiple lines sequentially in an elevated command prompt using c#

Am a Newbie in C# and I have 3 commands(command2, command3 and command4) I need to execute in the elevated command prompt and I will also like to view the execution process as it happens. Currently, the problem is that the code below just opens the elevated command prompt and without executing the commands. I also seek better interpretations of the lines if wrong.
My code and Interpretation/Understanding of each line based on reviews of similar cases: ConsoleApp1
class Program
{
static void Main(string[] args)
{
string command2 = #"netsh wlan";
string command3 = #" set hostednetwork mode=true ssid=egghead key=beanhead keyusage=persistent";
string command4 = #" start hostednetwork";
string maincomm = command2.Replace(#"\", #"\\") + " " + command3.Replace(#"\", #"\\") ; //I merged commands 2 and 3
ProcessStartInfo newstartInfo = new ProcessStartInfo();
newstartInfo.FileName = "cmd"; //Intend to open cmd. without this the newProcess hits an error saying - Cannot run process without a filename.
newstartInfo.Verb = "runas"; //Opens cmd in elevated mode
newstartInfo.Arguments = maincomm; //I intend to pass in the merged commands.
newstartInfo.UseShellExecute = true; //
newstartInfo.CreateNoWindow = true; // I intend to see the cmd window
Process newProcess = new Process(); //
newProcess.StartInfo = newstartInfo; //Assigns my newstartInfo to the process object that will execute
newProcess.Start(); // Begin process and Execute newstartInfo
newProcess.StartInfo.Arguments = command4; //I intend to overwrite the initial command argument hereby passing the another command to execute.
newProcess.WaitForExit(); //
}
}
This is what I did to overcome the challenge and It gave me exactly what I wanted. I modified my code to use the System.IO to write directly to the elevated command prompt.
ProcessStartInfo newstartInfo = new ProcessStartInfo();
newstartInfo.FileName = "cmd";
newstartInfo.Verb = "runas";
newstartInfo.RedirectStandardInput = true;
newstartInfo.UseShellExecute = false; //The Process object must have the UseShellExecute property set to false in order to redirect IO streams.
Process newProcess = new Process();
newProcess.StartInfo = newstartInfo;
newProcess.Start();
StreamWriter write = newProcess.StandardInput ; //Using the Streamwriter to write to the elevated command prompt.
write.WriteLine(maincomm); //First command executes in elevated command prompt
write.WriteLine(command4); //Second command executes and Everything works fine
newProcess.WaitForExit();
Referrence: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx
I think an understanding of some properties of the ProcessStartInfo might clear things.
The verb - Gets or sets the verb to use when opening the application or document specified by the FileName property.,
+The UseShellExecute - Gets or sets a value indicating whether to use the operating system shell to start the process.
+The FileName - Gets or sets the application or document to start MSDN Docs
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 Documentation from MSDN.
In my case, cmd is an executable. the verb property is some thing that answers the question "How should my I run my FileName(for executables e.g cmd or any application)?" for which I answered - "runas" i.e run as administrator. When the FileName is a document (e.g `someFile.txt), the verb answers the question "What should I do with the file for which answer(verb) could be -"Edit","print" etc. also?"
use true if the shell should be used when starting the process; false if the process should be created directly from the executable file. The default is true MSDN Docs - UserShellInfo.
Another thing worth noting is knowing what you are trying to achieve. In my case, I want to be able to run commands via an executable(cmd prompt) with the same process - i.e starting the cmd as a process I can keep track of.

run shell command for third party application, pass file arguements

I'm trying to edit my own shell command to include another shell command from another application, namely AxCrypt. In a sense I'm trying to merge two context menu actions into one. If I right-click on a file, I go to AxCrypt and choose "Encrypt file to .EXE". Then I right-click again on the encrypted file and choose my shell command.
The reason I'm being so specific is someone may have something like this already. I have added this:
try
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = true;
proc.StartInfo.FileName = #"C:\Program Files\Axantum\AxCrypt\AxCrypt.exe";
proc.Start();
MessageBox.Show("AxCrypt run");
}...
I get my messagebox, but the AxCrypt application doesn't run. any ideas on how to
determine if the executable i've entered is the right one for the context menu selection in windows
correctly run this process and feed it the file argument for the file that i clicked on (as if i had chosen their menu item from the context menu)
correctly word a message to send to AxCrypt on what i'm trying to do!
1. determine if the executable i've entered is the right one for the
context menu selection in windows
Run ProcessMonitor and check the path used to launch the exe is correct - otherwise you'll see whats wrong.
2. correctly run this process and feed it the file argument for the
file that i clicked on (as if i had chosen their menu item from the
context menu)
string args = String.Format(#"{0}", "A File Arg");
proc.StartInfo.Arguments = args;
3. correctly word a message to send to AxCrypt on what i'm trying to
do!
Send them a link to this SO Q & A
I had the same problem. Look this:
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
pProcess.StartInfo.FileName = #"C:\Users\Vitor\Documents\Visual Studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe";
pProcess.StartInfo.Arguments = "olaa";
pProcess.StartInfo.UseShellExecute = false;
pProcess.StartInfo.RedirectStandardOutput = true;
pProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
pProcess.StartInfo.CreateNoWindow = true;
pProcess.Start();
string output = pProcess.StandardOutput.ReadToEnd();
pProcess.WaitForExit();

How to open "Network Connections" window programmatically

How to open "Network Connections" window programmatically using C# in Win7, XP??
Start a new process using shell execute, and run NCPA.cpl. Like so:
ProcessStartInfo startInfo = new ProcessStartInfo("NCPA.cpl");
startInfo.UseShellExecute = true;
Process.Start(startInfo);
As an extra reference, wikipedia has a pretty comprehensive list of the applets available to you that you can start in this way: http://en.wikipedia.org/wiki/List_of_Control_Panel_applets.
Edit:
As a small addition, it may be more sensible to invoke the required control panel applet using the string "control appletname". This is because while most applets can be started with their .cpl name alone, some of them, such as the Administrative Tools, don't have a .cpl name, so you need to use "control admintools" instead.
Edit 2:
As an additional reference, check out this knowledge base article: http://support.microsoft.com/kb/192806.
Another alternative:
[...]
System.Diagnostics.Process.Start("NCPA.cpl");
[...]

Mimic Windows' 'Run' window in .NET

I would like to mimic the Run command in Windows in my program. In other words, I would like to give the user the ability to "run" an arbitrary piece of text exactly as would happen if they typed it into the run box.
While System.Diagnostics.Process.Start() gets me close, I can't seem to get certain things like environment variables such as %AppData% working. I just keep getting the message "Windows cannot find '%AppData%'..."
You can use the Environment.ExpandEnvironmentVariables method to turn %AppData% into whatever it actually corresponds to.
Depending on what you're trying to do, you could also call CMD.EXE, which will expand your environment variables automatically. The example below will do a DIR of your %appdata% folder, and redirect the stdOut to the debug:
StreamReader stdOut;
Process proc1 = new Process();
ProcessStartInfo psi = new ProcessStartInfo("CMD.EXE", "/C dir %appdata%");
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
proc1.StartInfo = psi;
proc1.Start();
stdOut = proc1.StandardOutput;
System.Diagnostics.Debug.Write(stdOut.ReadToEnd());

How to use Process.Start() or equivalent with Mono on a Mac and pass in arguments

I am trying to write some c# code to start a browser using Process.Start(app,args); where apps is the path to the browser e.g. /Applications/Google Chrome.app/Contents/MacOS/Google Chrome and the args are --no-default-browser-check
If i do, which works on Windows and on Linux
Process.Start("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","--no-first-run");
I get
open: unrecognized option `--no-first-run'
Usage: open [-e] [-t] [-f] [-W] [-n] [-g] [-h] [-b <bundle identifier>] [-a <application>] [filenames]
Help: Open opens files from a shell.
By default, opens each file using the default application for that file.
If the file is in the form of a URL, the file will be opened as a URL.
Options:
-a Opens with the specified application.
-b Opens with the specified application bundle identifier.
-e Opens with TextEdit.
-t Opens with default text editor.
-f Reads input from standard input and opens with TextEdit.
-W, --wait-apps Blocks until the used applications are closed (even if they were already running).
-n, --new Open a new instance of the application even if one is already running.
-g, --background Does not bring the application to the foreground.
-h, --header Searches header file locations for headers matching the given filenames, and opens them.
I have also tried Monobjc to try run the code with
// spin up the objective-c runtime
ObjectiveCRuntime.LoadFramework("Cocoa");
ObjectiveCRuntime.Initialize();
NSAutoreleasePool pool = new NSAutoreleasePool();
// Create our process
NSTask task = new NSTask();
NSPipe standardOut = new NSPipe();
task.StandardOutput = standardOut;
task.LaunchPath = #"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
// add some arguments
NSString argumentString = new NSString("--no-first-run");
NSArray arguments = NSArray.ArrayWithObject(argumentString);
task.Arguments = arguments;
// We should have liftoff
task.Launch();
// Parse the output and display it to the console
NSData output = standardOut.FileHandleForReading.ReadDataToEndOfFile;
NSString outString = new NSString(output,NSStringEncoding.NSUTF8StringEncoding);
Console.WriteLine(outString);
// Dipose our objects, gotta love reference counting
pool.Release();
But when I run my code using NUnit it causes NUnit to blow up.
I suspect that this is a bug but can't prove it. I appreciate any and all help!
To make Process.Start use exec directly instead of using the OS' mechanism for opening files, you must set UseShellExecute to false. This is also true on Linux and Windows.
Process.Start(new ProcessStartInfo (
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"--no-first-run")
{ UseShellExecute = false });
Note that you can also use 'open' for your use case, to run the Chrome app bundle properly. Use the '-a' argument to force it to run a specific app, the '-n' argument to open a new instance, and '--args' to pass in arguments:
Process.Start(new ProcessStartInfo (
"open",
"-a '/Applications/Google Chrome.app' -n --args --no-first-run")
{ UseShellExecute = false });
Looks like Process uses the open command line utility to launch.
You should avoid calling the executable directly. If the application is already running, this would launch a second instance of it instead of activating the already running instance. That's probably not what you want, and not all applications can handle this anyway.
With open, the syntax to launch Chrome would be
open -a Chrome
I don't know how the Process class works on MacOS X, but I assume that the parameters should be similar.
Note, if you just want to open a web page, you should not specify the executable; instead, just pass the URL, so that it will be opened in the user's default browser. This is valid for any platform.
Process.Start("http://www.google.com");
Have you tried something like concatenating the parameters into the process name instead of passing it separated?
var processName = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
var args = "--no-default-browser-check";
Process.Start(String.Format("{0} {1}", processName, args));
Why dont you try something like this:
Process P = new Process();
P.StartInfo.FileName = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
P.StartInfo.Arguments = "--no-default-browser-check";
P.UseShellExecute = false;
P.Start();

Categories