Monitoring completed status of a remote cmd.exe process - c#

I am running a .bat file in computer A from computer B by using my form application using WMI to publish dash boards. The .bat file calls a command line utility tabcmd.exe multiple times and utility updates log file in computer A in the below location "C:\Users[UserName]\AppData\Roaming\Tableau\tabcmd.log"
I want to update my form application with the log file details in Computer B once the process is completed in computer A.
I am running the .bat file by using like below,
String path = #"C:\tabcmd.bat";
String machineName = textBox1.Text;
var processToRun = new[] { path };
var connection = new ConnectionOptions();
connection.Username = textBox3.Text;
connection.Password = textBox2.Text;
var wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\cimv2", machineName), connection);
var wmiProcess = new ManagementClass(wmiScope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
wmiProcess.InvokeMethod("Create", processToRun);
This .bat file publishes dashboards in computer B based on dynamic datasource parameters, so the run-time of the .bat file is unpredictable, in this case how do I ensure that .bat file is run or the updating log file is completed.
Is there any way to monitor this process by process ID? if so I can read the log file once my process is completed. the below is not helping me in this situation since cmd.exe is still running in the target computer A.
System.Diagnostics.Process prc = System.Diagnostics.Process.GetProcessById(10100, "CHORRL0110")
prc.WaitForExit ()
Thanks for your help!

Related

How to launch the atmx file programmatically in C#?

can someone please tell me why my line of code to execute an atmx file isn't working?
the code doesn't go further after opening the internet explorer :(
try
{
switch (status)
{
case true:
IWebDriver driver = new InternetExplorerDriver();
driver.Navigate().GoToUrl(#"http://www.rpachallenge.com/");
Console.WriteLine("get ATMX file...........");
string getATMX = String.Format("C:\\Users\\{0}\\Desktop\\VS Test Environment\\Testing.atmx", Environment.UserName);
Process.Start(getATMX);
SqlConnection connect = new SqlConnection();
connect.Open();
SqlCommand
the atmx file get info from sql and fills the fields on rpachallenge.com, capture the ending result then saves in sql.
The .atmx file isn't the executable itself, it's an script file which is executed by the Automation Anywhere runtime (AA.Player.exe) instead.
You need to ensure that "AA.Player.exe" is installed and is registered application for files with extension ".atmx" on the machine you're trying to execute. Hope that helps.
Atmx file runs on AAPlayer.exe, if you have Automation Anywhere installed you can execute ATMX by invoking AAPlayer.exe with atmx file path.
Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "C:\\Program Files (x86)\\Automation Anywhere\\Enterprise\\Client\\AAPlayer.exe";
p.StartInfo.Arguments = "/fD:\\bots\\mybot.atmx";
p.Start();

how to publish a mvc website that has python script in it

I'm working on a MVC.net website in which I use python script in it. I have a python file which I call it in order to get some results from it. The algorithm has been wrtiten in python and I have to call to get the result. If I want to execute python file, I have to call python.exe file which I call it like below and the result of calling file is string. When I run website locally it works fine but now I want to publish website to server and don't know how to upload python file in it.
Second question is that how should I change the path of a python.exe and python file to run on cpanel.
string python = #"C:\Users\Cebit\AppData\Local\Programs\Python\Python37\python.exe";
string myPythonApp = #"C:\Users\Cebit\Desktop\phase2-final.py";
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(python);
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.CreateNoWindow = true;
myProcessStartInfo.RedirectStandardOutput = true;
myProcessStartInfo.RedirectStandardError = true;
List<String> argv = new List<String>();
argv.Add(d1);
argv.Add(m1);
argv.Add(y1);
argv.Add(h1);
argv.Add(min1);
argv.Add(d2);
argv.Add(m2);
argv.Add(y2);
argv.Add(h2);
argv.Add(min2);
argv.Add(favor);
argv.Add(budget.ToString());
myProcessStartInfo.Arguments = string.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12}", myPythonApp, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]);
Process myProcess = new Process();
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();
StreamReader myStreamReader = myProcess.StandardOutput;
myProcess.WaitForExit();
string myString = myStreamReader.ReadToEnd();
myProcess.Close();
My question is how should I publish a website which I have to run python.exe and python file in a server. Should I have to do something extra in order to run python.exe file in server ? I'm new to use py script in mvc and don't know how to publish it on cpanel
I would suggest using ENVIRONMENT variables to set the path. This would allow you to have different paths for local development vs deployed. Hopefully, then CPANEL allows you to set these variables. Otherwise, you will need to deploy to a VM that you have more control of.
As an example your path string would now be:
string python = Environment.GetEnvironmentVariable("python_exe");
string myPythonApp = Environment.GetEnvironmentVariable("app_python_script");
In terms of actually deploying it, add it as an item and set it to Copy and the py script should be in the bin directory.

Process.Start on gpg.exe just hangs

I'm trying to run gpg.exe from C# using ProcessStartInfo()/Process.Start(). When I run it from cmd it works. I copy and paste the exact command I ran from cmd into my C# app and gpg.exe opens but it just hangs. Doesn't show any text in the window and just sits there doing nothing. What could be going on?
var gpg = new ProcessStartInfo(#"C:\GnuPG\gpg.exe", #"--batch --yes --output c:\applications\development\invoicedecryption\temp\invoice.csv --passphrase-fd <C:\GNUPG\pasfraz.txt --decrypt C:\applications\development\invoicedecryption\temp\Invoices.csv.pgp");
var prs = new Process();
prs.StartInfo = gpg;
prs.Start();

How to run a command prompt on a shared server? [duplicate]

How can I start a process on a remote computer in c#, say computer name = "someComputer", using System.Diagnostics.Process class?
I created a small console app on that remote computer that just writes "Hello world" to a txt file, and I would like to call it remotely.
Console app path: c:\MyAppFolder\MyApp.exe
Currently I have this:
ProcessStartInfo startInfo = new ProcessStartInfo(string.Format(#"\\{0}\{1}", someComputer, somePath);
startInfo.UserName = "MyUserName";
SecureString sec = new SecureString();
string pwd = "MyPassword";
foreach (char item in pwd)
{
sec.AppendChar(item);
}
sec.MakeReadOnly();
startInfo.Password = sec;
startInfo.UseShellExecute = false;
Process.Start(startInfo);
I keep getting "Network path was not found".
Can can use PsExec from http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx
Or WMI:
object theProcessToRun() = { "YourFileHere" };
ManagementClass theClass = new ManagementClass(#"\\server\root\cimv2:Win32_Process");
theClass.InvokeMethod("Create", theProcessToRun);
Use one of the following:
(EDIT) Remote Powershell
WMI (see Ivan G's answer)
Task Scheduler API (http://msdn.microsoft.com/en-us/library/windows/desktop/aa383606%28v=vs.85%29.aspx)
PsExec
WshRemote object with a dummy script. Chances are, it works via DCOM, activating some of scripting objects remotely.
Or if you feel like it, inject your own service or COM component. That would be very close to what PsExec does.
Of all these methods, I prefer task scheduler. The cleanest API of them all, I think. Connect to the remote task scheduler, create a new task for the executable, run it. Note: the executable name should be local to that machine. Not \servername\path\file.exe, but c:\path\file.exe. Delete the task if you feel like it.
All those methods require that you have administrative access to the target machine.
ProcessStartInfo is not capable of launching remote processes.
According to MSDN, a Process object only allows access to remote processes not the ability to start or stop remote processes. So to answer your question with respect to using this class, you can't.
An example with WMI and other credentials as the current process, on default it used the same user as the process runs.
var hostname = "server"; //hostname or a IpAddress
var connection = new ConnectionOptions();
//The '.\' is for a local user on the remote machine
//Or 'mydomain\user' for a domain user
connection.Username = #".\Administrator";
connection.Password = "passwordOfAdministrator";
object[] theProcessToRun = { "YourFileHere" }; //for example notepad.exe
var wmiScope = new ManagementScope($#"\\{hostname}\root\cimv2", connection);
wmiScope.Connect();
using (var managementClass = new ManagementClass(wmiScope, new ManagementPath("Win32_Process"), new ObjectGetOptions()))
{
managementClass.InvokeMethod("Create", theProcessToRun);
}
I don't believe you can start a process through a UNC path directly; that is, if System.Process uses the windows comspec to launch the application... how about you test this theory by mapping a drive to "\someComputer\somePath", then changing your creation of the ProcessStartInfo to that? If it works that way, then you may want to consider temporarily mapping a drive programmatically, launch your app, then remove the mapping (much like pushd/popd works from a command window).

Can't Delete folder as it's in use.

I have an issue with an auto update software that I am trying to make. The application runs as a server application and checks via FTP for updates and downloads them if there is a newer version available. This then unzips a folder called update in the programs root directory. it then launches a file called update.bat that does any file copying etc that I may need to do for that update. Once this is finished the update.bat launches the new server application. Once the program goes to check for updates again it is suppose to delete the update directory that is in the root directory of the server application as well as the update.rar file that was downloaded from the update server. All of this works perfectly except the folder is being used and will not delete. I have read all kinds of things about releasing the handle and changing the current directory etc.. but just can't seem to get it to work. I would appreciate someone helping me out here. Here is the code for this update.
private void Form1_Load(object sender, EventArgs e)
{
foreach (string s in Directory.GetDirectories("C:/my update dir"))
{
if (s.Contains("Instance"))
{
var _instance = Regex.Match(s, #"\d+");
Process p = new Process();
ProcessStartInfo pinfo = new ProcessStartInfo();
pinfo.FileName = "cmd.exe";
pinfo.WorkingDirectory = "C:/mySQL/bin";
pinfo.Arguments = "/C mysql.exe -u** -p** dbnameHere" + _instance.ToString() +
" < \"C:/my update dir/update/update.sql\"";
p.StartInfo = pinfo;
p.Start();
p.WaitForExit();
p.Close();
p.Dispose();
Directory.SetCurrentDirectory("C:/");
}
}
Directory.SetCurrentDirectory("C:/");
this.Dispose();
Application.Exit();
}
I'm going to guess that your problem is here:
Once this is finished the update.bat launches the new server
application.
Windows is going to "lock" the directories all the way down to the .BAT file. So if the .BAT runs a server process from that directory, that process is going to inherit the CWD and file descriptors of the calling process.
It's not clear from your code that this is what's happening, but you may also want to try changing the CWD prior to spawning the process.

Categories