Under which user account does Process.Start start? - c#

I run on the machine as admin, but with the UAC set to default mode.
I start an installation program (using "Run as administrator"). From the installation process (using Wix) I start a client program that creates some files on the disc (C:\ProgramData...).
var startInfo = new ProcessStartInfo()
{
WorkingDirectory = installLocation,
FileName = fullPath
};
Process.Start(startInfo);
This first time the program runs, I can access all the data stored on the local disc without problems.
If I close it and start it again, I receive this error message:
Access to the path 'C:\ProgramData...' is denied.
If I start again the application using "Run as administrator" I can access the files from local disc; no error this time. The access path error appears only when I start the application directly.
Is this due to the settings from UAC or it is related that the local files where created under a more privileged user account?

Yes, the application will run without elevated privileges which are required to access ProgramData and other sensitive system folders or user related folders.
Any process you spawn from within your application will inherit the privileges your application has.
You need to create a manifest for your application to request elevated rights upon starting so you will have access to those folders.

Yes, as you say the local files are created under a more privileged user account.
You can check this passing the admin credential with ProcessStartInfo
var startInfo = new ProcessStartInfo()
{
WorkingDirectory = installLocation,
FileName = fullPath,
UserName = "Administrator",
Password = "password"
};
You can bypass this simply creating the ProgramData folder with lower privileges:
Add "Everyone" privilege to folder using C#.NET

or you can force that the application has to be started with administrator rights..
Project - Add New Item - "Application Manifest File".
change
<requestedExecutionLevel>
to
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>

When starting a new process, it inherits the privileges of the current process.
So if your process was elevated, the created process is elevated too. Second time you run your program, if it's not elevated, the spawned process won't be too.
You can specify the runas verb to force the display of the UAC pop-up that will allow to manually elevate your spawned process:
ProcessStartInfo startInfo = new ProcessStartInfo
{
UseShellExecute = true,
FileName = "cmd.exe",
Verb = "runas"
};

Related

Process cannot find file specified

I have the following issue:
I have a C# app that runs as a 32-bit Application on my 64-Bit Machine. This application opens a process and starts wbadmin to make a backup of the C drive.
Now: when I call enter "wbadmin" in the command line wbadmin works and shows lists all its commands.
In my c# app when i do
ProcessStartInfo info = new ProcessStartInfo("wbadmin", $"start backup -backupTarget:{destinationDrive} -include:C: -quiet -vssCopy")
{
UseShellExecute = false
};
Process p = new Process()
{
StartInfo = info,
EnableRaisingEvents = true
};
p.Start();
it tells me that the file specified cannot be found.
I did some research and I think my app is looking for the wbadmin in the WOW64 folder, where it cant find it because it is inside the System32 Folder.
How do I tell my program to use the correct wbadmin.exe in the correct location?
Do I HAVE to run the app as a 64-bit application for it to work?
If so how would i support 32-bit architecture?
Thanks
Thanks to #PavelAnikhouski for providing me with the correct answer.
I had to specify the path to sysnative.

Getting "Access is Denied" error on Process.Start() on an application running an executable with all permissions granted

The context here is that we have a C# service that normally runs scheduled jobs, but an executable was created that allows jobs to be triggered manually via command line. We put that executable on a separate IIS server, and did NOT install it as a service. The code inside the app to determine how it's being run is simply:
if (Environment.UserInteractive)
{
//parse the parameters and run the specified job
}
else
{
//start the service jobs
}
I made an API as a wrapper to call that executable, which uses the following code to run the executable with arguments as a user of the machine.
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
WorkingDirectory = (absolute path of the folder that contains the exe),
FileName = (absolute path to the exe),
Arguments = (args),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
Domain = (domain),
UserName = (username),
Password = (password),
Verb = "runas"
}
};
proc.Start();
proc.WaitForExit();
The API and the exe live in the same base folder. The API runs in IIS under an app pool user that is the same user it is running the process with. This user has Full Access permissions to the folder and executable, as well as the app pool user. We also added the user to the Administrator's group on that machine.
Running the exe via command line locally on that machine works fine. Only when calling from this application do we get the following error:
System.ComponentModel.Win32Exception (5): Access is denied
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
I've confirmed that we are targeting the right file, that my SessionId is not 0 (I would get an error saying the service was not installed whenever I didn't start the process as a specified user), and that the app pool user and windows user have permissions to execute the file. UAC is off, and the API and exe are not on the C:/ drive. After hours of googling and trying different things, I'm out of ideas. Any help would be very appreciated.

How to accessing admin local data location from non-admin user?

I have an installer that will run as adminstrator. On installing that exe in non-admin system account, some files shipped in administrator local appdata location. I need to access admin local appdata location (C:\Users{ admin user name}\AppData\Local) using process in console app that is in non-admin account.
Process proc = new Process();
proc.StartInfo.FileName = #"C:\Users\{admin user name}\AppData\Local";
proc.Start();
But current user local appdata location opened in file explorer while run. Could you please help me to resolve this?
Using the below code works for me!!!
Process.Start("explorer.exe",#"C:\Users\{admin user name}\AppData\Local");

Calling a .exe as Admin from within my code in Program Files folder

I have a C# application which calls an .exe file. This executable file must be started with administrator rights. But I don't want to run my application with admin rights.
I use the following code for that:
ProcessStartInfo procStartInfo = new ProcessStartInfo("foo.exe");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.Verb = "runas";
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
If I put my application in no specific folder, everything works fine, when calling the executable, the user is asked to run it as admin. But when I put my application in the "Program Files" folder and start it, when calling the execution file, there is NO question to run it as admin. And because of that, execution fails.
I'm using Windows 7 and the executable file is not lying in the "Program Files" folder. Is there a way to always run this file as admin but not my application?
Just add a manifest to the target application stating that it should be run as admin. The responsibility for that generally lies with the application being started, not the application which starts it.
An exception would be cases like Notepad being called to open a shared configuration file, but you haven't provided enough details to determine that.
Just Add a new Application manifest file in your project and
change this <requestedExecutionLevel> as
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

SC.EXE - Calling from C# - Access Denied

I have a batch file I wrote (proof of concept) to install a sample service I also created. It contains the following command line:
sc create serviceTest binPath= C:\Sandbox\ServiceTest\ServiceTest.exe DisplayName= "Service Test"
When I right click and select 'Run as Administrator' everything runs as expected. Running the batch file without doing this gives 'Access Denied'. This is proof that the command works.
I have also tried running the sc command via Process.Start():
const string sc = #"sc";
const string arguments = #"create serviceTest binpath= {0} DisplayName= ""Service Test""";
FileInfo fi = new FileInfo(this.txtServiceLocation.Text);
if (fi.Exists)
{
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = sc,
Arguments = string.Format(arguments, fi.FullName),
UserName = "admin",
Password = "secret".ToSecureString(),
Domain = "MYDOMAIN",
WorkingDirectory = fi.DirectoryName,
CreateNoWindow = true,
UseShellExecute = false
};
Process.Start(psi);
}
else
MessageBox.Show("The service exe could not be found.");
I need to be able to do this programatically. What do I need to do to get this to work?
CLARIFICATION: I need to be able to do this without a user being prompted. This code will be running under a custom tfs build process.
In Windows 7 by default, runs most applications with least privilege access (non-admin) control. As your application is trying to modify the system, it needs to be elevated to Admin privilege in order to run successfully. If you want to make this app to run in admin privilege permanently, please follow the instructions as in the link
http://www.groovypost.com/howto/microsoft/automatically-run-any-application-as-admin-in-windows-7/
You need to add a UAC manifest file to your assembly in order to force UAC to run the process as an administrator. For a reference to other solutions, you can see UAC need for console application.
While I never got this to work I can still use impersonation via code and also ensure that the tfs build account has appropriate access. This is what I had to do.

Categories

Resources