public void BuildMod()
{
var startIngo = new ProcessStartInfo();
startIngo.WorkingDirectory = ModBuilderLoc;
startIngo.FileName = "ModPack Builder.exe";
startIngo.Arguments = "\"" +
LoadedMod.Directory.Substring(Folders.MyDocuments.Length + 28)
+ "\"" + " " + "true";
startIngo.WindowStyle = ProcessWindowStyle.Normal; //TODO: Set to hidden
//startIngo.UseShellExecute = false;
//startIngo.RedirectStandardOutput = true;
try
{
Process proc = new Process();
proc.StartInfo = startIngo;
proc.Start();
//proc.StandardOutput.ReadLine();
proc.WaitForExit();
MessageBox.Show("Build successful", "Build Info");
}
catch (Win32Exception)
{
MessageBox.Show("Could not find \"ModPack Builder.exe\" in \""
+ ModBuilderLoc +"\", change from menu bar");
}
}
This works perfectly fine, unless I uncomment the comments, which makes the program read the first line to my program's console.
When the comments are uncommented, a Win32 exception is caught, which I do not want happening.
Related
I have checked and there are many posts similar but I cannot solve this. This is a SQL CLR proc to run an exe that parses PDF files. I can run same code as myself in console app. Permissions are not an issue. I am dumping to event log and the ProcessStartInfo is full formed. UseShellExecute - I am not certain. I have also created a .bat file to execute the code - run it manually - it runs fine. Via this CLR program ? Hangs or runs right away but does nothing. At wits end. My goal was to create the CLR using the Nuget from itext but I had a real hard time installing. SQL CLR doesnt support it but I tried anyway.
Thanks in advance.
[Microsoft.SqlServer.Server.SqlProcedure]
public static void PDFToCSVViaExe_CLR()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
string args = #"\\app\Systems\Universal";
args = " \"" + args + "\"" + " \"" + "*" + "\"" + " \"" + "LVM" + "\"";
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = true;
startInfo.FileName = "c:\\SqlCLR\\PDFRipper\\PDFToCSV.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = args;
EventLog.WriteEntry(".NET Runtime", startInfo.FileName.ToString()+" " + args, EventLogEntryType.Warning, 1000);
string folder = "C:\\SqlCLR\\PDFRipper\\LVM.bat";
try
{
//using (new ImpersonationNamespace.Impersonation("domain", "user", "password"))
{
EventLog.WriteEntry(".NET Runtime", System.Security.Principal.WindowsIdentity.GetCurrent().Name + " OR " + Environment.UserName, EventLogEntryType.Warning, 1000);
folder = System.IO.Path.GetDirectoryName(folder);
if (!Directory.Exists(folder))
{
throw (new Exception("Directory does not exist for " + folder));
}
else
{ EventLog.WriteEntry(".NET Runtime", folder + " exists.", EventLogEntryType.Warning, 1000); }
// 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 ex)
{
using (EventLog EventLog = new EventLog("Application"))
{
EventLog.Source = "Application";
//eventLog.WriteEntry(ex.Message);
EventLog.WriteEntry(".NET Runtime", ex.Message + "Trace" + ex.StackTrace, EventLogEntryType.Warning, 1000);
//eventLog.WriteEntry(".NET Runtime", ex.Message, EventLogEntryType.Warning, 1000);
}
}
When I am trying to start a process from web API locally its started successfully but when I am hosting it to IIS 7.5 and try to start that process there is no response I am getting. when I tried to debug attaching the process to visual studio and start a debug I seen this error Process's BaseProperty
process.BasePriority threw an Exception of Type 'System.InvalidOperationException'
I am starting a process to start a cmd.exe and here is the code:
public static void Start(long campaign_id, long contact_id, string startDate, string endDate, string user)
{
try
{
//WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.WorkingDirectory = #"C:\";
startInfo.Arguments = "/c sparkclr-submit --master " + ConfigurationManager.AppSettings["SparkMaster"] + " --driver-class-path " + AppDomain.CurrentDomain.BaseDirectory + "Engine\\mysql.jar " + "--exe CmAnalyticsEngine.exe " + AppDomain.CurrentDomain.BaseDirectory + "Engine " + campaign_id + " " + contact_id + " " + startDate + " " + endDate + " " + user;
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.LoadUserProfile = true;
//startInfo.Verb = "runas";
process.StartInfo = startInfo;
process.Start();
if (!process.HasExited)
{
Console.WriteLine("process is running");
}
else
{
Console.WriteLine("process is stopped");
}
}
catch (Exception e)
{
LogWritter.WriteErrorLog(e);
}
}
when I am running this locally it works properly but on IIS its printing msg Process is stopped.
do I need to give permission to cmd.exe to start from IIS? if yes then how to do it?
Any help will be most appreciated.
Thanks
This error means the process has exited.-or- The process has not started, so there is no process ID.
public static void Start(long campaign_id, long contact_id, string startDate, string endDate, string user)
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.WorkingDirectory = #"C:\";
startInfo.Arguments = "/c sparkclr-submit --master " + ConfigurationManager.AppSettings["SparkMaster"] + " --driver-class-path " + AppDomain.CurrentDomain.BaseDirectory + "Engine\\mysql.jar " + "--exe CmAnalyticsEngine.exe " + AppDomain.CurrentDomain.BaseDirectory + "Engine " + campaign_id + " " + contact_id + " " + startDate + " " + endDate + " " + user;
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.LoadUserProfile = true;
//startInfo.Verb = "runas";
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
if (!process.HasExited)
{
Console.WriteLine("process is running");
}
else
{
Console.WriteLine("process is stopped");
}
}
catch (Exception e)
{
LogWritter.WriteErrorLog(e);
}
}
Hope it helps.
The job of the method ExecuteCommandSync is to detect the silences from a video and return the output as string but when I run this code it never bring the value of proc.HasExited as true. If I forcefully drag the debugger to the line
result =proc.StandardOutput.ReadToEnd()
then it never exit the ffmpeg.exe so as a result control never returns back.
Although the same method is working fine for a different command like creating an audio file from a video. In this case proc.HasExited also returns false but it also generates the audio file successfully.
public static string ExecuteCommandSync(string fileName, int timeoutMilliseconds)
{
string result = String.Empty;
string workingDirectory = Directory.GetCurrentDirectory();
try
{
string command = string.Format("ffmpeg -i {0} -af silencedetect=noise=-20dB:d=0.2 -f null -", "\"" + fileName + "\"");
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
procStartInfo.WorkingDirectory = workingDirectory;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = false;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit(timeoutMilliseconds);
// Get the output into a string
if (proc.HasExited)
{
if (!proc.StandardOutput.EndOfStream)
{
result = proc.StandardOutput.ReadToEnd();
}
else if (!proc.StandardError.EndOfStream)
{
result = "Error:: " + proc.StandardError.ReadToEnd();
}
}
}
catch (Exception)
{
throw;
}
return result;
}
So please advice.
I've been messing around with C# and in one moment of the code, I need to dump the output of an external .exe into a .txt. I do it by starting cmd.exe and then loading the program, with its attributes plus the > opperator. But now, when I execute the program, the file isn't even created. Meanwhile, if I input the EXACT same code that is passed to cmd in the program:
"o:\steam\steamapps\common\counter-strike global offensive\bin\demoinfogo.exe" "O:\Steam\SteamApps\common\Counter-Strike Global Offensive\csgo\testfile.dem" -gameevents -nofootsteps -deathscsv -nowarmup > "o:\steam\steamapps\common\counter-strike global offensive\demodump.txt"
directly into the Command Prompt, it does get dumped. I've been looking around, and I found A LOT of info, but sadlly nothing has helped me enough so far, so I decided to ask myself.
I attach the chunks of code that I think are relevant to this.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = true;
startInfo.FileName = "CMD.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (checkBox1.Checked)
{
arguments += " -gameevents";
if (checkBox2.Checked)
{
arguments += " -nofootsteps";
}
if (checkBox3.Checked)
{
arguments += " -extrainfo";
}
}
if (checkBox4.Checked)
{
arguments += " -deathscsv";
if (checkBox5.Checked)
{
arguments += " -nowarmup";
}
}
if (checkBox6.Checked)
{
arguments += " -stringtables";
}
if (checkBox7.Checked)
{
arguments += " -datatables";
}
if (checkBox8.Checked)
{
arguments += " -packetentites";
}
if (checkBox9.Checked)
{
arguments += " -netmessages";
}
if (dumpfilepath == string.Empty)
{
dumpfilepath = getCSGOInstallationPath() + #"\demodump.txt";
}
baseOptions = #"""" + demoinfogopath + #"""" + " " + #"""" + demofilepath + #"""" + arguments;
startInfo.Arguments = baseOptions + " > " + #"""" + dumpfilepath + #"""";
try
{
using (exeProcess = Process.Start(startInfo))
....a bunch of code...
The Process class that you're creating has this useful little property:
Process.StandardOutput
When a Process writes text to its standard stream, that text is normally displayed on the console. By redirecting the StandardOutput stream, you can manipulate or suppress the output of a process. For example, you can filter the text, format it differently, or write the output to both the console and a designated log file.
All you need to do is ensure you're redirecting the StandardOutput to this stream (using the RedirectStandardOutput property in the ProcessStartInfo) and then you can read the output from that stream. Here's the MSDN sample code, slightly abridged:
Process myProcess = new Process();
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(args[0], "spawn");
myProcessStartInfo.UseShellExecute = false; // important!
myProcessStartInfo.RedirectStandardOutput = true; // also important!
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();
// Here we're reading the process output's first line:
StreamReader myStreamReader = myProcess.StandardOutput;
string myString = myStreamReader.ReadLine();
Console.WriteLine(myString);
If you look at the help for CMD (access by typing CMD /?) you'll see the following options:
/C Carries out the command specified by string and then terminates
/K Carries out the command specified by string but remains
Without one of those switches, CMD won't interpret the string you provide it as a command to execute.
When I write a short program like the following, it successfully generates a file... but only if I use either the /C or /K options:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = true;
startInfo.FileName = "CMD.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
var command = #"echo test > c:\users\myusername\Desktop\test.txt";
var args = "/C " + command;
startInfo.Arguments = args;
using (var process = Process.Start(startInfo)) { }
//Hi you could try this to build your process like this.
public class Launcher
{
public Process CurrentProcess;
public string result = null;
public Process Start()
{
CurrentProcess = new Process
{
StartInfo =
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
WorkingDirectory = #"C:\",
FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe")
}
};
CurrentProcess.Start();
return CurrentProcess;
}
//Start the process to get the output you want to add to your .txt file:
private void writeOuput()
{
Currentprocess = new process();
Start()
CurrentProcess.StandardInput.WriteLine("Your CMD");
CurrentProcess.StandardInput.Close();
result = CurrentProcess.StandardOutput.ReadLine();
CurrentProcess.StandardOutput.Close()
//Then to put the result in a .txt file:
System.IO.File.WriteAllText (#"C:\path.txt", result);
}
}
}
I have been trying to export and save registry files to an arbitrary location, the code is running. However, on specifying the path and saving, the function does not work and no registry is exported. There is no error shown either.
private static void Export(string exportPath, string registryPath)
{
string path = "\""+ exportPath + "\"";
string key = "\""+ registryPath + "\"";
// string arguments = "/e" + path + " " + key + "";
Process proc = new Process();
try
{
proc.StartInfo.FileName = "regedit.exe";
proc.StartInfo.UseShellExecute = false;
//proc.StartInfo.Arguments = string.Format("/e", path, key);
proc = Process.Start("regedit.exe", "/e" + path + " "+ key + "");
proc.WaitForExit();
}
catch (Exception)
{
proc.Dispose();
}
}
You need to add a space after the /e parameters so your code will be :
private static void Export(string exportPath, string registryPath)
{
string path = "\""+ exportPath + "\"";
string key = "\""+ registryPath + "\"";
using (Process proc = new Process())
{
try
{
proc.StartInfo.FileName = "regedit.exe";
proc.StartInfo.UseShellExecute = false;
proc = Process.Start("regedit.exe", "/e " + path + " "+ key);
proc.WaitForExit();
}
catch (Exception)
{
// handle exceptions
}
}
}
regedit.exe requires elevated privileges. reg.exe is better choice. It does not require any elevation.
Here's what we do.
void exportRegistry(string strKey, string filepath)
{
try
{
using (Process proc = new Process())
{
proc.StartInfo.FileName = "reg.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.Arguments = "export \"" + strKey + "\" \"" + filepath + "\" /y";
proc.Start();
string stdout = proc.StandardOutput.ReadToEnd();
string stderr = proc.StandardError.ReadToEnd();
proc.WaitForExit();
}
}
catch (Exception ex)
{
// handle exception
}
}