I have been having trouble passing input programmatically to the system net user program using C#. I am trying to activate and set a password for a certain user account. By my investigations, it seems like the process finishes before anything can be passed. I do not know why the background net user program does not wait for input before exiting.
Here is the command I am running programmatically to accomplish this:
net user username /active:yes & net user username *
The output of the second command is as follows:
Type a password for the user:
Retype the password to confirm:
The command completed successfully
If you were to run the above command manually, it would ask you for the password and hide what you're typing from the screen. However, the program doesn't seem to stop when ran programmatically.
To call the program, I have a function that starts the program and returns the process to another function, which sends input to the process. Here is the first function:
static Process RunCommandGetProcess(string command)
{
Process process = new Process();
ProcessStartInfo psInfo = new ProcessStartInfo();
psInfo.FileName = "CMD.exe";
psInfo.Arguments = "/C " + command + "& PAUSE";
// Allow for Input redirection
psInfo.UseShellExecute = false;
psInfo.RedirectStandardInput = true;
// Window style
psInfo.WindowStyle = ProcessWindowStyle.Normal;
// Start the mothertrucker!
process.StartInfo = psInfo;
process.Start();
return process;
}
And the Calling function:
static int ActivateUserWithPassword(string password)
{
// Start net user with that other function
Process process = RunCommandGetProcess("net user username /active:yes & net user username *");
StreamWriter streamWriter = process.StandardInput;
streamWriter.WriteLine(password); // First Prompt
streamWriter.WriteLine(password); // Second Prompt
process.WaitForExit();
return process.ExitCode;
}
However, When I run the debugger, the commands complete successfully before the two streamWriter.WriteLine(password); lines are even met! I have tried Googling, but came to no avail.
You people are my only hope.
Okay! I have been highly motivated to solve your issue as soon as i saw it!. after 2 hours of non-stop debugging, i have a solution for you!.
Issue No .1 : Your application does not have Administrator privileges, that is why the command exits right after you start. Start the .exe with Admin Privileges.
Issue No. 2 : Since the password is masked in the input, Even if i did a streamWriter.WriteLine(password) once,The output is "Command Executed Successfully". There is no way of knowing if the password was actually passed or it took empty string as the password.
Solution
You can use the net user command with a parameter for password like this
net user user_name password. No need to prompt the user for password i.e Don't use '*' after username ,since you are passing it through the program.
So this is how it works
Process proc = new Process();
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "cmd";
start.Arguments = "/k";
start.RedirectStandardInput = true;
start.WorkingDirectory = Environment.CurrentDirectory;
start.UseShellExecute = false;
proc.StartInfo = start;
proc.Start();
proc.StandardInput.WriteLine("net user \"username\" password");
Very Very Important!!
Start the exe as an administrator OR you will have to do this
start.UseShellExecute = true;
start.Verb = "runas";
But then you wont be able to redirect the Output/Input streams!.
Related
I would like to check if State is DISABLED or ENABLED.
I opened the file D:\TOOLS\Security.bat and run it.
In addition i must insert password in CMD to continue program
and I want to C# write that password. Is that possible?
How can I insert password into open process in CMD?
The file must be opened with D:\TOOLS\Security.bat
Process process = new Process();
process.StartInfo.FileName = "D:\\TOOLS\\Security.bat";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
process.StandardInput.WriteLine("password");
process.StandardInput.Flush();
process.StandardInput.Close();
process.WaitForExit();
Console.WriteLine(process.StandardOutput.ReadToEnd());
Here is Security.bat file:
runas /user:Administrator c:\utility\info.bat
cls
Here is info.bat file:
ewfmgr c:
pause
When I write password in CMD I got that data.
From that data I would like to get State value.
But I don not know how to save this console data to string.
How can I get all data from last console call?
Here is my code for get state data.
string check= #"State(.)*DISABLED";
if (Regex.IsMatch(output, check)) {
// SECURE IS OFF
}
Thanks for help.
No, it's not possible to insert the password into the command prompt. it's specifically designed to prevent that.
What you CAN do is save the password in the credential cache on that particular machine. You do this with the runas command by using the /savecred switch. After you enter your password, it will no longer ask for it when you runas this app as that user.
I can call Process.Start(filename.sln) and it launches VisualStudio with that solution.
But doing so using ProcessStartInfo with Verb="runas" and I get an exception. Even with UseShellExecute=true.
Is there a way to launch an app running as admin where I pass it the app's data file and don't have the application.exe filename?
Found the answer - when you run as admin you can only give it the executable file, not the app for the program to run. So you have to pass devenv.exe, not filename.sln
ProcessStartInfo processInfo = new ProcessStartInfo(); //new process class
processInfo.Verb = "runas"; //wanna admin rights
processInfo.FileName = sDevPath + "devenv.exe"; //exe file path
processInfo.Arguments = sPrjPath + "mConverter.sln"; //sln file as argument
try
{
Process.Start(processInfo); //try to start
}
catch (Win32Exception)
{
//oops
}
I am running one batch file every few seconds to do timesync with server using following code:
Process process = new Process();
process.StartInfo.WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.System);
process.StartInfo.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe");
process.StartInfo.Arguments = #"/C C:\TimeSync.bat";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UserName = "username";
SecureString pwd = new SecureString();
Char[] pwdCharacters = "password".ToCharArray();
foreach (char t in pwdCharacters)
{
pwd.AppendChar(t);
}
process.StartInfo.Password = pwd;
process.Start();
string output = process.StandardOutput.ReadToEnd();
The problem is it flashes the command windows on the screen which I don't want. How can I prevent that?
One behavior I have seen is if I run the same code with UseShellExecute = true and don't provide username and password then the command window doesn't flash.
So basically I want to run .bat file using c# code as different user silently.
Because you are passing a user name and password, the CreateNoWindow parameters are not respected. This is a feature (i.e. bug) in windows. Here's the five year old connect details:
http://connect.microsoft.com/VisualStudio/feedback/details/98476/cmd-windows-shows-using-process-with-createnowindow-when-using-username-password-option
Process.Start() calls advapi32.dll's
CreateProcessWithLogonW in the event
that a user supplies a username and
password, and CreateProcessWithLogonW
always opens a new window.
Unfortunately, there is no workaround
for this behavior
An excellent overview of the create no window option is given here:
http://blogs.msdn.com/b/jmstall/archive/2006/09/28/createnowindow.aspx
which also points out errors in the msdn documentation on this topic.
And there's a very good overview in this stackoverflow answer:
How to hide cmd window while running a batch file?
In the end, I think you want to create a separate little app that you call out to only once, and it runs the whole time, as the escalated user. It can then perform the time sync as often as you want, in the same manner as you've described above, but without having to specify username and password. Thus there will only be one 'flash' of a console window for the entire duration of the application.
Hope this helps
lb
Change your line:
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
to
process.StartInfo.WindowStyle =
ProcessWindowStyle.Hidden;
That will hide the window and never show it.
Hope that helps!
Phil
Did you try to just specify:
process.StartInfo.CreateNoWindow=true;
?
You could use impersonation. I've written an impersonation class that implements the IDisposable interface and is rather straightforward to use, I hope.
Due to the joys of UAC, I need to open an elevated command prompt programmatically and then redirect the standard input so I can use the time command.
I can open the link (a .lnk file) if I use
Process ecp = System.Diagnostics.Process.Start("c:/ecp.lnk");
however, if I use this method, I can't redirect the standardIn.
If I use the StartProcessInformation method (which works wonderfully if you are calling an exe)
ProcessStartInfo processStartInfo = new ProcessStartInfo("c:/ecp.lnk");
processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
Process process = new Process();
process.StartInfo = processStartInfo;
bool processStarted = process.Start();
StreamWriter inp = process.StandardInput;
StreamReader oup = process.StandardOutput;
StreamReader errorReader = process.StandardError;
process.WaitForExit();
I get the error message:
The specified executable is not a valid Win32 application.
Can anyone help me create an elevated command prompt which I can capture the standard input of? Or if anyone knows how to programatically escalate a command prompt?
In case no-one comes up with a better idea (pretty please), here is the work around one of the more devious in my office just came up with:
Copy cmd.exe (the link it pointing at this file)
Paste this file into a different directory
Rename the newly pasted file to something different
Set the permissions on this new file to Run As Administrator
You will still get the escalation dialog popping up, but at least you can capture the standardIn of this valid Win32 app!
I'm trying to run a Jscript task from a C# console application.
The Jscipt file is not mine so I can't change it. The script moves some files and this is what is causing the issues.
When I run the script manually, i.e. form the shell it executes correctly. When I try and run the script from my console application the bulk of the process runs but I get a ":Error = Permission denied" error when it tries to move the files.
I've tried every permutation of the Diagnostics.Process class that I can think of but I've had no luck.
My current code:
Process process = new Process();
process.StartInfo.WorkingDirectory = Path.GetDirectoryName((string)path);
process.StartInfo.FileName = #"cmd.exe";
process.StartInfo.Arguments = "/C " + (string)path;
process.StartInfo.UseShellExecute = false;
process.StartInfo.Verb = "runas";
process.StartInfo.LoadUserProfile = true;
process.StartInfo.Domain = "admin";
process.StartInfo.UserName = #"cardax_sync_test";
process.StartInfo.Password = GetSecureString("abc123");
process.Start();
process.WaitForExit();
Any ideas?
Thanx
Rookie Mistake!
I forgot to close the text reader that creates one of the input files for the jscript.
I'll submit this question for deletion when it get's old enough. Don't want more useless info clogging up the net!