I am developing an App where I need to Run Git Command from C#. I used Process to run Commands if I am passing user Name and password then Is says UserName or Password is Incorrect but it actual working Conventional. Below is my Code:-
public static void PullCode(string gitCommand)
{
string strPassword = "Password";
ProcessStartInfo gitInfo = new ProcessStartInfo();
Process gitProcess = new Process();
gitInfo.CreateNoWindow = true;
gitInfo.UserName = "UserNAme";
gitInfo.Password = Misc.ConvertPassword(strPassword);
gitInfo.UseShellExecute = false;
gitInfo.FileName = #"C:\Program Files (x86)\Git\bin\git.exe"; //git repostory directory path
gitInfo.Arguments = gitCommand; //git command such as "fetch orign"
gitInfo.WorkingDirectory = #"E:\Code Demo\testrepo"; //YOUR_GIT_REPOSITORY_PATH Where you want to Copy Data
gitInfo.RedirectStandardError = true;
gitInfo.RedirectStandardOutput = true;
using( var proc = new System.Diagnostics.Process() )
{
proc.StartInfo = gitInfo;
proc.Start();
var output = proc.StandardOutput.ReadToEnd();
var error = proc.StandardError.ReadToEnd();
var logRaw = string.IsNullOrEmpty( output ) && !string.IsNullOrEmpty( error )
? error.Split( '\n' ).ToArray()
: output.Split( '\n' ).ToArray();
proc.WaitForExit();
proc.Close();
}
}
You have two options. The first one is to set the configuration for your git repo (or globally) to use the git askpass witch is "git config core.askpass git-gui--askpass". Call this as the first command for your process. The drawback here is that each time you do a modifying command it will ask for password.
Or you can have your own executable witch will ask for password once, and have the option to store the password into your application. But here you will have to be careful since if you don't store it properly it will be a security risk.
Related
enter image description here
I setting my WorkerService appsettings.json like below
"AppRun": {
"App1": {
"AppName": "CheckDataForm",
"AppPath": "D:\\2021-Project\\Project\\CheckDataForm-MSSQL\\CheckDataForm\\bin\\Debug\\net5.0-windows\\CheckDataForm.exe"
},
"App2": {
"AppName": "notepad++",
"AppPath": "C:\\Program Files\\Notepad++\\notepad++.exe"
},
and call the app like this:
//i is foreach count
var AppName = _config["AppRun:App"+i+":AppName"];
var AppPath = _config["AppRun:App" + i + ":AppPath"];
//check file exist
var fileExist = System.IO.File.Exists(AppPath);
if ( !String.IsNullOrEmpty (AppName) && !String.IsNullOrEmpty(AppPath) &&
fileExist )
{
//find APP
var processApp = Process.GetProcessesByName(AppName);
//can't find app
if (processApp.Length <=0 )
{
try
{
Process proc = new Process();
proc.StartInfo.FileName = AppPath;
proc.StartInfo.WorkingDirectory =
System.IO.Path.GetDirectoryName(AppPath);
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.WindowStyle =
ProcessWindowStyle.Maximized;
proc.Start();
}
catch (Exception ex)
{
var error = ex;
}
}
}
the Process can Start notepad++ And CheckDataForm , but notepad++ And CheckDataForm AP run in [Background processes] , I need AP Run in [Apps]
How To Executable under Apps , Not in Background Process
, like image show
You can execute the program using the CMD:
Process proc = new Process();
proc.StartInfo.FileName = "CMD";
proc.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(AppPath);
proc.StartInfo.Arguments = "/C "+AppPath;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
proc.Start();
That way will be ran as if you run it as the logged user.
Since you are using a Service, you could use a predefined TASK from the Task Scheduler to run the program:
var ts = new TaskService();
var task = ts.FindTask("mainTVMTask2");
task.Run();
The nugget package used was:
TaskScheduler by David Hall
This last code is being used right now to keep an app running, the service is checking if the process is in the process list, if its not, will run that task, previusly created in the Task Scheduler.
You might choose the user that will be logged in order to run the process instead of the service that will run with System Account.
The action is a standard run command to start the program that you need.
I want to run a gpu accelerated python script on windows using conda environment (dlwin36).
I’m trying to activate dlwin36 and execute a script:
1) activate dlwin36
2) set KERAS_BACKEND=tensorflow
3) python myscript.py
If I manually open cmd on my machine and write:"activate dlwin36"
it works.
But when I try opening a cmd from c# I get:
“activate is not recognized as an internal or external command, operable program or batch file.”
I tried using the following methods:
Command chaining:
var start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.Arguments = "/c activate dlwin36&&set KERAS_BACKEND=tensorflow&&python myscript.py";
Process.Start(start).WaitForExit();
(I’ve tested several variations of UseShellExecute, LoadUserProfile and WorkingDirectory)
Redirect standard input:
var commandsList = new List<string>();
commandsList.Add("activate dlwin36");
commandsList.Add("set KERAS_BACKEND=tensorflow");
commandsList.Add("python myscript.py");
var start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.UseShellExecute = false;
start.RedirectStandardInput = true;
var proc = Process.Start(start);
commandsList.ForEach(command => proc.StandardInput.WriteLine(command));
(I’ve tested several variations of LoadUserProfile and WorkingDirectory)
In both cases, I got the same error.
It seems that there is a difference between manually opening cmd and opening it from c#.
The key is to run activate.bat in your cmd.exe before doing anything else.
// Set working directory and create process
var workingDirectory = Path.GetFullPath("Scripts");
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
UseShellExecute = false,
RedirectStandardOutput = true,
WorkingDirectory = workingDirectory
}
};
process.Start();
// Pass multiple commands to cmd.exe
using (var sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
// Vital to activate Anaconda
sw.WriteLine("C:\\PathToAnaconda\\anaconda3\\Scripts\\activate.bat");
// Activate your environment
sw.WriteLine("activate your-environment");
// Any other commands you want to run
sw.WriteLine("set KERAS_BACKEND=tensorflow");
// run your script. You can also pass in arguments
sw.WriteLine("python YourScript.py");
}
}
// read multiple output lines
while (!process.StandardOutput.EndOfStream)
{
var line = process.StandardOutput.ReadLine();
Console.WriteLine(line);
}
You need to use the python.exe from your environment. For example:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\path-to-Anaconda3\envs\tensorflow-gpu\python.exe";
or in your case:
start.Arguments = "/c activate dlwin36&&set KERAS_BACKEND=tensorflow&&\"path-to-Anaconda3\envs\tensorflow-gpu\python.exe\" myscript.py";
I spent a bit of time working on this and here's the only thing that works for me: run a batch file that will activate the conda environment and then issue the commands in python, like so. Let's call this run_script.bat:
call C:\Path-to-Anaconda\Scripts\activate.bat myenv
set KERAS_BACKEND=tensorflow
python YourScript.py
exit
(Note the use of the call keyword before we invoke the activate batch file.)
After that you can run it from C# more or less as shown above.
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.Arguments = "/K c:\\path_to_batch\\run_script.bat";
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.WorkingDirectory = "c:\\path_to_batch";
string stdout, stderr;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
stdout = reader.ReadToEnd();
}
using (StreamReader reader = process.StandardError)
{
stderr = reader.ReadToEnd();
}
process.WaitForExit();
}
I am generating the batch file on the fly in C# to set the necessary parameters.
If this is gonna help anyone in the future. I found that you must run the activation from C:\ drive.
Use case: I am checking certain credentials on a remote system by running commands via PsExec (i.e. for this example, I am trying to retrieve the KB articles currently installed on the remote system).
I have the following to retrieve command output:
public string GetCmDOutput(string cmd)
ProcessStartInfo startInfo = new ProcessStartInfo("control", cmd)
{
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
string output = string.Empty;
Process process = Process.Start(startInfo);
process.OutputDataReceived += (sender, e) => output = string.Concat(output, e.Data);
process.BeginOutputReadLine();
process.Start();
process.WaitForExit();
Delay.Milliseconds(1500) //API-specific delay
return output;
}
Whenever I use GetCmdOutput() to run a command locally it works like a charm, but if I try to run a command with PsExec, my output is empty.
For instance, I ran the following:
string cmd = #"\psexec.exe \\remoteComputerName -u username -p password -c cmd /c wmic qfe";
GetCmdOutput(cmd);
Report.Info(cmd); //API-specific reporting
And an empty string was returned.
After playing around with this for a couple of hours, I feel I may need a second set of eyes. What might be causing this issue?
I have run into this same problem. My solution was to run cmd and have it call psexec. I have psexec's output saved to a temp file for further manipulation. My code is returning a List.
public List<string> ExecutePSExec(string hostname)
{
List<string> recordNames = new List<string>();
string command = #"\\path\to\psexec.exe /accepteula \\" + hostname + ". exe-to-run-remotely";
try
{
string location = AppDomain.CurrentDirectory.BaseDirectory;
string cmdWithFileOutput = string.Format("{0} >{1}temp.log", command, location);
procStartInfo.UseShellExecute = true;
procStartInfo.CreateNoWindow = true;
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
// Read file contents, manipulate data and then delete temp file here
}
catch (Exception e)
{
Console.WriteLine("Failure to run psexec: {0}", e.Message);
}
return recordNames;
}
NOTE: I ran into another problem and found out that running psexec this way requires the remote hostname (not IP Address) in the command to end in a period \\" + hostname + ".
This code assumes you can run psexec on the remote machine as your current user.
I'm trying to run powershell script, but during this operation is required administrator rights for powershell.exe.
Using this example everything working successfully
var process = new Process();
const string password = "pwd";
SecureString str;
char[] chArray = password.ToCharArray();
unsafe
{
fixed (char* chRef = chArray)
{
str = new SecureString(chRef, chArray.Length);
}
}
var info = new ProcessStartInfo
{
FileName = "powershell.exe",
//UserName = username,
//Password = str,
//Domain = domain,
UseShellExecute = true,
Verb = "runas",
Arguments = arguments
};
process.StartInfo = info;
process.Start();
but it calls User Account Controll and I should press "OK".
if I comment verb and set shellexecute as false PS console starting with non-administrator rights.
How can I avoid UAC to run powershell.exe with administrator rights?
You have to disable UAC, you can google for instructions. End users of your app will have to deal, but you can ensure your app has admin rights off the jump by altering the manifest.
i want to pass the value of a lable or textbox in an aspx page to a console.exe application
such that the if the value is sample.doc it changes to that.
i am calling from the aspx page with
string f = TextBox1.Text;
System.Diagnostics.Process.Start("C:/DocUpload/ConsoleApplication1.exe", f);
i have tried converting to string then using the string vatiable inplace of sample.doc but no luck
object FileName = System.IO.Path.Combine(ExecutableFileInfo.DirectoryName, "sample.doc");
any help or ideas will be welcomed.
thank u
You're probably trying to process a file that is in a different folder.
If so, you need to pass the full path of the file, like this:
Process.Start(#"C:\DocUpload\ConsoleApplication1.exe",
Path.Combine(#"C:\path\to\folder", TextBox1.Text));
Here is what I use to start processes from calling applications. Since you are calling it from a web-app you are going to need to make sure you have appropriate permissions.
Process proc = new Process();
StringBuilder sb = new StringBuilder();
string[] aTarget = target.Split(PATH_SEPERATOR);
string errorMessage;
string outputMessage;
foreach (string parm in parameters)
{
sb.Append(parm + " ");
}
proc.StartInfo.FileName = target;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = sb.ToString();
proc.Start();
proc.WaitForExit
(
(timeout <= 0)
? int.MaxValue : (int)TimeSpan.FromMinutes(timeout).TotalMilliseconds
);
errorMessage = proc.StandardError.ReadToEnd();
proc.WaitForExit();
outputMessage = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
A link to MSDN:
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.start.aspx
You'll also need to check to make sure that the account the Web application is running under has the appropriate permissions to execute the program.