Running a python script on C# not working - c#

I have this code that I'm trying to run a Python script. It works correctly when I do it manually via the command prompt but if I try to do it via a button click in a C# Windows form it doesn't work.
private void btnGenerateAndrowarn_Click(object sender, EventArgs e) {
string[] filePaths = Directory.GetFiles(#"C:\Users\User1\Desktop\Android Tools\androwarn\Samples", "*.apk");
foreach (string fileName in filePaths) {
ProcessStartInfo startInfo;
Process process;
string directory = #"C:\Users\User1\Desktop\Android Tools\androwarn\";
string script = "androwarn.py";
startInfo = new ProcessStartInfo("python");
startInfo.WorkingDirectory = directory;
startInfo.Arguments = directory + script + " -i " + fileName + " -r html -v 3";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
process = new Process();
process.StartInfo = startInfo;
process.Start();
}
}

Most likely is that python is not in your %PATH%.

Related

Command won't run in Command Prompt

When users click on a button, I want it to run the logon script(launching from server), but each computer in different servers, so I get the server name. But the netlogon.StartInfo.Arguments = slnres + #"/c \netlogon\logon.cmd"; line is not working as it should be. It should run the logon.cmd on the PC(mapping network drivers, printers, etc), and then the CMD should close.
private void MapNetwork_Click(object sender, EventArgs e)
{
Process sln = new Process();
sln.StartInfo.UseShellExecute = false;
sln.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
sln.StartInfo.FileName = "cmd.exe";
sln.StartInfo.Arguments = "/c echo %logonserver%";
sln.StartInfo.RedirectStandardOutput = true;
sln.Start();
string slnres = sln.StandardOutput.ReadToEnd();
label1.Text = slnres;
Process netlogon = new Process();
netlogon.StartInfo.UseShellExecute = false;
netlogon.StartInfo.FileName = "cmd.exe";
netlogon.StartInfo.Arguments = slnres + #"/c \netlogon\logon.cmd";
netlogon.Start();
}
A couple things:
You don't need to run a command prompt to get an environment variable. You can use Environment.GetEnvironmentVariable.
Your Arguments property for your call to logon.cmd is being constructed into this:
\\myserver/c \netlogon\logon.cmd
When I think you want this:
/c \\myserver\netlogon\logon.cmd
So make sure you put slnres at the right place in your string. Your code should look like this:
private void MapNetwork_Click(object sender, EventArgs e)
{
string slnres = Environment.GetEnvironmentVariable("logonserver");
label1.Text = slnres;
Process netlogon = new Process();
netlogon.StartInfo.UseShellExecute = false;
netlogon.StartInfo.FileName = "cmd.exe";
netlogon.StartInfo.Arguments = "/c " + slnres + #"\netlogon\logon.cmd";
netlogon.Start();
}
i am a little confused about your question and i am not rly sure if i understand you correctly. some time ago i made a program where i had to run few powershell commands, so i made a class for it. redirected to your button it would look like that:
(and remember you need the fqdn to your file location => Reading File From Network Location)
using System.Diagnostics;
//class lvl scope vars
string output;
string ErrorOutput;
private void MapNetwork_Click(object sender, EventArgs e)
{
//define process arguments
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"cmd.exe";
startInfo.Arguments = #"FQDN path to your file on the server; exit";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
//start process
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
//outpunt handling
if (string.IsNullOrEmpty(ErrorOutput))
{
return output;
}
else
{
return ErrorOutput;
}
}
first of all i would check if your application is able to open the file one the shared network location. (server available? access rights to server? serer mapped?)
after that you can check if he is able to start the file locally. (does it need admin rights to run the *.cmd, *.bat file)
now you can check if your application runs it correctly.

"Multi-Step" commands while using CMD.exe in C#

I'm trying to use "multi-step" command in a c# script, for example the command "net user usrname *" contains 3 steps to enter a password and then validate, i don't know if it is possible to send extra arguments while the Process is running
My code:
Process p = new Process();
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C " + command;
p.StartInfo.WorkingDirectory = startupFolder;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
p.Start();
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
You would concatenate each command with "&". For example, "cmd /k echo Test 1 & echo test 2".
Edit:
I created a remote control/remote admin solution a while back that uses this same technique to allow you to run batch and PowerShell scripts against remote computers via the web portal. As shown in the below screenshot, it works.
The C# that executes the command can be found here: https://github.com/Jay-Rad/InstaTech_Client/blob/master/InstaTech_Service/Socket.cs#L614
if (cmdProcess == null || cmdProcess.HasExited)
{
var psi2 = new ProcessStartInfo("cmd.exe", "/k " + command);
psi2.RedirectStandardOutput = true;
psi2.RedirectStandardInput = true;
psi2.RedirectStandardError = true;
psi2.UseShellExecute = false;
psi2.WorkingDirectory = Path.GetPathRoot(Environment.SystemDirectory);
cmdProcess = new Process();
cmdProcess.StartInfo = psi2;
cmdProcess.EnableRaisingEvents = true;
cmdProcess.OutputDataReceived += async (object sender, DataReceivedEventArgs args) =>
{
jsonMessage.Status = "ok";
jsonMessage.Output = args.Data;
await SocketSend(jsonMessage);
};
cmdProcess.ErrorDataReceived += async (object sender, DataReceivedEventArgs args) =>
{
jsonMessage.Status = "ok";
jsonMessage.Output = args.Data;
await SocketSend(jsonMessage);
};
cmdProcess.Start();
cmdProcess.BeginOutputReadLine();
cmdProcess.BeginErrorReadLine();
}
else
{
cmdProcess.StandardInput.WriteLine(command);
}

Create a process that execute powershell in C# but failed outpt

I dont know where is my missing. Even it dit not write out log. Could you fix my test code:
private void button1_Click(object sender, EventArgs e)
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe";
startInfo.Arguments = #"/C Import-Module AppLocker;Set-AppLockerPolicy -XMLPolicy 'iPolicy.xml' > C:\log.txt";
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
//startInfo.RedirectStandardOutput = true;
//startInfo.RedirectStandardError = true;
//startInfo.UseShellExecute = false;
//startInfo.CreateNoWindow = false;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
}
catch (Exception ex) {
Debug.Print("Error: " + ex.Message);
}
}
Finally got it to work, code should look like this:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"cmd.exe";
startInfo.Arguments = #"/C powershell.exe /C Import-Module AppLocker;Set-AppLockerPolicy -XMLPolicy 'iPolicy.xml' > C:\log.txt";
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
This worked for me! You can use full paths to cmd.exe and powershell.exe if you feel necessary, it's not that important here.

How I can call the installer.ini arguments in a silent installer?

I use this code to install in silent mode a program :
private void Install_Click(object sender, EventArgs e)
{
string path = AppDomain.CurrentDomain.BaseDirectory.ToString();
string configfilename = path + "config.ini";
string installerfilename = path + "installer.ini";
string configtext = File.ReadAllText(configfilename);
string installertext = File.ReadAllText(installerfilename);
}
Process process = new Process();
process.StartInfo.FileName = #"D:\Matlab\NSIS\R2008a\win64\setup.exe";
process.StartInfo.Arguments = "/quiet";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
process.WaitForExit();
}
But this code made setup.exe to run, but doesn't use the installer.ini where I have the license number, outlog number ...How I can do this, to use the arguments of installer.ini for a silent installer of Matlab program ?
Also I tried this :
Process process = new Process();
process.StartInfo.FileName = #"D:\Matlab\NSIS\R2008a\win64\setup.exe";
process.StartInfo.Arguments = #"C:\temp\installer.ini";
process.StartInfo.Arguments = "/quiet";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
process.WaitForExit();
As far as I understood
http://www.mathworks.com/matlabcentral/answers/106140-how-do-i-utilize-silent-activation-using-activate-ini
http://www.mathworks.com/help/install/ug/install-noninteractively-silent-installation.html
the installer wants -if key and installer.ini file, so the C# syntax will be
// Put IDisposable into using
using (Process process = new Process()) {
// The installer itself
process.StartInfo.FileName = #"D:\Matlab\NSIS\R2008a\win64\setup.exe";
// suggested (see links above) arguments
process.StartInfo.Arguments = #"-if C:\temp\installer.ini";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
process.WaitForExit();
}

How to pipe output from C# application using cmd to text?

I'm running an app that uses a console app in the background
When I do this in cmd read-info.exe Myfile.file >fileinfo.txt it will create the file fileinfo.txt in the route folder.
But when I do it in code nothing happens, why?
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog theDialog = new FolderBrowserDialog();
theDialog.RootFolder = System.Environment.SpecialFolder.MyComputer;
if (theDialog.ShowDialog() == DialogResult.OK)
{
textBox1.Text = theDialog.SelectedPath.ToString();
string command = "read-info.exe " + textBox1.Text +"> File.txt";
string retur = CMD(command);
}
}
static string CMD(string args)
{
string cmdbat = "cd " + Application.StartupPath.Replace("\\", "/") + "\r\n";
cmdbat += args + " >> out.txt\r\n";
cmdbat += "exit\r\n";
File.WriteAllText("cmd.bat", cmdbat);
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.Arguments = "";
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Application.StartupPath;
startInfo.CreateNoWindow = true;
startInfo.FileName = Application.StartupPath + "\\cmd.bat";
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
System.Threading.Thread.Sleep(5000);
string cmdOut = File.ReadAllText("out.txt");
File.Delete("cmd.bat");
File.Delete("out.txt");
return cmdOut;
}
See this - I tnink it is what necessary: http://www.dotnetperls.com/redirectstandardoutput
Copied from the link above:
using System;
using System.Diagnostics;
using System.IO;
class Program
{
static void Main()
{
//
// Setup the process with the ProcessStartInfo class.
//
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"C:\7za.exe"; // Specify exe name.
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
//
// Start the process.
//
using (Process process = Process.Start(start))
{
//
// Read in all the text from the process with the StreamReader.
//
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
Console.Write(result);
}
}
}
}
use cmd /C for running console commands.
string command = "cmd /C read-info.exe " + textBox1.Text +"> File.txt";
Got It Working Thanks to #crashmstr
it outputs file as out.txt so just had to comment out File.Delete("out.txt");

Categories