How to execute multiple commands - C# - c#

There are 2 PCs(server & node). The Selenium hub is up & running. The notifications are seen in its cmd window.
Now, I'm trying to set up another PC as a Selenium node. To do that I need to run 2 commands from the server PC command prompt.It works when done manually.Failing to do so programatically.
Here is what I have so far.
private static void StartSeleniumNode()
{
string Command1 = "/C cmdkey.exe /add:ABCDES181 /user:abc /pass:abc#123 & ";
string Command2 = "psexec.exe \\ABCDES181 -i -w D:\\Selenium java -jar selenium-server-standalone-2.47.1.jar -role node -hub http://someip:4444/grid/register";
Process.Start(cmd.exe, Command1 + Command2);
}
When run, a cmd window just pops up and closes. There would be a notification if a node is registered, but nothing of that sort here. I think it is the syntax to run 2 commands that is the issue here.

The way to tell cmd to run multiple commands is to chain them using &&.
For ex, you could get your command prompt to do this:
echo hello && echo world
In your case, try using this statement:
Process.Start(Constants.CommandPrompt, string.Format("{0} && {1}", Command1,Command2));

Related

How can I change two items in one string via Windows command prompt and C#

Total newbie at C# and Windows command prompt, so please be patient with me.
This is my first time to write code to create an executable designed to alter the registry, as well as, the preferences in Chrome.
A little background first. The engineers at the company that I am contracted to, use an old program called Cadkey, which is used to view files of things that the company has been manufacturing since the 40s.
As many of you probably know, Chrome no longer allows for applets and other type of files to be viewed in the browser for security purposes, but most engineers at this company would rather use Chrome than IE.
As a result, I have been charged with the task of giving them the ability to open the file via an "application link" and some have also referred to this as "custom url protocol" like the following example:
some file
This allows the engineers to click on the file name in the browser, which then opens the file in the program Cadkey.
To accomplish this, I have to register the key within the user's registry, as well as, alter the preference file of Chrome, so that they are not bothered with the little window that alerts them that this file is about to use the Windows command prompt. I had no issue with the later, but my boss wanted the process to be as smooth as possible.
With all of this said, I was able to accomplish this with the following code:
using System;
using System.IO;
using Microsoft.Win32;
using Newtonsoft.Json.Linq;
namespace CadkeyRegAndPrefs
{
class Program
{
static void Main()
{
try
{
RegistryKey hkCurUsr = Registry.CurrentUser.OpenSubKey("Software\\Classes", true);
// Create a subkey named cadkey under HKEY_CURRENT_USER.
RegistryKey cadkey = hkCurUsr.CreateSubKey("cadkey", true);
cadkey.SetValue("", "URL:cadkey Protocol");
cadkey.SetValue("URL Protocol", "");
// Create data for the defltIcn subkey.
RegistryKey cadkeyDefltIcn = cadkey.CreateSubKey("DefaultIcon", true);
cadkeyDefltIcn.SetValue("", "");
cadkeyDefltIcn.SetValue("C:\\CK19\\Ckwin.exe", "-1");
// Create data for the cadkeyShell subkey.
RegistryKey cadkeyShell = cadkey.CreateSubKey("shell", true);
RegistryKey cadkeyShellOpen = cadkeyShell.CreateSubKey("open", true);
// Create data for the cadkeyCommand subkey.
RegistryKey cadkeyCommand = cadkeyShellOpen.CreateSubKey("command", true);
cadkeyCommand.SetValue("", "");
cadkeyCommand.SetValue("", "cmd /V:ON /C \"SET r=%1 & start C:\\CK19\\Ckwin.exe !r:cadkey:=!\"");
// Retrieve path of the current user
string path = System.Environment.ExpandEnvironmentVariables("%userprofile%");
string pathToPrefs = path + "\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Preferences";
// Have to create a JObject of the json file
JObject jsonObj = JObject.Parse(File.ReadAllText(pathToPrefs));
// Determine if the user has a protocol handler set and append cadkey set to false, otherwise, create node and set cadkey to false
var isExlcudedSchemes = jsonObj.SelectToken("protocol_handler.excluded_schemes");
if (isExlcudedSchemes != null)
{
jsonObj["protocol_handler"]["excluded_schemes"]["cadkey"] = false;
} else {
jsonObj.Add(new JProperty("protocol_handler", new JObject(
new JProperty("excluded_schemes", new JObject(
new JProperty("cadkey", new JObject()))))));
jsonObj["protocol_handler"]["excluded_schemes"]["cadkey"] = false;
}
// set the variable output and write the json content to the preferences file for Chrome
string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(pathToPrefs, output);
// Let the end user know that the operation was successful
Console.WriteLine("Cadkey registration installed successfully");
Console.WriteLine("\nPress any key to exit");
Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e.ToString());
}
}
}
}
The engineers have a little bootstrap modal, which gives them the instructions to download the exe, followed by double clicking the exe to install the registry keys and alter the Chrome prefs.
So what's the problem? The code registers the keys to the user's registry, as well as altering the Chrome preferences file, along with informing the user at the end that it was successful.
The problem is that some of the files have a space in the name, which then makes Cadkey prompt the user that the file cannot be found. Mainly because "%20" appears in the place of the space. I guess Cadkey was made at a time when urlencoding was not part of the design.
I have tried to alter the url via the command prompt, as I do with removing the string "cadkey:" from the param being passed to the command prompt:
cmd /V:ON /C \"SET r=%1 & start C:\\CK19\\Ckwin.exe !r:cadkey:=! & !r:%20= !\"
I have tried:
cmd /V:ON /C \"SET r=%1 & start C:\\CK19\\Ckwin.exe !r:cadkey:=! | !r:%20= !\"
I have tried:
cmd /V:ON /C \"SET r=%1 & start C:\\CK19\\Ckwin.exe !r:cadkey:=! & !r:%%20= !\"
I have tried using another var
cmd /V:ON /C \"SET r=%1 & !r:cadkey:=! & SET s=r start C:\\CK19\\Ckwin.exe !s:%20= !\"
While the command is successful in replace the string "cadkey:" - I have yet to replace both strings at the same time. I have tried too many things, but I am a newbie at this, any help would be appreciated.
Thanks in advance
After working with my boss on this last night, we finally found an answer, which is the following:
Change
cadkeyCommand.SetValue("", "cmd /V:ON /C \"SET r=%1 & start C:\\CK19\\Ckwin.exe !r:cadkey:=!\"");
To:
cadkeyCommand.SetValue("", "cmd /V:ON /C \"SET r=%1 & SET s=!r:cadkey:= ! & SET t=!s:%%20= ! & start C:\\CK19\\Ckwin.exe !t!\"");
The result is that the both the string "cadkey:" and the string "%20" are removed, with the string "%20" replaced by a space, which results in the following being passed to cadkey where you see the variable "t"

Send message to standalone Unity application from HTML or command prompt link?

Is there a way to send a message to Unity standalone build from external source? The source could be an html created file or a link through PDF or even from command prompt. I have not started anything since I need an idea of how to approach this.
I finally found a solution. Here is my C# script:
static string cmdInfo = "";
void Start ()
{
string[] arguments = Environment.GetCommandLineArgs();
foreach(string arg in arguments)
{
cmdInfo += arg.ToString() + "\n ";
}
}
void OnGUI()
{
Rect r = new Rect(5,5, 800, 500);
GUI.Label(r, cmdInfo);
}
and from the project build folder, I am running the following command from command prompt:
Halo2 --UserCreated -One
"Halo2" is basically the app name and other two are the arguments.
The first time I run the above command, it opens the app. Unfortunately the second time I run the app, it opens another instance of the same app.
Is there a way to make the command prompt pass the arguments to the same app without opening new one?

Use CMD commands in C# For showing Tasklist

I need to find the PID number for a process using C# and tasklist in the CMD.
the PID number needs to be put into a textbox in a c# form.
The code for finding the pid number in Command prompt is this.
for /f "tokens=1,2" %a in (' Tasklist /fi "imagename eq notepad.exe" /nh') do #echo %b
But I don´t know how to integrate CMD commands into C# winform.
You can achieve the same thing in .NET by using Process.GetProcessesByName and then outputting the process Id:
foreach (var p in Process.GetProcessesByName("notepad"))
{
Console.WriteLine(p.Id);
}
Alternatively, if you really want to use the cmd window and capture the output, you can create a process that will run cmd.exe and pass it the command line you want to execute (add a /C at the beginning, which tells cmd.exe to close the cmd window after running). You also want to RedirectStandardOutput, which allows you to capture the output of the command that was run. Then you can use proc.StandardOutput.ReadLine() to get each line that was returned:
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/C for /f \"tokens=1,2\" %a in " +
"('Tasklist /fi \"imagename eq notepad.exe\" /nh') do #echo %b",
RedirectStandardOutput = true,
UseShellExecute = false,
}
};
proc.Start();
proc.WaitForExit();
while (!proc.StandardOutput.EndOfStream)
{
Console.WriteLine(proc.StandardOutput.ReadLine());
}
You can certainly initiate a command prompt window ( Console ) and capture its stdout and stderr streams to grab the data and then parse it and show it in a windows forms control,
at the same time, usually in a case like this the Process class part of standard .NET Framework is used to retrieve any information of a running process on thw Windows machine,
have a look at this methos in MSDN for example: Process.GetProcessesByName or any other method of the Process class, that way you can do it without running any command in any console window.

cmd converting language other than English to junk

I'm making a uiautomator based application where the app touches the objects based on text.
I've written the uiautomator methods in Java and have made a C# app which asks the used which text to touch. I'm using cmd/adb to execute the uiautomator commands.
The problem comes when I change the phone language to something other than English. Cmd/adb replaces the text (in other language) with ???. It passes the same to uiautomator.
Is there a way I can make cmd understand the other language?
C# code
Process procToExecute = new Process();
procToExecute.StartInfo.FileName = "adb.exe";
procToExecute.StartInfo.Arguments = strCommand;
procToExecute.StartInfo.CreateNoWindow = true;
procToExecute.StartInfo.UseShellExecute = false;
procToExecute.StartInfo.RedirectStandardOutput = true;
procToExecute.StartInfo.RedirectStandardInput = true;
Thread.Sleep(1500);
procToExecute.Start();
procToExecute.WaitForExit();
where strCommand looks like this for other languages
adb shell uiautomator runtest UiAutomatorTest.jar -c com.lge.uiautomatorTest.UiAutomatorClass#UiEnterText -e edit संदेश%दर्ज%करें -e text को
and it shows like this on cmd
adb shell uiautomator runtest UiAutomatorTest.jar -c com.lge.uiautomatorTest.UiAutomatorClass#UiEnterText -e edit ?????%????%???? -e text ??

Displaying command in cmd console

I'm trying to run a command in cmd using C# and am having some difficulties. I'd like to be able to write the command to the cmd console so I can see what it's trying to run (I think there's some issue with the quotes or something, so if I could see the actual string in the command line, I'd be able to see exactly what the problem is). My code looks like this:
var processStartInfo = new ProcessStartInfo("cmd", "/c"+commandString);
processStartInfo.CreateNoWindow = true;
Process.Start(processStartInfo);
So basically, I just want to see the string commandString written in the console. Any help would be greatly greatly appreciated.
string CommandLineString = #"""C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe"" ""SELECT * FROM table where date >= '2009-01-01'"" queryout ""C:\Data\data.dat"" -S DBSW0323 -d CMS -n -T";
In this case, the problem is probably just your lack of a space after "/c".
var processStartInfo = new ProcessStartInfo("cmd", "/c " + commandString);
As for viewing in a command window, instead, you will probably be better off inspecting the Arguments property of your processStartInfo instance.
EDIT
Taking into account the command line details you posted, I believe this is what your issue is. Check out the following from cmd help:
If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:
If all of the following conditions are met, then quote characters
on the command line are preserved:
no /S switch
exactly two quote characters
no special characters between the two quote characters,
where special is one of: &<>()#^|
there are one or more whitespace characters between the
the two quote characters
the string between the two quote characters is the name
of an executable file.
Since you are using /c, you have quote and special char issues still. Try wrapping your entire commandString in a set of quotes.
Take this simple example for instance (creating temp.txt manually of course):
string commandString = #"""C:\WINDOWS\Notepad.exe"" ""C:\temp.txt""";
var processStartInfo = new ProcessStartInfo("cmd", "/c " + commandString);
The command line to be executed will be: /c "C:\WINDOWS\Notepad.exe" "C:\temp.txt", but this will fail since "C:\temp.txt" is not an executable.
If you wrap the whole thing in one last set of quotes, you should see the intended result:
string commandString = #"""""C:\WINDOWS\Notepad.exe"" ""C:\temp.txt""""";
var processStartInfo = new ProcessStartInfo("cmd", "/c " + commandString);
Resulting in a command line of: /c ""C:\WINDOWS\Notepad.exe" "C:\temp.txt"" and ultimately opening notepad with your test file.
That string is not "written" to the console, it's part of the argument list for a program you launch (which in this case happens to be cmd.exe). Since the console created is owned by that program, unless it wants to print its arguments for its own reasons (which it won't) this is not directly doable.
If you simply want to debug then why not inspect the value of commandString, or write it out into a log file?
If you absolutely need the command line to be displayed in the console then you could resort to hacks (run another intermediate program that prints the command line and then calls cmd.exe with it), but unless there is some other good reason to use this approach I would not recommend it.

Categories

Resources