I have a C# program that is trying to call a bat file in the project folder. Here is the code which is calling the bat file:
protected void btnHotFolder_Click(object sender, EventArgs e)
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.Verb = "runas";
string path = System.Web.Hosting.HostingEnvironment.MapPath("~/Abbyy_Script/restart-hotfolder.bat");
startInfo.FileName = path;
Process.Start(startInfo);
}
catch (Exception ex)
{
log.Error("Batch file error");
log.Error(ex.InnerException.Message);
log.Error(ex.InnerException.StackTrace);
}
}
I have read on the forum that some have suggested giving the IIS user folder access rights to the folder containing the bat file. Tried but no avail..
This is part of the project structure showing where the bat file resides:
project - Abbyy_Script - restart-hotfolder.bat
In the bat file, I am currently testing it with notepad++ exe:
taskkill /im notepad++.exe
TIMEOUT 2
START "" "C:\Program Files\Notepad++\notepad++.exe"
You should improve your batch file:
taskkill /f /im notepad++.exe /t
timeout /t 2 /nobreak
IF EXIST "%ProgramFiles(x86)%\Notepad++\notepad++.exe" (
start "" "%ProgramFiles(x86)%\Notepad++\notepad++.exe"
)
IF EXIST "%ProgramFiles%\Notepad++\notepad++.exe" (
start "" "%ProgramFiles%\Notepad++\notepad++.exe"
)
The C# code needs to be improved too:
protected void btnHotFolder_Click(object sender, EventArgs e)
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
string path = System.Web.Hosting.HostingEnvironment.MapPath("~/Abbyy_Script/restart-hotfolder.bat");
startInfo.FileName = path;
Process.Start(startInfo);
}
catch (Exception ex)
{
log.Error("Batch file error");
log.Error(ex.InnerException.Message);
log.Error(ex.InnerException.StackTrace);
}
}
Related
This question already has answers here:
Restart Server from ASP.NET application when AppPool is ran under LocalSystem or LocalService account
(2 answers)
Shutdown or Restart Machine In C# and ASP.NET
(1 answer)
Closed 3 years ago.
I have a web app c # hosted on IIS on a computer with windows server 2008, I ran a command on a windows server cmd through C#, but it doesn't work, I tried it locally on my computer and the command works, I don't know why it doesn't work on the computer with windows server, I use this source code,I put a log but doesn't throw any error.
protected void btnReboot_Click(object sender, EventArgs e)
{
try
{
//StartShutDown("-l");
StartShutDown("-f -r -t 5");
Log2("MNS OK");
}
catch (Exception ex)
{
Log2("MNS ERROR " + ex.ToString());
}
}
private static void StartShutDown(string param)
{
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = "cmd";
proc.WindowStyle = ProcessWindowStyle.Hidden;
proc.Arguments = "/C shutdown " + param;
Process.Start(proc);
}
You can actually capture the error output from the process that was launched by redirecting the standard error. An example would be like this:
private static void StartShutDown(string param)
{
Process p = new Process();
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true; // You need to set this
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C shutdown " + param;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.Start();
string stdoutx = p.StandardOutput.ReadToEnd();
string stderrx = p.StandardError.ReadToEnd(); // here is where you get the error output string
p.WaitForExit();
Console.WriteLine("Exit code : {0}", p.ExitCode);
Console.WriteLine("Stdout : {0}", stdoutx);
Console.WriteLine("Stderr : {0}", stderrx);
}
Once you have the Stderr you can check its contents and, if it's not empty then you know an error occurred.
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.
I am having an issuing trying to get a form app on visual studio 19 to execute a cmd on command line for converting a video from mp4 to avi.
I am using ffmpeg for this but everytime I compile it wont pick anything up.
I have ran the argument through command line and it converts the video just fine. The path as far as I am aware is correct so I am not sure why the compiler wont pick up on any files.
private void Button1_Click(object sender, EventArgs e)
{
string cmdString = "c:\ffmpeg\bin";
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "ffmpeg.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = cmdString + $"-i shatner.mp4 shatner.avi";
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
}
}
The error I am getting:
"The system cannot find the specified file"
Also I would have put a try catch block around the Process.Start but it doesnt matter since it is still throwing the exception.
Your fileName and arguments are specified incorrectly. Please see below.
private void button1_Click(object sender, EventArgs e)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "c:\\ffmpeg\\bin\\ffmpeg.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "-i shatner.mp4 shatner.avi";
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
using (Process exeProcess = Process.Start(startInfo))
{
string error = exeProcess.StandardError.ReadToEnd();
string output = exeProcess.StandardError.ReadToEnd();
exeProcess.WaitForExit();
MessageBox.Show("ERROR:" + error);
MessageBox.Show("OUTPUT:" + error);
}
}
I have used the following code to copy the folder from one path to another path. If the copying file is already exists it does not replace the existing file. Is there any command available with this like xcopy/replace?
private static void ProcessXcopy(string SolutionDirectory, string TargetDirectory)
{
// Use ProcessStartInfo class
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
//Give the name as Xcopy
startInfo.FileName = "xcopy";
//make the window Hidden
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
//Send the Source and destination as Arguments to the process
startInfo.Arguments = "\"" + SolutionDirectory + "\"" + " " + "\"" + TargetDirectory + "\"" + #" /e /y /I";
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch (Exception exp)
{
throw exp;
}
}
Referrence: http://www.c-sharpcorner.com/UploadFile/jawedmd/xcopy-using-C-Sharp-to-copy-filesfolders/
xcopy should overwrite files by default (and the /Y flag suppresses prompts for confirmation). Could it be that the destination file is read-only? In that case, you also need to specify the /R flag.
The note at http://support.microsoft.com/kb/240268 describes /R as an additional parameter to overwrite read-only files. Have you tried adding that?
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%.