I am writing a c# program and I want to run (npm install) and (npm run build) from the c# code.
I tried
public static Boolean BuildNpm()
{
Console.WriteLine("start process method?");
var proc = new System.Diagnostics.Process();
proc.StartInfo.WorkingDirectory="../../frontend/";
proc.StartInfo.FileName = "/bin/bash";
proc.Start();
//npm install
//npm run build
//exit
proc.WaitForExit();
Console.WriteLine("Done?");
return (proc.ExitCode == 0) ? true : false;
}
I was able to create a shell that ask for command and I add the commands I want but I want the commands in the program automatically.
Why do you need to run bash to run the commands? Shouldn't it work to run npm directly from your program?
public static Boolean BuildNpm()
{
Console.WriteLine("start process method?");
var proc = new System.Diagnostics.Process();
proc.StartInfo.WorkingDirectory="../../frontend/";
proc.StartInfo.FileName = "/path/to/npm";
proc.StartInfo.Arguments = "install";
proc.Start();
proc.WaitForExit();
proc.StartInfo.Arguments = "run build";
Console.WriteLine("Done?");
return (proc.ExitCode == 0) ? true : false;
}
You should add some error handling if either execution of npm fails, as well.
Related
enter image description here
I setting my WorkerService appsettings.json like below
"AppRun": {
"App1": {
"AppName": "CheckDataForm",
"AppPath": "D:\\2021-Project\\Project\\CheckDataForm-MSSQL\\CheckDataForm\\bin\\Debug\\net5.0-windows\\CheckDataForm.exe"
},
"App2": {
"AppName": "notepad++",
"AppPath": "C:\\Program Files\\Notepad++\\notepad++.exe"
},
and call the app like this:
//i is foreach count
var AppName = _config["AppRun:App"+i+":AppName"];
var AppPath = _config["AppRun:App" + i + ":AppPath"];
//check file exist
var fileExist = System.IO.File.Exists(AppPath);
if ( !String.IsNullOrEmpty (AppName) && !String.IsNullOrEmpty(AppPath) &&
fileExist )
{
//find APP
var processApp = Process.GetProcessesByName(AppName);
//can't find app
if (processApp.Length <=0 )
{
try
{
Process proc = new Process();
proc.StartInfo.FileName = AppPath;
proc.StartInfo.WorkingDirectory =
System.IO.Path.GetDirectoryName(AppPath);
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.WindowStyle =
ProcessWindowStyle.Maximized;
proc.Start();
}
catch (Exception ex)
{
var error = ex;
}
}
}
the Process can Start notepad++ And CheckDataForm , but notepad++ And CheckDataForm AP run in [Background processes] , I need AP Run in [Apps]
How To Executable under Apps , Not in Background Process
, like image show
You can execute the program using the CMD:
Process proc = new Process();
proc.StartInfo.FileName = "CMD";
proc.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(AppPath);
proc.StartInfo.Arguments = "/C "+AppPath;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
proc.Start();
That way will be ran as if you run it as the logged user.
Since you are using a Service, you could use a predefined TASK from the Task Scheduler to run the program:
var ts = new TaskService();
var task = ts.FindTask("mainTVMTask2");
task.Run();
The nugget package used was:
TaskScheduler by David Hall
This last code is being used right now to keep an app running, the service is checking if the process is in the process list, if its not, will run that task, previusly created in the Task Scheduler.
You might choose the user that will be logged in order to run the process instead of the service that will run with System Account.
The action is a standard run command to start the program that you need.
I have the following C# code:
private void executeBat(string batfile)
{
ProcessStartInfo psi = new ProcessStartInfo(batfile);
psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.UseShellExecute = false;
psi.RedirectStandardError = false;
psi.RedirectStandardOutput = false;
Process p = Process.Start(psi);
p.WaitForExit();
if (p.ExitCode != 0)
{
throw new Exception("bat script failed with exit code " + p.ExitCode + ".");
}
p.Close();
}
string batFile = #"C:\Data\SomeFolder\AnotherFolder\SomeBat.bat";
executeBat(batFile);
That runs a .bat script that looks like this:
"c:\Program Files (x86)\SomeThirdParty\SomeExe" >C:\Data\SomeLog.txt 2>&1
set exitcode=%errorlevel%
echo "error return is %exitcode%" >>C:\Data\SomeLog.txt
exit /b %exitcode%
The SomeLog.txt file looks like this:
"error return is 0"
But it appears that the .bat does not really exit because the c# code never returns from p.WaitForExit().
Other people have experienced this problem but my report is different because I am not reading stdout or stderr.
This does not happen consistently. Perhaps 1 out of 1000 executions.
Here is a big clue...
It only happens when I run the c# code from Task Scheduler. When I run it from the commandline I have never gotten the issue.
How do I use wait for exit when using C# to use a vbs file to run bat file?
Currently, it does not wait until the vbs is done. I have added the vbs code.
private string SetBackUpFiles(string vbsFileName, CheckBox BackUpCheckBox)
{
Process proc = null;
string BackUpCompleted;
BackUpCompleted = "Back up function error";
try
{
proc = new Process();
proc.StartInfo.WorkingDirectory = vbsDir;
proc.StartInfo.FileName = vbsFileName;
proc.StartInfo.CreateNoWindow = false;
proc.EnableRaisingEvents = true;
proc.Start();
proc.WaitForExit();
BackUpCompleted = "Backup Completed!";
BackUpCheckBox.Checked = true;
BackUpCheckBox.Visible = true;
}
catch (Exception ex)
{
BackUpCompleted = (ex.StackTrace.ToString());
}
return BackUpCompleted;
}
--------VBS script-----
Set oShell = CreateObject ("Wscript.Shell")
Dim strArgs
strArgs = "cmd /c LayoutsBackup.bat"
oShell.Run strArgs, 0, false
You are executing an other command inside that VBS script that it runs an other cmd. So the VBS script it just calls the cmd command and it exits without checking if the shell run has finished. Try to change your VBScript like this:
oShell.Run strArgs, 0, true
Run Documentation
.Run
Run an external Command.
Syntax
objShell.Run (strCommand, [intWindowStyle], [bWaitOnReturn])
Last parameter says the Run to wait until finish.
I have a batch file that copy file from one folder to another folder. So I would like to run this file from a C# windows services then I would like to read if the script generate an error or it works correctly.
This is my code for lunch it but I don't Know how to read the message of the script:
SCRIPT CODE:
REM
REM This script moves files with results from GOLD server and saves them on MES06 server on .
REM IMPORT folder.
REM
REM Robocopy Options:
REM /R:2 Two retries on failed copies (default is 1 million)
REM /W:5 Wait 5 seconds between retries (default is 30 sec).
REM
REM GOLD QAS Inbound Folder: \\goldqas01.app.pmi\limscihome$\RootDirectory
REM
for /f "delims=: tokens=2,3" %%j in (F:\MES2GOLD\copy_list_test.txt) do ROBOCOPY.EXE %%j %%j\..\BACKUP *.* /R:2 /W:5 /log+:%%j\..\LOGS\MES2GOLD.log & ROBOCOPY.EXE %%j %%k *.* /R:2 /W:5 /MOV /log+:%%j\..\LOGS\MES2GOLD.log
PAUSE
C# Code:
public void execute(string workingDirectory, string command)
{
// create the ProcessStartInfo using "cmd" as the program to be run, and "/c " as the parameters.
// Incidentally, /c tells cmd that we want it to execute the command that follows, and then exit.
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", #"/c C:\Users\mcastrio\Desktop\GOLD2MES.bat");
procStartInfo.WorkingDirectory = workingDirectory;
//This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
//This means that it will be redirected to the Process.StandardError StreamReader. (same as StdOutput)
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
//This is importend, else some Events will not fire!
proc.EnableRaisingEvents = true;
// passing the Startinfo to the process
proc.StartInfo = procStartInfo;
// The given Funktion will be raised if the Process wants to print an output to consol
proc.OutputDataReceived += DoSomething;
// Std Error
proc.ErrorDataReceived += DoSomethingHorrible;
// If Batch File is finished this Event will be raised
proc.Exited += Exited;
}
Can we help me?
You can use the code below inside your loop:
var startInfo = p.StartInfo;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = false;
startInfo.StandardOutputEncoding = Encoding.GetEncoding("ibm850");
startInfo.RedirectStandardOutput = true;
startInfo.FileName = filebatch;
startInfo.Arguments = arguments;
p.Start();
var output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Or just use ProcessHelper.Run from TestSharp library:
ProcessHelper.Run(string exePath, string arguments = "", bool waitForExit = true)
I am making a backup program in c# in which I use a .bat script to create a new Tasks that runs my program on an interval. I need to make sure the .bat is only run if the task does not exist. To do this I use the following piece of code, but it doesn't seem to detect whether or not it exists.
if (!File.Exists(#"C:\Windows\System32\Tasks\BackupUtil.*"))
{
Process proc = new Process();
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.FileName = #"C:\Users\Sebastian Esp\documents\visual studio 2012\Projects\FileBackUp_Sorter\FileBackUp_Sorter\Task_Schedule.bat";
proc.Start();
proc.WaitForExit();
}
Use Directory.GetFiles instead
if (Directory.GetFiles(#"C:\Windows\System32\Tasks", "BackupUtil.*").Length == 0)
//....Your code
}
http://msdn.microsoft.com/en-us/library/wz42302f(v=vs.110).aspx