I need to ensure that my widnows app (winform not console) runs under a certain user account (in other words any user can be logged on to the maching but the .exe will always execute as the specified user).
Can this be done programtically? If so, how?
You can start the application like this:
ProcessStartInfo psi = new ProcessStartInfo(myPath);
psi.UserName = username;
SecureString ss = new SecureString();
foreach (char c in password)
{
ss.AppendChar(c);
}
psi.Password = ss;
psi.UseShellExecute = false;
Process.Start(psi);
One thing you could do in your app is check if you're running as the desired user, and if not, create a new instance of your app as that other user. The first instance would then exit.
To check which user you are running as, you could adapt the solution from here so that the process queries itself for its token information.
Use CreateProcessWithLogonW, passing the LOGON_WITH_PROFILE login flag. The user you are logging in as must have the appropriate policies set to be allowed to log on interactively.
EDIT: Now that you have indicated that you are using .NET, here's how you should do it:
First you need to find out which user you are currently running as. Use the WindowsIdentity class from the System.Security.Principal namespace. Call its GetCurrent method to obtain the WindowsIdentity object for the user that you are running as. The Name property will give you the actual user name that you are running under.
In your ProcessStartInfo object, set LoadUserProfile = true, the FileName field, possibly the Arguments field, the UserName and Password fields, possibly the Domain field, and set UseShellExecute = false. Then call Process.Start(), passing in your ProcessStartInfo object.
Here's a sample that I threw together, but I don't have a C# compiler installed to test it:
using System;
using System.Diagnostics;
using System.Security;
using System.Security.Principal;
// Suppose I need to run as user "foo" with password "bar"
class TestApp
{
static void Main( string[] args )
{
string userName = WindowsIdentity.GetCurrent().Name;
if( !userName.Equals( "foo" ) ) {
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "testapp.exe";
startInfo.UserName = "foo";
SecureString password = new SecureString();
password.AppendChar( 'b' );
password.AppendChar( 'a' );
password.AppendChar( 'r' );
startInfo.Password = password;
startInfo.LoadUserProfile = true;
startInfo.UseShellExecute = false;
Process.Start( startInfo );
return;
}
// If we make it here then we're running as "foo"
}
}
Related
Hi I'm trying to change the startup type of a existing Windows service. Say "Spooler" ( Print Spooler). I'm using ServiceController
var service = new ServiceController("Spooler");
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, 600);
Though I'm able to start/stop services I'm not able to figure out how can I change the startup type itself? ( eg: Disabled/Automatic/Manual )
When I peek definition of ServiceController I can see ServiceStartMode being defined. Could someone help me how can I set this option?. My need is to disable a Windows service programmatically using ServiceControl class or any other feasible way..
The simplest way is to use a sc command tool:
Example for changing the startup type to disabled:
sc config "MySql" start=disabled
Note you need to have the administrator privileges to run this command successfully.
Wrapping with C# code:
var startInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "CMD.EXE",
Arguments = string.Format("/C sc {0} {1} {2}", "config", "MySql", "start=disabled"),
};
using (var process = new Process { StartInfo = startInfo})
{
if (!process.Start())
{
return;
}
process.WaitForExit();
Console.WriteLine($"Exit code is {process.ExitCode}");
}
Update:
Use process.Exit code to check if process the operation succeeded or not.
0 ExitCode is success.
Note: In case you are running the process/Visual Studio without the Admin privileges, the ExitCode will be 5 (access deined).
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.
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.
Below is the scenario.
Logged in to windows using user name "JOHN"
Run the Windows application writtern in c# . This tool name is BootStrapper.exe. But this tool I executed using different user called "ALEX" using Run As feature.
Boot strapper will show some button called "Launch Application". On clicking Launch executing Application.exe using Process class of c#. Note that i am not passing any user name and password. So Application.exe is also running under "ALEX" User.
How do I run the Application.exe under "JOHN" from Bootstrapper.exe even though it is started by "ALEX".
Note that the password of the "JOHN" will not be known to Application.exe to impersonate JOHN user.
Host a WCF service in a process started by JOHN (maybe by putting it in the startup folder).
Call the WCF service from the ALEX process with a command telling what process to start.
Start the process from the WCF service and it will be running as JOHN.
I apologize for my bad English. Maybe I wrong understand you... Compile it, and copy result to "C:\test" directory. Now run it.
using System;
using System.Text;
using System.Diagnostics;
using System.Security;
using System.Reflection;
using System.IO;
namespace ConsoleApplication6 {
class Program {
unsafe static void Main(string[] args) {
Process process = new Process();
String dir = Path.GetDirectoryName(typeof(Program).Assembly.Location);
String txtFile = Path.Combine(dir, "example.txt");
if (!File.Exists(txtFile)) {
StreamWriter sw = File.CreateText(txtFile);
sw.Close();
sw.Dispose();
}
ProcessStartInfo info = new ProcessStartInfo();
info.Domain = "myDomainName";
info.UserName = "userName";
String pass = "userPassword";
fixed (char* password = pass) {
info.Password = new SecureString(password, pass.Length);
}
// Will be run notepad.exe
info.FileName = Environment.ExpandEnvironmentVariables(#"%winDir%\NOTEPAD.EXE");
// in notepad.exe will be open example.txt file.
info.Arguments = txtFile;
info.LoadUserProfile = false;
info.UseShellExecute = false;
info.WorkingDirectory = dir;
process.StartInfo = info;
process.Start();
}
}
}
Regards
I have a process that needs to run under administrative privileges. I need the average joe to run the process, but I don't want to give everyone access... so I've created a simple class that will run this ONE task as an administrator, using impersonation.
The code is VERY striaght-forward, but I can't understand why this is crashing. HELP??!!
I'm running this via a batch file, and I've even copied the file that needs to execute to the local hard drive, thinking this might be a permission issue for running an app over the network.
public static Process ImpersonateProcess(string exe, string args, string Username, string Password)
{
ProcessStartInfo psi = new ProcessStartInfo(exe);
psi.Arguments = args;
psi.UseShellExecute = false;
psi.UserName = Username;
psi.Password = new SecureString();
foreach (char c in Password.ToCharArray())
{
psi.Password.AppendChar(c);
}
Process proc = null;
Console.WriteLine("starting...");
proc = Process.Start(psi);
Console.WriteLine("started");
return proc;
}
In the code above, I never get to "started". It throws an error in the Process.Start(psi) and with an error message of "the directory name is invalid."
It could be because you're not setting the WorkingDirectory property. According to the
docs:
Important Note:
The WorkingDirectory property must be set if UserName and Password are provided. If the property is not set, the default working directory is %SYSTEMROOT%\system32.