I have a native EXE that converts a file based on command line arguments. Provided, I know how to give full path names of the input and output files, can I run such an EXE from my app service when some button is pressed and wait till the output file is created? Converting to DLL is not an option.
As far as I know, we could run a native exe in the azure app service.
But we couldn't directly pass the parameter to the native exe.
You need write a web application or something else for the user to type in the input parameter.
Then you could use Process.Start method to run the exe.
About how to do it , you could refer to this code sample.
I use ASP.NET MVC to get the input parameter then send the parameter to the exe and get the result.
public ActionResult Index()
{
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = Server.MapPath("/exe/Sum.exe"),
//Arguments could be replaced
Arguments = "1 2",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
// do something with line
Response.Write( " The result is : " + line);
}
//await getResultAsync();
return View();
}
Result:
Related
I doing my final year project by implementing learning web application using ASP.NET Core
however, in some page i need the user to interact with some command line application where these commands need to be sent based on the given output from the command line application. I have no issue with sending on command, but when it comes to the second command i got several issues. here is the code
public static Process process = new Process()
{
StartInfo = new ProcessStartInfo
FileName = "cmd",
RedirectStandardOutput = true,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
This is my definition for my process i have created outside the function because i do need to use the same process several time until the user leave the page.
For the process.Start(); I have putted with the function of viewing the page, so the process is started already and no issue with it.
public IActionResult acceptingInputFromUser(string input)
{
string result;
try
{
StreamWriter sw = process.StandardInput;
StreamReader rd = process.StandardOutput;
using (process.StandardInput)
{
sw.WriteLine(input);
sw.Flush();
sw.Close();
result = process.StandardOutput.ReadToEnd();
}
}catch (Exception ex)
{
result = ex.ToString();
}
return Json(result);
}
Here where is the issue, once the user submit any input the the first time will accept and give the result, however when he send another request it says
Cannot write to a closed TextWriter
I have tried several ways but so far i couldn't find solution. Can anyone help me with this error like how I can open the Textwriter again or if there is any other efficient way to where I can use CMD freely.
Mostly just as a curiosity, I wrote a little app to start up Terminator shell on Windows, using Ubuntu/WSL and Xming window server.
Doing things manually from the shell, I can run Firefox, gedit, Terminator, etc on Windows, it's pretty cool.
So I checked the location of bash.exe using where bash and it returned...
C:\Windows\System32\bash.exe
However when I tried to run this code...
using (var xminProc = new Process())
{
xminProc.StartInfo.FileName = #"C:\Program Files (x86)\Xming\Xming.exe";
xminProc.StartInfo.Arguments = ":0 -clipboard -multiwindow";
xminProc.StartInfo.CreateNoWindow = true;
xminProc.Start();
}
using (var bashProc = new Process())
{
bashProc.StartInfo.FileName = #"C:\Windows\System32\bash.exe";
bashProc.StartInfo.Arguments = "-c \"export DISPLAY=:0; terminator; \"";
bashProc.StartInfo.CreateNoWindow = true;
bashProc.Start();
}
I get the error...
System.ComponentModel.Win32Exception: 'The system cannot find the file specified'
And checking my entire system for bash.exe reveals it really be in another place altogether...
I'm not sure if this location is one that I can rely on, I'm worried it's ephemeral and can change during a Windows Store update, although I may be wrong about that.
Why does the command prompt show bash.exe to be in System32 but it's really in another location altogether?
Can I get C# to also use the System32 location?
As #Biswapriyo stated first set the platafrom to x64 on your solution:
Then you may run on your ubuntu machine from c# as:
Console.WriteLine("Enter command to execute on your Ubuntu GNU/Linux");
var commandToExecute = Console.ReadLine();
// if command is null use 'ifconfig' for demo purposes
if (string.IsNullOrWhiteSpace(commandToExecute))
{
commandToExecute = "ifconfig";
}
// Execute wsl command:
using (var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = #"cmd.exe",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
CreateNoWindow = true,
}
})
{
proc.Start();
proc.StandardInput.WriteLine("wsl " + commandToExecute);
System.Threading.Thread.Sleep(500); // give some time for command to execute
proc.StandardInput.Flush();
proc.StandardInput.Close();
proc.WaitForExit(5000); // wait up to 5 seconds for command to execute
Console.WriteLine(proc.StandardOutput.ReadToEnd());
Console.ReadLine();
}
How should I restart a dotnetcore C# console app?
I have tried suggestions found for C# console apps, but doesnt work for dotnetcore.
(This is not asp.net, which is where so many dotnetcore answers point)
OK, so im going to assume in this answer that it is ok with you if your program will start a new instance of your program and then close itself.
Here we go:
Since a dotnet console app can be started from the console, I think the best way to start a new instance of your console application would be thorugh using shell commands. To run shell commands from your program, add this helper class to your application: (If you are using windows instead of mac/linux, please see the end of this post)
using System;
using System.Diagnostics;
public static class ShellHelper
{
public static string Shell(this string cmd)
{
var escapedArgs = cmd.Replace("\"", "\\\"");
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = $"-c \"{escapedArgs}\"",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return result;
}
}
Then since this is a extension method, just import it and then create a string with the command to restart your app and then use the Shell() method.
So if you are in development and you normally start your app by running dotnet run then make sure you are in the proper directory and then just use this line of code "dotnet run".Shell();
If you want to get the feedback from running the command then just assign the return value like this string result = "dotnet run".Shell();
Then once you have started the new process you just exit your current program by either returning on your main method etc.
Please Note: The above code is for mac/linux, If you are on windows, then the following two lines of the above code:
FileName = "/bin/bash",
Arguments = $"-c \"{escapedArgs}\"",
Should be replaced with:
FileName = "cmd.exe",
Arguments = $"/c \"{escapedArgs}\"",
I have an exe file which I run through windows command prompt and give command line arguments. I went through this post and ran the following command:
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
But all it did, is to give me resource files located in WindowsFormsApplication1\obj\Debug folder
I went through this post but it tells on how to execute the exe directly without the running it from cmd.
I even tried the following command:
string path = Path.Combine(Path.GetTempPath(), "MyApplication.exe");
It worked but after clearing my C:\Users\UserName\AppData\Local\Temp folder the application started giving an error.
I even tried the following command:
global::ApplicationName.Properties.Resources.MyApplication
but it gives byte[] and not the path to the application.
All I want to know is how to run the application which is embedded in my resources so that I can successfully execute the following command:
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/K " + MyApplication+" Argument "+Path1+" "+Path2 ,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadToEnd();
using (System.IO.StreamWriter file = new System.IO.StreamWriter(resultFile))
{
file.WriteLine(line);
}
}
Extract the resource into a file in the filesystem and then run it.
byte[] fileContents = ApplicationName.Properties.Resources.MyApplication;
File.WriteAllBytes("MyApplication.exe", fileContents);
Now you can run the file using MyApplicaton.exe as path.
I want my c# application (which I execute on a raspberry pi) to run a bash script whenever it starts..
basically : the script is located in /etc/init.d and is named mnw. I want whenever my c# application starts, it should execute a part of the mnw script.
If it was written it in the terminal would look like :
cd /etc/init.d
./mnw stop
I want this to happen right at the start of public static void Main(), I've been trying
ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "/dev/init.d/./mnw", Arguments = "stop", };
Process proc = new Process() { StartInfo = startInfo, };
proc.Start();
but it says that stop is a unexpected argument, any ideas?
I have never used ProcessStartInfo on Mono / Linux, but have you tried calling via bash?
ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "/bin/bash", Arguments = "/dev/init.d/mnw stop", };
Process proc = new Process() { StartInfo = startInfo, };
proc.Start();
Also, there is no issues with the executable bit on mnw?
While using the Process class like in the accepted answer works, I'
d like to add that there is a library called CliWrap that makes CLI calls like this much easier:
fluent API to build the calls
async support
call with custom environment variables
set working directory
ability to pipe stdout/stderr into a string
retrieve exit code
etc.
using OPs question as example:
var result = await Cli
.Wrap("/dev/init.d/mnw")
.WithArguments("stop")
.ExecuteBufferedAsync();
// result contains:
// -- result.StandardOutput (string)
// -- result.StandardError (string)
// -- result.ExitCode (int)
// -- result.StartTime (DateTimeOffset)
// -- result.ExitTime (DateTimeOffset)
// -- result.RunTime (TimeSpan)
if (result.ExitCode != 0)
Console.WriteLine("Command failed")
Thank you #Tyrrrz for this library!