Executing Batch File on Remote Server Itself using C# - c#

I need to execute a batch file on remote server itself . I was using the below code as i found as an example but the batch file is getting executing on the application server itself and not on the remote server. If i need to create a log file using the batch file on remote server , it was throwing error stating file path cannot be found .Thanks for the help in advance
if (File.Exists(filePath))
{
var process = new Process();
var startInfo = new ProcessStartInfo
{
CreateNoWindow = true,
FileName = "cmd.exe",
Arguments = "/c \"\"" + filePath + "\"\"",
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
//WorkingDirectory = workingdirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true
};
process.StartInfo = startInfo;
process.Start();
//process.WaitForExit(30000);
string output = process.StandardOutput.ReadLine();
string errors = process.StandardError.ReadLine();

The work around for executing the batch file on remote server itself is to do a windows scheduler job and trigger the job by some c# code .Please find the below code to do that
string job = #"""\JobLocation\JobName""";
string server = #"XXXXXXXXXXX";
string user = #"Domian\XXXXXX";
string pwd = #"XXXXXXXXXXXXXXX";
string line = #" /run /tn " + job + " /s " + server + " /u " + user + " /p " + pwd;
var process = new Process();
var startInfo = new ProcessStartInfo
{
CreateNoWindow = true,
FileName = #"C:\WINDOWS\SYSTEM32\schtasks.exe",
WindowStyle = ProcessWindowStyle.Hidden,
Arguments = line,
//WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true
};
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
string output = process.StandardOutput.ReadLine();
string errors = process.StandardError.ReadLine();code here

Related

I get a can't execute binary file error when running a bash command from C#

I've created a Discord Bot with which you can interact (running on a Raspberry Pi with a default Raspberry Pi OS). I also added a command to execute a shell command. My code:
ProcessStartInfo inf = new()
{
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
FileName = "/bin/bash",
Arguments = command,
};
if (Process.Start(inf) is Process cmd)
{
string ret = "Output: " + await cmd.StandardOutput.ReadToEndAsync();
ret += "\nError Output: " + await cmd.StandardError.ReadToEndAsync();
await Program.Log(ret);
return ret;
}
When I set command to "echo Hello, World!" I just get the error
/usr/bin/echo: /usr/bin/echo: cannot execute binary file
from the StandardOutput.
What am I doing wrong?
You have to pass -c parameter to bash if you want execute something through it
ProcessStartInfo inf = new()
{
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
FileName = "/bin/bash",
Arguments = $"-c \"{command}\""
};
if (Process.Start(inf) is Process cmd)
{
string ret = "Output: " + await cmd.StandardOutput.ReadToEndAsync();
ret += "\nError Output: " + await cmd.StandardError.ReadToEndAsync();
await Program.Log(ret);
return ret;
}

How to make a progress bar for PostgreSQL DB backup through c#?

I am working on a c# winforms program, where the data is saved to a database.
Now transferring the DB from MSSQL to PostgreSQL.
I am looking for a way to backup (and restore) through the program, with a progress bar showing the backup status.
The only backup option I found is using pg_dump through a cmd.exe method (see below code), but this does not provide the feedback of success/failure, progress percentage, etc.
Is there a way to backup and provide progress reports?
Thank you
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
Process backupProcess = new Process();
backupProcess.StartInfo = startInfo;
backupProcess.StartInfo.EnvironmentVariables["PGPASSWORD"] = "xxxxxxx";
backupProcess.Start();
using (StreamWriter sw = backupProcess.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
command = #"cd C:\Program Files\PostgreSQL\12\bin";
sw.WriteLine(command);
command = #"pg_dump -U postgres -d " + databaseName.ToLower() + " -f " + fileName;
sw.WriteLine(command);
}
}

Send Python Output to File from C#

I want to get the output and error messages after running a python script from C#. The output works, however if there's an error in the python script the output returns as "" and I can't get the error. The error displays correctly if the python script is run from Windows shell.
As a workaround I'd like to output from the python script to a txt file and then read the text file in C#. The below works in shell to write for the file mylog.log.
python c:\temp\text.py 2>&1 | tee -filePath mylog.log
If I run the code below in C# no mylog.log file is created.
public string RunFile(string fileName)
{
fileName = #"c:\temp\text.py 2>&1 | tee -filePath c:\temp\myLog.log";
Process p = new Process();
p.StartInfo = new ProcessStartInfo(#"python", fileName)
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = #"c:\temp"
};
p.Start();
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();
return output;
}
Thanks for the comments. I've just enabled redirect of the error and am reading the error in C#.
Process p = new Process();
p.StartInfo = new ProcessStartInfo(#"python", fileName)
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = #"c:\temp"
};
p.Start();
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();

can not get out put from pg_dump.exe command line

i'm developing an application to get backup from my postgreSQL database with C#.
i,m using code below to execute and get out put from pg_dump.exe.
ProcessStartInfo startinfo = new ProcessStartInfo
{
FileName = "\"C:\\Program Files (x86)\\pgAdmin III\\1.16\\pg_dump.exe\"",
Arguments = "--host XXX.XXX.XXX.XXX --port 5432 --username \"USERNAME\" --no-password --format plain --verbose --file \"D:\\MYBACKUP.backup\" \"MYDBNAME\"",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
Process proc = new Process();
proc.StartInfo = startinfo;
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
var r = proc.StandardOutput.ReadLine();
}
proc.WaitForExit();
Console.WriteLine(proc.ExitCode);
Console.ReadLine();
but proc.StandardOutput.ReadLine always returns null!!!
i try to put pg_dump.exe output to a file with command propt like this:
C:\Program Files (x86)\pgAdmin III\1.16>pg_dump.exe > d:\log.txt
but again log.txt is empty!!
thanks in advance.
Replace RedirectStandardOutput with RedirectStandardError.
My working code is:
ProcessStartInfo startinfo = new ProcessStartInfo
{
FileName = "Path to pg_dump.exe",
Arguments = "Arguments",
UseShellExecute = false,
RedirectStandardError = true,
CreateNoWindow = true
};
using (Process process = Process.Start(startinfo))
{
using (StreamReader reader = process.StandardError)
{
StreamWriter sw = new StreamWriter(#"C:\log.txt");
sw.WriteLine(reader.ReadToEnd());
sw.Close();
}
}

Running / spawning commands vs files in c#

I can in C# do the following:
var pSpawn = new Process
{
StartInfo = { WorkingDirectory = #"C:\temp", FileName = fileToRun, CreateNoWindow = true }
};
pSpawn.Start();
and this works fine.... however I am wondering if there is a way to run a command (ie: "dir /b") without having to encapsulate it in a batch file?
Just start the cmd.exe and pass the arguments required
var pSpawn = new Process
{
StartInfo =
{
WorkingDirectory = #"C:\temp",
FileName = "cmd.exe",
Arguments ="/K dir /b" }
};
pSpawn.Start();
I have added the parameter /K to leave the command window open so, it is possible to see the output of the command dir.
Of course I think that you are really interested to catch the output of the command.
In this case you could work with something like this:
StringBuilder sb = new StringBuilder();
var pSpawn = new Process
{
StartInfo =
{
WorkingDirectory = #"C:\temp",
FileName = "cmd.exe",
Arguments ="/c dir /b",
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
UseShellExecute = false
}
};
pSpawn.OutputDataReceived += (sender, args) => sb.AppendLine(args.Data);
pSpawn.Start();
pSpawn.BeginOutputReadLine();
pSpawn.WaitForExit();
Console.WriteLine(sb.ToString());
You can call something like this:
ProcessStartInfo info = new ProcessStartInfo("cmd.exe");
info.Arguments = "/c dir /b";
Process.Start(info);

Categories