How to start linux systemd service in C# programmatically on Ubuntu Server? - c#

I have a very simple question:
How to start / stop a systemd service from a .NET 6.0 Console App?
Just to clarify: I do not want the service to stop itself. I want a console app to stop another service already installed on a Ubuntu Server 20.04.
More concrete: How would I call this line in C# properly?
sudo systemctl start SERVICE_NAME
Do I have to start a Process like this?
var process = new Process();
process.StartInfo.FileName = " /usr/lib/systemd"
process.StartInfo.Arguments = "start SERVICENAME";
process.Start();
What have I tried so far?
I googled but could not find any viable solution, and since I am no expert on Linux I might have fallen into the XY trap

I've never done this before. I like .NET and I use netcore every day but, if you want to create a script to be run only on linux. Maybe a bash script would do.
Since you want to use .NET, I think you'll need to do something like:
ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "/bin/bash", Arguments = "systemctl stop SERVICE", };
Process proc = new Process() { StartInfo = startInfo, };
proc.Start();
You're creating a bash instance from where you call systemctl.
You also might want to wait until the process has finished. You can do that with
proc.WaitForExit();
Be aware this is a synchronous waiting.

Related

Is there anyway to access and edit Cron Jobs from a C# application?

I've got a C# asp.net core app running on an Ubuntu box. I need to run some scheduled tasks and wanted some way to manage that from the app, rather than logging into a terminal.
Is there anyway the C# app can connect to cron and return current jobs, add / edit existing ones?
Best bet is to expand on the following code:
Process process = new System.Diagnostics.Process ();
Process proc = new System.Diagnostics.Process ();
proc.StartInfo.FileName = "/bin/bash";
proc.StartInfo.Arguments = "-c \" " + command + " \"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
This will get you started with executing bash commands and reading the output in your code.
Alternatively, as Tristan mentioned in the comments, you can certainly read/write the cron files from your code as well.
Not a direct answer but if you want a controllable scheduled tasks you can consider using hosted services to perform background tasks or libraries/frameworks like Hangfire or Quartz.NET.

Launch a command shell from a console application run via Windows Task Scheduler

I have a Windows console application that is launched via a schedule setup in Task Scheduler. This console application, as part of its normal runtime, will launch a command prompt in order to run a java program. No, I have no control over the design of the Java program. It was supplied to me as is and I have no rights or access to make changes to it. I also cannot implement it in another language. I must use what was given to me.
At any rate, when my console application tries to run the command prompt it will work just fine if I'm launching the application manually. However, when I try it as an action within Task Scheduler, my console application will start and run as expected until it needs to launch the command prompt. At this point, the console application exits. No error message or code is provided.
How do I get the command prompt window to start as a new window from within my console application when no one is logged into the server?
Thanks for any hints or suggestions you can provide.
* UPDATE *
Here is the code snippet that launches the program from within my console application:
string parameter_save_path = #"C:\output\folder"
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo start_info = new System.Diagnostics.ProcessStartInfo();
start_info.WorkingDirectory = #"C:\mtselect-client";
start_info.FileName = "cmd.exe";
start_info.Arguments = "/C run.bat \"" + parameter_save_path + "\"";
process.StartInfo = start_info;
process.Start();
process.WaitForExit();
The run.bat is what launches the java program.
I think it's too late for this message, but...
Maybe in your batch file you are running your java application with something like: java -jar ApplicationName
First I would do should be comment out the "#echo off" from the batch file, next trace out the batch lines with one echo "x" (being x a natural number starting from 1 and increasing by 1 in each ocurrence). Next I will add a line with java -version, and so I will be sure java app is installed and accesible.
Maybe java needs be ran by an authenticated user and so have java_home defined. Maybe the application needs some JVM parameters like memory size, etc.
Have good luck, tell me and I will try to help

Start cmd process call in a .NET MVC web project on IIS web server (not working!)

Hi fellow software developers
So I need to start a CMD process in my .NET MVC web project. This is my function that I pass the command I need to call:
private void ExecuteCommandSync(string command)
{
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
// Hide the CMD window:
procStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
// The following commands are needed to redirect the standard output.
procStartInfo.UseShellExecute = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
}
The command calls a program that starts a linear programming framework that solves a problem which takes 20 seconds to finish.
The problem is that nothing happens when this function is called! It works fine outside the IIS, but not in IIS. The IIS web server runs on a Windows Server 2012. My web project is called from outside of our local network, where the web server is running, does some work, calls my synchronous method and waits for it to finish and ends by returning the result of the call as a JSON object.
This question suggests that it might have something with user privileges. In the Application Pools for the web project in Advanced Settings -> Identity I have tried to change from ApplicaitonPoolIdentity to Local System (which has high privileges) but no luck (as explained here).
Does anyone have any suggestions to how I can solve this problem? Any advice would be greatly appreciated.
you must run project pool under user have privilege's to execute exec.

Communication via stdout/stdin between py2exe executable and C# program

So here's my problem:
Python scripts launched from C# via the Process class require the -i switch to be passed to python.exe or else they don't send any output when I redirect the StandardXxx streams
I want to bundle my Python program with py2exe (or another similar setup, if one meets my needs)
py2exe does not seem to let me pass the -i switch in any obvious way, but it's giving my the same issue as running python.exe - it doesn't output anything when launched by my C# program. So I need a way to force it into a similar mode so I can actually receive and send messages over stdin/stdout. I found some similar problems when it's built with "windows=['my_script']" but I built it with "console=['my_script']", so those fixes didn't help, and I don't need an actual interactive mode (i.e. the REPL), but for some reason the -i switch fixes the console IO issues.
This is the code I'm using to launch it:
ProcessStartInfo psi = new ProcessStartInfo();
psi.UseShellExecute = false;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.FileName = "py2exe_program.exe";
Process p = Process.Start(psi);
// program hangs here because ready message is never printed
p.StandardOutput.ReadLine(); // Consume ready message
The executable works as expected when launched externally, and the above code works when I launch the Python script via "python.exe -i my_script.py" but it runs into the same problem without the -i switch.
How do I get it to behave as expected?

Windows SDK - C# - Debugging process exiting with error code -1073741502

SHORT VERSION
How do you figure out which DLL is failing to load (and potentially why) when a process exits with error code -1073741502?
LONG VERSION
I'm trying to write a pretxnchangegroup hook for Mercurial, and as a part of that hook I need to get the output of running the command:
hg log
The code that I'm using to start and run the hg.exe process is as follows:
string Command = "log";
Process p = new Process();
ProcessStartInfo psi = p.StartInfo;
p.StartInfo.FileName = #"C:\Program Files (x86)\Mercurial\hg.exe";
psi.CreateNoWindow = true;
psi.LoadUserProfile = true;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.WorkingDirectory = Environment.CurrentDirectory;
p.StartInfo.Arguments = Command;
// Pass-through environment variables
psi.UserName = Properties.Settings.Default.HG_User;
psi.Domain = Properties.Settings.Default.HG_Domain;
psi.Password = new System.Security.SecureString();
foreach (char c in Properties.Settings.Default.HG_Pass)
{
psi.Password.AppendChar(c);
}
p.Start();
p.WaitForExit();
The problem is that the process keeps exiting with error code -1073741502, without outputting anything on Standard Output or Standard Error. After some research online, I discovered that this error code has something to do with the application failing to initialize properly (couldn't find DLL's, maybe?), but I have no idea how to go about figuring out how to fix it.
Keep in mind that this hook is being called for when I'm pushing to the repository over the web (so, IIS is calling the Mercurial CGI via Python, which has this program configured as a hook).
In a totally different web application, I'm able to run HG commands just fine, and I'm also able to run this by doing
runas /user:<same account as in the code> /noprofile cmd.exe and then manually typing in the hg command line.
Also, if I set UseShellExecute = true, then it executes just fine, but then I can't get the Standard Output. I'm really tempted to just make a web service call to the web app which is able to execute this command successfully, but that'd be a really ugly solution.
Any ideas why this thing isn't executing?
I was able to resolve this by disabling UAC so it sounds like a permissions problem even though I do not know the exact details.

Categories