I need to start an application from another application. It looks like I have to use the shell to do it (since I need to be able to close the launcher), but I also would like to downgrade the rights given to the launching application.
Is this possible? The launcher must run as administrator, but I'd like to have the launching application run as user.
this is how I currently run the process:
Process process = new Process();
process.StartInfo = new ProcessStartInfo();
process.StartInfo.FileName = name;
process.Start();
Forgive me I forgot to add a couple of details:
I need to run it in .net 3.5 on mono
I'd prefer to not use native code
I need to run the launcher application in admin mode
This seems to be have discussed before, check this out: How do you de-elevate privileges for a child process
Looks like an UAC elevation is strictly one-way, so the solutions are a bit gnarly, i.e. code injection into explorer and stuff like that.
http://www.codeproject.com/Articles/18946/High-elevation-can-be-bad-for-your-application-How
Eventually I decided to create a bootstrapper that could run the launcher as administrator, but then the application as normal user. Once the launcher is done it goes back to the bootstrap executable which launches the application.
Related
I have a custom application running as a the shell (Windows 10 Enterprise) for a particular user - i.e. the user boots straight into this application.
However, I want to be able to provide access to the WiFi settings form. I have read that the way to do this is something like
Process.Start("ms-settings:network-wifi");
or
Process.Start("ms-availablenetworks:");
However, as far as I can tell, that relies on explorer running as the shell.
I've tried...
Process proc = new Process();
proc.StartInfo.FileName = #"c:\windows\explorer.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = "ms-availablenetworks:";
proc.Start();
All of the above work fine if I run in a normal environment, i.e. with explorer as the shell.
But for this user (with my custom shell application), I get an instance of explorer.exe running and displaying an error, Class not registered
I have also come across using LaunchUriAsync() but I don't think that would help me here, besides it's only available for Windows Store applications for what I've read, which this is not.
Well I managed to get this working
First start explorer on its own, then a second Process.Start() to run the settings page.
Unfortunately, when explorer.exe runs, it displays the taskbar which I don't want. (I had previously assumed I'd be able to hide it with a group policy setting or something but this doesn't appear to be the case).
But I suppose that's another question...
Background:
I created a service that will trigger the execution of an application when certain conditions have been met. This service is setup to run under the same windows user account that is used to log on to the system via RDP. I also created the .NET application that is trigger via this service. This application looks for a configuration file on disk (found in the ProgramData folder for the application) uses the settings found in the configuration file to affect the output of this application.
Problem:
When the application is ran by the user interactively the application runs great. However when the service triggers the application to run it appears that the application is not loading the correct values from the configuration files. It's almost as though the application when ran from a service has its own configuration file, and is not using the one found in ProgramData.
I'm just looking for some insight to why this may be happening. I have seem some odd behavior from Windows 7 and Windows 2008 R2 when running applications via scheduled tasks or as a service. It's almost like interactive applications and service applications have different environments on the same system running as the same user...
Note: The service executable is also found in the same folder as the triggered application. I would expect that the working directory by default would be the services running directory.
public int ExecRun()
{
Process proc = new Process();
proc.StartInfo = new ProcessStartInfo
{
FileName = "C:\\Program Files\\TEST\\runme.exe",
Arguments = "/DS:TEMP"
};
proc.Start();
proc.WaitForExit();
return proc.ExitCode;
}
Try adding the working directory info:
Process proc = new Process();
proc.StartInfo = new ProcessStartInfo
{
FileName = "C:\\Program Files\\TEST\\runme.exe",
WorkingDirectory="C:\\Program Files\\TEST",
Arguments = "/DS:TEMP"
};
It sounds like the service that triggers the execution of the application also needs to set the working directory. If you're using the Process class, you'll need to set the StartInfo.WorkingDirectory property the path where your application resides.
This has been solved.
Unfortunately, I think I wasted all your time with this question. The users is running this service on a second system (other than the one they claimed was having this issue). They copied the same configuration to both systems which would've been fine if they had setup both systems the same way, but alas they did not. The file did not exist on the system throwing the error, but both systems were setup to log exceptions to the same location.
The user had to disable the second service, or setup the configuration file correctly.
I have a c# application that needs to do some things as an admin (some installation stuff) and then it needs to run another process as a non-admin. I haven't done anything with UAC before, but I assume there must be a way to do this, right?
This also needs to be automated, so assume that the c# app is started with admin credentials.
Basically the program will need to do something like this:
// MUST run this process as admin
Process adminInstall = new Process();
adminInstall.StartInfo.FileName = "install.bat";
adminInstall.Start();
adminInstall.WaitForExit();
// CANNOT run this process as admin
Process nonAdminProcess = new Process();
nonAdminProcess.StartInfo.FileName = "runner.cmd";
nonAdminProcess.StartInfo.UseShellExecute = false;
nonAdminProcess.StartInfo.RedirectStandardOutput = true;
nonAdminProcess.OutputDataReceived += new DataReceivedEventHandler(myHandler);
nonAdminProcess.Start();
nonAdminProcess.BeginOutputReadLine();
nonAdminProcess.WaitForExit();
You can embed a manifest in the executable using MT.exe (manifest tool) in the platform SDK after the binary is compiled, but before it is signed. You also have the option of using a custom manifest within your project properties. Open the project properties, then go to the application tab, then change the manifest option from default manifest, to custom manifest. Visual Studio will add a manifest to your project where you can specify "requireAdministrator" privleges. When your app runs, it will provide a UAC prompt, or ask for credentials if logged on as user. There is a good chance sub process will start as admin as well. Otherwise you will need to launch them with the "runas" verb which is undocumented.
Process.Start parameters has one for Username. See Process.Start reference:
http://msdn.microsoft.com/en-us/library/sxf2saat.aspx
There does not appear to be a nice way of doing this using the .Net classes. However, Process.Start with different credentials with UAC on explains a way of doing it using CreateProcessAsUserW after stealing a handle from another process.
If the aforementioned methods aren't viable, then you can try my method. But its ugly; you need to get a handle to a non admin process, then use DuplicateTokenEx (p/invoke) to copy its (non admin) privileges, then pass that into CreateProcessAsUser. You first need to identify a non admin process though, there may not be any. The newly created process will be spawned with whatever privileges the token you copied contained, not the token of the parent process.
For some reason, my C# program needs to restart with elevated privileges. I use the following code to achieve it:
private static void RestartForPermissionsFix()
{
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.Verb = "runas";
processInfo.FileName = Assembly.GetExecutingAssembly().Location;
Process.Start(processInfo);
}
This works great.
After I "fix my privileges", I want to restart the program unelevated. I tried the same as above without the "runas", but it does not work. I assume the process being started from an elevated process automatically gets elevated. Any idea?
In order to launch a process at medium integrity from a high integrity process, I believe you would have to get the current process token using OpenProcessToken, duplicate it, remove the high integrity SID from the token using SetTokenInformation, and then use that token to create the new process using CreateProcessAsUser. This would be similar to this example, except rather than add the low integrity SID you'd have to remove the high integrity one. Note: I haven't tested this, so I'm not 100% sure it would work.
I suggest you leave the original unelevated process running, and have it wait for its elevated counterpart to finish (e.g. using Process.WaitForExit). Once that finishes, it can continue unelevated as before. This would be a lot easier and more foolproof.
I had the same problem with an application that I wanted to update automatically (The update program requires elevated privileges).
What I did was creating an external .exe that would start my updater program with elevated privileges, wait for it to exit, then restart my application with normal privileges.
I then embedded this .exe in my main application, and start this .exe just before leaving my application when I update it.
Is it possible to start a program so that it is available to a user with a windows service? I have been working with the Process.Start() in C#. I can get the service to kickoff some sort of process that appears in the Task Manager list under processes. However, the program nevers appears on the screen. By default, it runs under the user name "SYSTEM". I have adjusted the "Log On" option in the service manager to match the person logged into the computer, but this does not cause a window to appear either.
I feel like I am either missing a simple setting, or need to take a different direction for this. Below is the code I have been working with to start up Firefox as a test app.
private void startRunDap()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "Firefox";
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.UseShellExecute = true;
Process.Start(startInfo);
//Process.Start("Firefox");
}
On Vista and Win7 Services run in their own session with a private desktop. You'll get Firefox started but it will never be visible. The account name is actually how this came about, LocalSystem is a highly privileged account, a giant security hole.
You will need an "agent" in the user session to get the process started. An otherwise invisible program that you start with the Run key or the Startup folder that talks to the service through, say, a named pipe or socket. It can start the program.
Put a tick at "Allow service to interact with user" at properties of service in Services
Here's a link to a blog post that describes how to do this in Windows Vista and later. You should note, though, that the first sentences in the article are:
The first thing you should do about it is that; don't do it. There are many limitations and bad implications and restrictions involved.
In case, you are in a state that you cannot avoid launching an interactive process from Windows Service then you might want to read this article.
Windows SDK blog