Controlling 2nd cmd window - c# - c#

I am trying to use DB2's Command Line processor. When using it on the command line, I enter: db2cmd then a 2nd window opens where I can connect to the database and submit queries. I am attempting to write a wrapper for the CLP and when I access the command line, it opens the DB2 CLP in a 2nd window and I can't figure out how to send arguements to the new window. Here is what I have:
static void Main(string[] args)
{
var p = new Process();
var info = new ProcessStartInfo();
info.FileName = "db2cmd";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;
p.StartInfo = info;
p.Start();
using (var sw = p.StandardInput)
{
sw.WriteLine("DB2 CONNECT TO dbname USER \"username\" USING \"password\"");
sw.WriteLine("DB2 SELECT * FROM SPYPRD.CLMDTL FETCH FIRST 10 ROWS ONLY");
}
}

Maybe better to use an alternative interface (e.g. the ADO .net interface) from C# instead of using the CLP.
To use commands like LOAD and EXPORT etc, from ADO (or jdbc/odbc etc) you invoke them via stored procedure SYSPROC.ADMIN_CMD() if the Db2-server runs on Linux/Unix/Windows. Pay attention to the details in the documentation for that stored procedure because all file names are relative to the Db2-server (not the workstation).
Not sure if CLP accepts stdin redirection for passwords - you would also need to parse the stdout, maybe messy.
If the database is local then you can use the CLP without needing a userid/password on the CONNECT statement. If you wish to connect with different credentials use runAs to specify the credentials independently of the CLP, to avoid needing to send arguments to the CLP.
If the database is remote and is on Linux/Unix/Windows, best to use an alternative interface than CLP (e.g. ADO etc), or consider shipping the script to the remote-server to run locally on the Db2-LUW server as the required-user again avoiding passwords(e.g. if the Db2-server runs on Linux/Unix/Windows, use tools equivalent to psexec or ssh etc).

Related

Mongo. C#. How can i execute string as mongo query

Let's say I have a string. " db.getCollection("somecollection").find({})". Can I execute this string as a query in C#? i.e. I get a string. And I just execute it as a query but in c#
I just want like this
string query = "db.getCollection("somename")";
Mongo.execute(query);
no, the best you can do in this context is to use db.RunCommand<BsonDocument>("{ ping : 1 }") (c#) which is close to the shell db.runCommand({ ping : 1 })
UPDATE:
you may look at this as well How to execute mongo commands through shell scripts?, I'm not familiar with this and it doesn't work for me on windows and 5.0 server in most of the cases mentioned there other than simple one: mongo --eval "printjson(db.serverStatus())", but if you will be able to make this suggested script mongo < script.js (or similar) work in, for example, the shell, you will be able to put your random query in this file(script.js) and then, add this file as argument into Process creating similar to:
using (var process = new Process())
{
// arguments below may require the whole path to the files
process.StartInfo.Arguments = "script.js";
process.StartInfo.FileName = "mongo";
process.Start();
}
to read results, you will need analyzing process.StandardOutput/process.StandardError stream.

How to display a multi-line output from cmd in c#

I need my c# program to run a cmd query to show all sql services and then display them in a message box. In the situation I will be running this in, there will frequently be more than one and the names may be different each time.
"Wmic service where (PathName like '%Binn\sqlservr%') get caption, name" displays the information I need but there are multiple lines returned. the WriteNote() method is one that writes the information to a textbox in the program.
I have tried everything I can find on Google and nothing seems to be working.
private void DoListSQLServices()
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
//startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "Wmic service where (PathName like '%Binn\\sqlservr%') get caption, name";
process.StartInfo = startInfo;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.Start();
string output = process.StandardOutput.ReadToEnd();
this.WriteNote(output);
process.WaitForExit();
}
When I run this code I get this:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
{file location of project}\bin\Debug>
and a pbd file is put in the debug folder.
What I want is for it to show the caption and name of the SQL services like if you run that command through cmd manually. Ultimately the user will type one of them in for the program to restart them but I would rather have the program display the list than have the user go to Services in windows and search for them manually.
Thanks in advance!
As mentioned by Noodles in the comments, it's much better to do this via the WMI support in .NET. One of the fairly direct methods for this is to use the ManagementObjectSearcher class to execute an ObjectQuery against the WMI data.
Create a new console application. Add a reference for the System.Management assembly to and add using System.Management; to the top of your program.cs file.
Now add the following code:
static void Main()
{
// Create a scope (connection to WMI)
var scope = new ManagementScope(#"\\localhost\root\cimv2");
// Create query
var query = new ObjectQuery(#"SELECT Name,Caption FROM Win32_Service WHERE PathName like '%Binn\\sqlserv%'");
// Create a search to run the query against the scope
using (var search = new ManagementObjectSearcher(scope, query))
{
// Iterate through the query results
foreach (var item in search.Get())
{
// get values, all strings in this case
string name = (string)item["Name"];
string caption = (string)item["Caption"];
Console.WriteLine("{0}\t{1}", name, caption);
}
}
}
Note that the ObjectQuery query syntax is a little different to the WMIC syntax. It's called WQL (WMI Query Language) and is heavily modelled on SQL.
Hopefully you can adapt the above for your own use fairly easily. Just be careful with the actual type of the fields you're fetching. Here's a list of properties for Win32_Service objects.

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.

How continuously communicate to Cmd?

I found how to open cmd in C#.
But I can use Inputstream only once.
Create Cmd Process
ProcessStartInfo CmdInfo = new ProcessStartInfo();
Process cmd = new Process();
CmdInfo.FileName = #"cmd";
CmdInfo.WindowStyle = ProcessWindowStyle.Hidden;
CmdInfo.CreateNoWindow = true;
CmdInfo.UseShellExecute = false;
CmdInfo.RedirectStandardInput = true;
CmdInfo.RedirectStandardOutput = true;
CmdInfo.RedirectStandardError = true;
cmd.EnableRaisingEvents = false;
cmd.StartInfo = CmdInfo;
cmd.Start();
Now we can use cmd.StandardInput and cmd.StandardOutput.
Use Cmd
// Use cmd 1
cmd.StandardInput.WriteLine("cd");
cmd.StandardInput.Close(); // if don't close, I can't get output
Console.WriteLine( cmd.StandardOutput.ReadToEnd() ); // Done!
// Use cmd 2
cmd.StandardInput.WriteLine("cd C:\"); // It will occure ObjectDisposedException
I want solve this problem.
I don't think you're going to get far with that approach. The code is a hint ProcessStart ! It's a new process! After you've started the process it's completely seperate to the one in which your code resides, the only way you would be able to communicate with this new process is via COM or remoting or some other inter application communication channel... MSMQ etc.
As far as I know the cmd (command prompt) offers none of these.
I think you'll want to study up on powershell...
Calling PowerShell From C#
http://www.codeproject.com/Articles/18229/How-to-run-PowerShell-scripts-from-C
etc etc
The command shell executable will not process commands from a redirected standard input until the input is closed.
You have three choices:
Create a new process for each command.
Pipeline all of the commands that you want to execute, then close the standard input handle.
Create a batch file containing all of the commands and then execute that.
If you choose to create a new process for each command, use cmd.exe's "/C" command line switch to execute the command rather than passing it through standard input.

How can I create an SSH connection from a C# application?

I am working on creating a GUI to interface with a Citrix XEN server. I dont know how to execute commands from my within my application on my widows system on the XEN Server.
I was thinking using SSH but again I dont know how. Does anyone have an example of how to do this? How to establish a SSH tunnel when the user pushes a button? I want to be able to run the command xe vm-list and then display the output in a label. Thats just to start my next one will be to create a VM and name is what the user wants, but for now I just need to figure out how to execute commands on the XEN Server.
I have used SharpSSH with great success.
This can be downloaded from http://www.tamirgal.com/blog/page/SharpSSH.aspx.
Finding yourself an ssh component will allow you to do more meaningful things, but at the base level, you can do something like this:
public void ExecuteExternalCommand(string command)
{
try
{
// process start info
System.Diagnostics.ProcessStartInfo processStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
processStartInfo.RedirectStandardOutput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.CreateNoWindow = true; // Don't show console
// create the process
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = processStartInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
}
catch (Exception exception)
{
//TODO: something Meaninful
}
}
Which will let you run arbitrary external executables via the cmd.exe interface and then respond to it.
Here's some Links:
Example Code's SSH Component
[MSDN Process Class docs][2]

Categories