Unable to run cmd.exe by using ProcessStartInfo - c#

Web.config:
<appSettings>
<add key="MystemDirectory" value="D:\mystem\"/>
</appSettings>
Controller:
if (flag)
{
db.FbDocuments.Add(fbDocument);
db.SaveChanges();
var workingDirectory = WebConfigurationManager.AppSettings["MystemDirectory"];
System.IO.File.WriteAllText(workingDirectory + #"\input.txt", fbDocument.Title);
Process process = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processStartInfo.FileName = "cmd.exe";
processStartInfo.WorkingDirectory = workingDirectory;
processStartInfo.Arguments = "mystem.exe --format json input.txt output.txt";
process.StartInfo = processStartInfo;
process.Start();
string text = System.IO.File.ReadAllText(workingDirectory + #"\output.txt");
var jsSerializer = new JavaScriptSerializer();
var jsonCleanText = jsSerializer.Deserialize<CleanText>(text);
var fbToUpdate = db.FbDocuments.FirstOrDefault(x => x.Id == fbDocument.Id);
fbToUpdate.CleanText = jsonCleanText.ToString();
db.SaveChanges();
}
When the code in the controller writes the text in input.txt, but output.txt remains empty. If run cmd.exe manually, everything works... After the files input.txt output.txt and remain filled, and if you run the code in the controller again, an error in the variable jsonCleanText invalid format JSON and output.txt value does not change.

Try this
if (flag)
{
db.FbDocuments.Add(fbDocument);
db.SaveChanges();
var workingDirectory = WebConfigurationManager.AppSettings["MystemDirectory"];
System.IO.File.WriteAllText(workingDirectory + #"\input.txt", fbDocument.Title);
Process process = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processStartInfo.FileName = "mystem.exe";
processStartInfo.WorkingDirectory = workingDirectory;
processStartInfo.Arguments = "--format json input.txt output.txt";
process.StartInfo = processStartInfo;
process.Start();
string text = System.IO.File.ReadAllText(workingDirectory + #"\output.txt");
var jsSerializer = new JavaScriptSerializer();
var jsonCleanText = jsSerializer.Deserialize<CleanText>(text);
var fbToUpdate = db.FbDocuments.FirstOrDefault(x => x.Id == fbDocument.Id);
fbToUpdate.CleanText = jsonCleanText.ToString();
db.SaveChanges();
}

Related

How to Execute multiple commands in Process

I have a list of a thousand items, Each of these items must be checked by the CMD.exe, With the help of the following code, I can check an item by CMD
var p = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
FileName = "cmd",
Arguments = $"list {Id}"
}};
p.Start();
var _Data = await p.StandardOutput.ReadToEndAsync();
But the question is, I want all of these items to be checked quickly by CMD, I'm currently doing this as follows
foreeach(var item in list)
{
var p = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
FileName = "cmd",
Arguments = $"list {item}"
}};
p.Start();
var _Data = await p.StandardOutput.ReadToEndAsync();
}
But it takes a long time to do this
You can redirect standard input and use a StreamWriter to write to it:
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
using (StreamWriter sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("mysql -u root -p");
sw.WriteLine("mypassword");
sw.WriteLine("use mydb;");
}
}

How to take window ID of a created process in c#?

I am working on a C# .net core project.I created a process to run "xdotool windowactivate $windowpid".I should store the windowID which process run on it.The solution could be any property of xdotool which i couldn't find,or Is there any way to take windowId of a process when it is created?
Another Try is that:
I created my pages with this method. I tried to take mainwindowtitle of process;because of single process,i couldn't take the titles.
static List<string> chromeTitles = new List<string>();
public static Process StartChrome(string filePath)
{
string dataDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Chrome-UserData");
filePath += " --user-data-dir=" + dataDirectory;
var Chrome = new Process
{
StartInfo =
{
FileName = "C:/Program/chrome.exe",
Arguments = filePath,
UseShellExecute = false,
CreateNoWindow=true,
WindowStyle = ProcessWindowStyle.Maximized,
}
};
Chrome.Start();
string title = Chrome.MainWindowTitle;
chromeTitles.Add(title);
}
Then I call it :
StartChrome("https://tr.wikipedia.org/wiki/Anasayfa");
Thread.Sleep(2000);
StartChrome("https://tureng.com/");
You can use the Process class for accessing more capabilities.
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = "xdotool.exe";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.Arguments = $"windowactivate $windowpid";
process.StartInfo = startInfo;
process.Start();
To get the PID of the process that got run by the code, you can use Process.ID property:
process.Id;
if you want to read the output, you can add this code:
string output = process.StandardOutput.ReadToEnd();
To get Output, startInfo.RedirectStandardOutput should be True.

Cannot access the file because it is being used by another process using ffmpeg

I am getting the error:
Cannot access the file because it is being used by another process
I have a C# desktop app.
I am using the Process class to convert images to a video file by using FFMPEG.
This is my code:
using (Process serverBuild = new Process())
{
serverBuild.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
string args = " -f image2 -i " + {path} + "\\img%05d.jpg -s 352x288 -filter:v \"setpts=5.0*PTS\" -y " + {path}\\File.mp4;
serverBuild.StartInfo.Arguments = args;
serverBuild.StartInfo.FileName = "ffmpeg.exe";
serverBuild.StartInfo.UseShellExecute = false;
serverBuild.StartInfo.RedirectStandardOutput = true;
serverBuild.StartInfo.RedirectStandardError = true;
serverBuild.StartInfo.CreateNoWindow = true;
serverBuild.Start();
// string output = serverBuild.StandardOutput.ReadToEnd();
//Log.Instance.Debug(serverBuild.StandardError.ReadToEnd());
serverBuild.WaitForExit();
serverBuild.Close();
}
Directory.Delete(ExportRoute + FFMPEGPacket.LicenseKey + "\\" + FFMPEGPacket.Guid, true);
//which raise the error..
The images are all deleted but the File.Mp4 is not and that is the error. The error says that the newly created MP4 file cannot be deleted.
NB
This is partial code to illustrate the error
You may try the following code to create the file (it worked for me):
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = exe_path;
// replace your arguments here
psi.Arguments = string.Format(#" arguments ")
psi.CreateNoWindow = true;
psi.ErrorDialog = true;
psi.UseShellExecute = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = false;
psi.RedirectStandardError = true;
Process exeProcess = Process.Start(psi);
exeProcess.PriorityClass = ProcessPriorityClass.High;
string outString = string.Empty;
exeProcess.OutputDataReceived += (s, e) =>
{
outString += e.Data;
};
exeProcess.BeginOutputReadLine();
string errString = exeProcess.StandardError.ReadToEnd();
Trace.WriteLine(outString);
Trace.TraceError(errString);
exeProcess.WaitForExit();
exeProcess.Close();
exeProcess.Dispose();
FFMPEG might still be rendering the creation of video from images after it closes, so it might be worth if you place a Threading.Thead.Sleep(5000) 5 secs; before delete.
Try that:
File.WriteAllBytes(path, new byte[0]);
File.Delete(path);

How to run CL.exe using Process.Start()?

I have following code
using (StreamWriter outfile = new StreamWriter(#"f:\trial.cpp"))
{
outfile.Write(txtCode.InnerText);
}
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo(#"cl.exe", #" 'trial.cpp'");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.UserName = "asdasd";
SecureString secureString = new SecureString();
foreach (char c in "abcded")
{
secureString.AppendChar(c);
}
procStartInfo.Password = secureString;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
procStartInfo.WorkingDirectory = #"f:\";
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
// Get the output into a string
string result = proc.StandardOutput.ReadToEnd();
How to pass file name as parameter? Above code doesn't run and I have tried all full path, different path options.
can anyone help?
The argument is set incorrectly. You have:
var procStartInfo = new ProcessStartInfo(#"cl.exe", #" 'trial.cpp'");
Where there are spaces and single quotes in the name. Try:
var procStartInfo = new ProcessStartInfo(#"cl.exe", #"trial.cpp");
EDIT:
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "CL.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "trial.cpp";
try
{
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch
{
// error handling
}
The point here is that CL is a command line executable, not a windows GUI application.
http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx
http://msdn.microsoft.com/en-us/library/kezkeayy.aspx
http://msdn.microsoft.com/en-us/library/9s7c9wdw.aspx
If the cl.exe is not in the system PATH (which by default it is not) then the start process will not find the executable and it will fail to run.
So I suspect you are seeing the fact that the cl.exe is not in the system PATH.

How do I run Command line commands from code

I need to do 2 things: run a batch file (works fine), and run a command (does not work).
The method for the command throws the exception 'file not found'. If I open a cmd window, and type the command, it works perfectly.
private static void Rescan()
{
//System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("DEVCON ReScan");
//psi.RedirectStandardOutput = true;
//psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
//psi.UseShellExecute = false;
//System.Diagnostics.Process proc = System.Diagnostics.Process.Start(psi);
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "DEVCON ReScan";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
System.IO.StreamReader myOutput = proc.StandardOutput;
proc.WaitForExit(4000);
if (proc.HasExited)
{
string output = myOutput.ReadToEnd();
FileIO.WriteLog(_writePath, output);
}
}
The commented code also throws the same exception.
DEVCON ReScan is really the name of the executable? I guess the executable is DEVCON, while ReScan is a parameter. This means you have to set StartInfo.FileName to "DEVCON" and StartInfo.Arguments to "ReScan".
Is the DEVCON application actually in the working directory ?
Otherwise it won't work unless you specify the full path to it.
Furthermore you have to specify the extension, so I suppose you'd go for "Devcon.exe",
and specify the parameters not in the filename but in the parameters :)
Try this:
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Environment.GetEnvironmentVariable("comspec");
psi.CreateNoWindow = true;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
ConsoleColor fc = Console.ForegroundColor;
StreamWriter sw = p.StandardInput;
StreamReader sr = p.StandardOutput;
char[] buffer = new char[1024];
int l = 0;
sw.Write("DEVCON ReScan");
sw.Write(sw.NewLine);
Console.Write(">> ");
l = sr.Read(buffer, 0, buffer.Length);
for (int n = 0; n < l; n++)
Console.Write(buffer[n] + " ");
p.Close();

Categories

Resources