SCHTASKS Invalid Syntax in C# but working in CMD - c#

I've got a command I'm trying to run through C# to get a list of tasks in CSV format from a bunch of computers.
To do this, I am using the SCHTASKS command with command redirection to a CSV. So I wrote this code in C# to do this for me:
string commandGetStatus = "schtasks";
string argumentsGetStatus = "/s:" + CompName +
" /fo:csv" +
" > \"" + #"\\BIG\OL\UNC\PATH\"+CompName+".csv" + "\"";
getLatestTaskStatus.StartInfo.FileName = commandGetStatus;
getLatestTaskStatus.StartInfo.Arguments = argumentsGetStatus;
getLatestTaskStatus.StartInfo.CreateNoWindow = true;
getLatestTaskStatus.StartInfo.RedirectStandardOutput = true;
getLatestTaskStatus.StartInfo.RedirectStandardInput = true;
getLatestTaskStatus.StartInfo.RedirectStandardError = true;
getLatestTaskStatus.StartInfo.UseShellExecute = false;
getLatestTaskStatus.Start();
It returns the output:
ERROR: Invalid syntax.
Type "SCHTASKS /?" for usage.
So I used StartInfo.FileName + " " + StartInfo.Arguments to print out the exact command that should be being executed. From there, I copy and pasted the command into CMD. Where it worked without a problem. This was the command + args:
schtasks /s:COMPUTERNAME /fo:csv > "\\BIG\OL\UNC\PATH\COMPUTERNAME.csv"
I'm not sure what the problem is at this point.
My Solution
Luaan was absolutely correct about the problem. The command prompt redirection operator,>, is not available without using Command Prompt. Fortunately, the solution was quote simple and easy to implement. I reduced the argument variable to:
"/s:" + CompName + " /fo:csv"
And with standard output being redirected, I simply used:
string output = process.StandardOuptut.ReadToEnd();
File.WriteAllText(#"\\UNC\File\Path\" + myfile + ".csv", output);

You explicitly disabled UseShellExecute - > is a shell operator, not something inherent to processes. It definitely isn't an argument. You need to read the output and write it out manually :)

Related

How should I format a string when passing multiple arguments to Process.Start when part of the string is a var

I am trying to pass 2 arguments to the Process.start in c# and part of the string has to be a string var that is built from the input of the user.
This code works fine when I use a simple folder path but my path is determined by the user to the process.StartInfo.Arguments must = "-format mp4 -outfolder " + myVar.
I cannot get this to work.
Process process = new Process();
process.StartInfo.FileName = #"C:\Program Files (x86)\NCH Software\Prism\Prism.exe";
process.StartInfo.Arguments = "-format mp4 -outfolder C:/users/john";
process.Start();
The expected results would be the prism opening screen having the mp4 format automatically selected (which works fine) and the output folder is set by the variable. that part of the argument is being ignored and a default folder is being set up.
I think in your case you have to use \" \" between the var.
process.StartInfo.Arguments = "-format mp4 -outfolder #\" " + myVar + "\""
Follow this site and you can find more information.
https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.arguments?view=netframework-4.8
or else try,
string a = "aaa";
string b = "bbb";
Process.Start(#"something.exe ", "#"+ a + " " + b );

How can we avoid the gnupg passphrase prompt in C# for Windows?

I am trying to upgrade our legacy code from gnupg1.x to gnupg2.2.4. This is on Windows machine and I installed gnupg for windows gnupg-w32-2.2.4_20171220.exe.
I am stuck as my C# application keeps prompting me to enter the passphrase and time outs and is not able to decrypt the file and the process fails. All this time this application has run without much user intervention and we still want it that way. Is there anyway to avoid the passphrase prompt that comes up every time gnupg tries to decrypt a file?
This is what my current code looks like based on other feedback from this community but I cant figure out what I am doing wrong. It currently creates an empty file and there is no content. Although my encrypted file does have content in it.
I also read about using gpg --preset-passphrase but my release team is discouraging me from using that. Can you please help.
string _commandlineParams = "--home " + gnuHomedir + " --default-key " + "myRealIDKey" + " --batch" + " --passphrase-fd 0" + " --decrypt " + pathAndfile;
string vgpg = "echo " + gphrase + "|gpg ";
string gpgExecutable = Path.Combine(gnuBinDirectory, "gpg");
ProcessStartInfo pInfo = new ProcessStartInfo(gpgExecutable, _commandlineParams);
pInfo.WorkingDirectory = _gnuBinDirectory;
pInfo.CreateNoWindow = true;
pInfo.UseShellExecute = false;
pInfo.RedirectStandardInput = true;
pInfo.RedirectStandardOutput = true;
pInfo.RedirectStandardError = true;
string sCommandLine = vgpg + " " + _commandlineParams;
if (sCommandLine != null)
{
_processObject.StandardInput.WriteLine(sCommandLine);
//_processObject.StandardInput.WriteLine(gphrase); -- tried this too but didnt work
_processObject.StandardInput.Flush();
}
_processObject.StandardInput.Close();
I have also faced the same problem. It was repeatedly asking for Passphrase in a GUI. So after many head hunts found a solution.
Use command text as
gpg --output "decrypted_file_name" --batch --passphrase "passphrase_goes_here" --decrypt "encrypted_file_name"

Netstat focus on (find port)

Im recently trying to execute the following line ;
string strCmdText;
strCmdText = "netstat -np TCP | find " + quote + number + quote + "";
System.Diagnostics.Process.Start("netstat.exe", strCmdText);
Logs.Write("LISTEN_TO(" + Registry_val1.Text + ")", strCmdText);
now what this has to do is basicly find all TCP ports that contain '80' in them and show them up in my custom-made log system that will make a logbook in my folder called;
LISTEN_TO(80)-{date_time}.txt
inside this .txt it should contain the command issued text, however all i get is a time.
i debugged this command as above, and unfortunately all i know is that the CMDtext is set correctly, and that my logging system works correctly, leaving me with no choice that NETSTAT may be closed as soon as the query is launched?
hopefully i provided anough information, as this is my first post.
Regards,
Co
Due to vague description, here's an other-sort same code i tried to do, however still remain getting only a time.
const string quote = "\"";
Process p = new Process();
p.StartInfo.FileName = "cmd";
p.StartInfo.Arguments = "netstat -np TCP | find " + quote + number + quote + "";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
String output = p.StandardOutput.ReadToEnd();
Logs.Write("LISTEN_TO(" + Registry_val1.Text + ")", output);
basicly, you could see this as; textbox1.text = output; execpt now the output is being putten to a log file.
I don't understand why you use netstat in the first place. The .Net framework has a load of classes that give all kind of data, in this case IPGlobalProperties has the method you need.
var ip = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties();
foreach(var tcp in ip.GetActiveTcpConnections()) // alternative: ip.GetActiveTcpListeners()
{
if (tcp.LocalEndPoint.Port == number
|| tcp.RemoteEndPoint.Port == number)
{
Logs.Write(
String.Format(
"{0} : {1}",
tcp.LocalEndPoint.Address,
tcp.RemoteEndPoint.Address));
}
}
The benefit of using the build-in classes is the ease of shaping and selecting whatever you need and most important: you spare yourself and your user an out-of-process call and parsing of output.
You may try this:
strCmdText = "cmd /c \"netstat -np TCP | find " + quote + number + quote + "\"";
if this does not work, try first to use the command in a cmd prompt to make sure it returns data.
cmd /c "netstat -an | find "80"

Calling Accurev "hist" from C# process

I can't be sure if this is an issue specific to Accurev, or is more to do with calling the command line from C#. I'll make the question and its tags more specific when I work out which it is.
I've got the following two calls that I can successfully make using command prompt :
accurev stat -d -s "ProductionSupport" -fx
accurev hist -s "ProductionSupport" -ftx -e "1570567"
And in both cases I can see xml as a result.
However I want to make these calls from a C# program, and the first one of those works great but inexplicably the second one returns an empty string.
public string CallAccurev(string arguments)
{
Process cmdUtility = new Process
{
StartInfo =
{
FileName = "C:\\Program Files (x86)\\AccuRev v5.5\\bin\\accurev.exe",
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
cmdUtility.Start();
var s = cmdUtility.StandardOutput.ReadToEnd();
cmdUtility.WaitForExit();
return s;
}
My calls look like this :
var checkInComment = CallAccurev("hist -s " + _streamName + " -e " + Convert.ToString(processedFile.TransId) + " -ftx");
var filesString = CallAccurev("stat -d -s " + _streamName + " -fex");
As an attempt to get around this I've tried putting my "hist" call and its parameters into a .Bat file. I can see that double clicking that file gives the intended behaviour but when I call it from code I get empty strings again.
Any answers or clues on how to debug what is happening during my hist call are greatly appreciated!
I would think you would need to read the standard output AFTER the process has completed.
cmdUtility.WaitForExit();
var s = cmdUtility.StandardOutput.ReadToEnd();
However, reading Accurev output directly can sometimes overflow the buffer. You might want to investigate using asynchronous reading. How to spawn a process and capture its STDOUT in .NET?

Issue when passing multiple arguments to an external exe program using c#

I have an exe file in which I am trying to pass arguments through c#. the code is as follows
class Class1
{
static void Main()
{
string[] arg;
arg = new string[3];
Process p = new Process();
p.StartInfo.FileName = #"D:\xxx.exe";
for (int i = 0; i < 3; i++)
{
arg[i] = Console.ReadLine();
}
p.StartInfo.Arguments = arg[0] + " " + arg[1] + " " + arg[2];
p.Start();
}
}
I open up a console and then write the arguments there. As soon as I am finished typing 3 arguments, I make a string out of the 3 arguments and then call Process.Start() with the arguments in the p.StartInfo.Arguments string. The exe file loads but it does not generate any output. The strange thing is that if I open the exe file from my computer and then write
Arg1.txt Arg2.txt Arg3.txt
and press enter the exe file generates the output. However the same arguments in the same style are currently being passed through C# code and it is not generating any output. I donot understand what I am doing wrong. There are multiple questions on StackOverflow about this, I know that, however they all suggest the same procedure as what I have done here. I have also tried giving arguments as
p.StartInfo.Arguments = "\"arg[0]\"\"arg[1]\"\"arg[2]\"";
but this also has not worked.
Try this:
p.StartInfo.Arguments = "\"" + arg[0] + " " + arg[1] + " " + arg[2] + "\"";
p.Start();
It is recomended to use "" when you use several parameters between gaps.
EDIT: No "\" have to be included if you type it ok. It is the escape character. See picture below.

Categories