I am developing an application for managing Personal Hotspot of a Laptop
(Windows of Course).
I'm having a little difficulty in changing the Hotspot Name.
Here is my Code:
//For CMD Command
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new
System.Diagnostics.ProcessStartInfo();
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.FileName = "CMD.exe";
startInfo.CreateNoWindow = true;
//Reading User Input in textBox1:
string name = textBox1.Text;
//CMD Argument:..., Which is currently written wrong to make it Easy to
//understand the problem
startInfo.Arguments = "/C netsh wlan set hostednetwork ssid="name";
process.StartInfo = startInfo;
process.Start();
Here, In the Arguments line, the syntax is wrong. The value assigned to Arguments should be a single string. I need to incorporate name, that has a dynamic value, with the rest of the string that is constant. How do I do that?
Unless I'm missing something here, seems to me that a simple string concatenation would do it:
startInfo.Arguments = "/C netsh wlan set hostednetwork ssid=" + name;
There are several ways you can create a dynamic string:
For your specific case, Concatenation is the best choice as your string is very simple.The reason you would choose this method for your case is because it is very light as compared to other methods and has a clean enough syntax.
startInfo.Arguments = "/C netsh wlan set hostednetwork ssid=" + name;
For anything more complicated, string.Format is a popular go to. You would generally use it to combine more complex strings than your example. This tutorial covers the subject thoroughly.
startInfo.Arguments = string.Format("/C netsh wlan set hostednetwork ssid={0}", name);
The release of C#6.0 included a neat feature: interpolated strings. It is for the most part just syntactic sugar for string.Format, where the line below is turned into the line above at compile time. There are subtle differences, but those are not important in this thread.
startInfo.Arguments = $"/C netsh wlan set hostednetwork ssid={name}";
And lastly, if you need to change a string more than a few times (I usually use the rule of 5 - i.e. a string changes more than 5 times), I would use the StringBuilder class. A great application, among many others, would be a long loop that modifies a certain string each iteration. See This Tutorial.
In this case, the Garbage Collector will thank you for a using a StringBuilder!
Related
I want to add a rule using netsh advfirewall firewall to block any programs like chrome or firefox from accesing specific Ips?Would appreciate your help!!!
This is the code I tried but it did'nt work.Please guide me.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/c netsh advfirewall firewall add rule name=Block inbound traffic from 192.168.0.2 over TCP port 4000 dir=in action=block program=C:/Program Files/Mozilla Firefox/Firefox.exe enable=yes protocol=TCP remoteip=192.168.0.2 profile=domain,private,public";
startInfo.Verb = "runas";
process.StartInfo = startInfo;
process.Start();
I can't help you with the netsh stuff (and don't know why you are calling this from C#), but the most obvious error of the netsh call is the missing quoting of spaces in the program=C:/Program Files/Mozilla Firefox/Firefox.exe argument. As spaces are used as argument separators, it is parsed as three separate arguments, program=c:/Program and Files/Mozilla and Firefox/Firefox.exe. You can see the most simple fix in the Arguments description: Add escaped quotation marks around the path, i.e. "... program=\"C:/Program Files/Mozilla Firefox/Firefox.exe\" ...".
Other recommendations:
AFAICS, you don't need cmd.exe to call netsh, so you could simply call netsh.exe
Why are you using forward slashes in the path? It works with most stuff, but not with all, so I would recommend using backslashes \ as this is the Windows default path separator.
Rather than giving all arguments in a single string Arguments (and risking to stumble over subtleties like quoting), I would recommend ArgumentList.
In the end, it would look like this:
var startInfo = new ProcessStartInfo()
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "netsh",
ArgumentList =
{
"advfirewall", "firewall",
"add", "rule", "name=Block", "inbound", "traffic",
"from", "192.168.0.2", "over", "TCP", "port", "4000", "dir=in", "action=block",
#"program=C:\Program Files\Mozilla Firefox\Firefox.exe",
"enable=yes",
"protocol=TCP",
"remoteip=192.168.0.2",
"profile=domain,private,public",
},
Verb = "runas",
};
Process.Start(startInfo);
Running this from CMD produces the correct result:
powershell -command "& Get-DiskImage -imagepath C:\\file.vhdx | Get-Disk"
<Here is some stuff regarding VHD>
I want to achieve exactly the same running this from C# (there's no way to run it directly, use some PowerShell related .NET stuff, or something else).
My code is the following:
static void LaunchCommandLineApp()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "powershell";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.RedirectStandardOutput = true;
startInfo.Arguments = "-command \" & get-diskimage -imagepath C:\\file.vhdx | Get-Disk \"";
using (Process exeProcess = Process.Start(startInfo)) {
exeProcess.WaitForExit();
var out = exeProcess.StandardOutput.ReadToEnd();
}
}
And in "out" I am getting an error:
Get-Disk : Cannot validate argument on parameter 'Number'. The argument is null. Provide a valid value for the argument, and then try running the command again.
But exactly the same code works in CMD. If I remove "| Get-Disk" from arguments, I will get correct output in "out" from the Get-DiskImage cmdlet.
Also, I have tried to play with curly braces, as other answers suggested - error haven't changed.
What shall I put in "startInfo.Arguments", so my output of "Get-DiskImage" will be correctly piped to the next cmdlet?
This is not actually a problem with the difference between running from the command line and from C#. I created a test VHDX and got the same (error) result whether run from C# or the command line, as shown by the OP.
In both cases, omitting the | Get-Disk part showed information about the disk image, which lacked a disk number, which is exactly what Get-Disk was complaining about. I suspect the image needs to be mounted for it to have a disk number.
I need to execute the following command, it works perfectly, if I execute it via command prompt, here the command line is using kodakprv.exe to send a print of a tiff file.
but when trying to execute it via c#, its not throwing any error but not sending the print either, tried to execute this command via xp_cmdshell in SQL, but it didn't work, in the xp_cmdshell documentation found that, quotes are not allowed for more then once, but kodakprv.exe print logic requires 3 pair of quotes
Please suggest can we use multiple quotes in C# while executing the command or suggest any better solution for it
String sCommand = "\"c:\\progra~1\\imagin~1\\kodakprv.Exe\" /pt \"D:\\SQLDev\\Dlls\\Testing.TIF\" \"\\\\Galactica\\C-Test1\"";
// Put your code here
System.Diagnostics.Process ExecuteCommand = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.Arguments = #" /c " + sCommand.ToString();
MessageBox.Show(startInfo.Arguments);
ExecuteCommand.StartInfo = startInfo;
ExecuteCommand.Start();
You don't need all those quotes. Only paths with spaces require quotes. None of your paths have spaces.
Shortnames, as you are using, may not exist (they can be turned off), or may not have the name you think. Windows does not preserve short names, only long names.
You are running your program via CMD. Unless your command line has redirection characters (as CMD handles redirection characters) then CMD is not required. You can start your program directly, which would be the preferred way (faster, less resources used).
Your window is set to hidden. Therefore you cannot see the message it is telling you. Unhide your window.
Your program will likely exit and close the window before you can read it. Either stick a &pause at the end of the command line sent to CMD, or read what is on both StdErr and StdOut as you specify to capture them in your code.
I have researched and attempted to do this myself, but with no luck. I am trying to execute a java app and pass it a few variables. It is finding the java and running it, but not passing it any variables, here is what I have so far -
Process proc = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = #"-jar javaapp.jar" + "host:port" + "password" + "/say" + "test";
startInfo.FileName = "java";
proc.StartInfo = startInfo;
proc.Start();
I cant work this out at all. I dont want to use any third party software (unless it can be packaged in the .EXE) as this is meant to be distributed to people who need it. Any help is thanked.
You need to put spaces in the strings you're concatenating, your command currently looks like
java -jar javaapp.jarhost:portpassword/saytest
The simplest way is to use string.Format:
string command1 = "/say"
string command2 = "test"
string args = string.Format("-jar javaapp.jar {0}:{1} {2} {3} {4}", host, port, password, command1, command2);
startInfo.Arguments = args;
Arguments is a string - the way you have it they'll all be mashed together with no space separating them.
The # symbol in C# is used for literal format of string; it looks like you're trying to use it to build an array or something.
I have a little problem with star character in my command for linux - I need to find out distro. When I replace this character witch e.g. 'fedora' then this command gives good results. In this case it write something like this: /bin/cat: /etc/*-release: Directory or file doesn't exist.
My code is:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cat";
p.StartInfo.Arguments = "/etc/*-release";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Thanks in advance for your answer.
Matej
When you run cat /etc/*-release from your shell, the shell is responsible for expanding the * to a list of matching files, if any.
When you directly execute a program yourself (as you're doing here with the Process interface), you need to re-create the shell's behavior yourself. This is actually for the best, as it is a bit silly to run cat to read a file from a full-featured programming language -- surely the language provides something easy for the logical equivalent of:
list = glob(/etc/*-release)
foreach file in (list):
fd = open(file, "read");
contents = read(fd)
close(fd)
dosomething_with(contents)
You can use whatever mechanism you like to replace the glob() bit there; a fellow stacker has provided his own glob() mechanism in another answer.