I'm trying to kill some processes by their names (specific names that I already know) In C#. I find them and kill them with Process.Kill(), but sometimes on some processes i get 'access denied'. I assume it is because I'm not running them as an admin.
I created a batch that does the same, and if I run it as an admin it kills them all, otherwise not.
I can run the batch as an admin via the c# code, i.e:
var psi = new ProcessStartInfo();
psi.Verb = "runas"; //This suppose to run the command as administrator
//Then run a process with this psi
My question is, is this really a way to solve the access problem? Is there a better way? If I run my C# code as an admin, does Process.Kill() suppose to have the same result as doing it with the batch file?
What you are talking about are Elevated rights.
You need the programm that finds the programms and sends out the kills to always run Elevated. The most reliable way to do that, is to add this requirement to the Programm Manifest. It is something the UAC will read to help you.
The second most reliable way is to check if you got the rights. And if not, have the programm try to (re)start itself elevated. I did write some sample code for this a while back:
using System;
using System.Diagnostics;
using System.IO;
namespace RunAsAdmin
{
class Program
{
static void Main(string[] args)
{
/*Note: Running a batch file (.bat) or similar script file as admin
Requires starting the interpreter as admin and handing it the file as Parameter
See documentation of Interpreting Programm for details */
//Just getting the Absolute Path for Notepad
string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
string FullPath = Path.Combine(windir, #"system32\notepad.exe");
//The real work part
//This is the programm to run
ProcessStartInfo startInfo = new ProcessStartInfo(FullPath);
//This tells it should run Elevated
startInfo.Verb = "runas";
//And that gives the order
//From here on it should be 100% identical to the Run Dialog (Windows+R), except for the part with the Elevation
System.Diagnostics.Process.Start(startInfo);
}
}
}
Note that regardless how you try to elevate, Eleveation can fail in very rare OS settings.
Related
I'm having problems with a program and its buttons (I know, I'm awesome lol) the buttons can be "programmed" to run programs. They also can be set to run as admin (different credentials).
If I set up simply notepad or cmd or explorer it runs like charm. But if I start iexplore it has got no admin rights.
I had problems before with running explorer.exe the solution was that I had to run it by typing the full path C:\windows\explorer.exe to be able to run it but that I solved it by setting up the VB2015 compiler (?) to Platform target: x64.
My other problem is that if I try to run dsa.msc or generally anything ends with msc it throws the following exception, even if I set up the full path to the syswow64 (or the system32) folder like c:\windows\syswow64\dsa.msc
"The specified executable is not a valid application for this OS platform."
Running the C:\Windows\System32\mmc.exe "services.msc" (or syswow64, with or without the /computer= switch) throws
"The requested operation requires elevation." which I have since I'm able to run services.msc (and all other msc-s from command line with the same user rights)
Thank you.
A beginner.
Basically you don't need to run the host app as administrator! There is a variable (inside your Process instance) called StartInfo (which is an instance of the ProcessStartInfo Class), where Verbs could be used as followed:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("E:\\Users\\Temp\\app.exe")
{
Verb = "runas"
}
};
p.Start();
This will prompt the user to run the app.exe as administrator.
Edit
Running a Process as a defined user:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("E:\\Users\\Temp\\app.exe")
{
Verb = "runas",
Arguments = "/user:Vira"
}
};
For more information about those RUNAS Arguments, click me! :)
This is a silly and tricky issue that I am facing.
The below code works well (it launches Calculator):
ProcessStartInfo psStartInfo = new ProcessStartInfo();
psStartInfo.FileName = #"c:\windows\system32\calc.exe";
Process ps = Process.Start(psStartInfo);
However the below one for SoundRecorder does not work. It gives me "The system cannot find the file specified" error.
ProcessStartInfo psStartInfo = new ProcessStartInfo();
psStartInfo.FileName = #"c:\windows\system32\soundrecorder.exe";
Process ps = Process.Start(psStartInfo);
I am able to launch Sound Recorder by using Start -> Run -> "c:\windows\system32\soundrecorder.exe" command.
Any idea whats going wrong?
I am using C# in Visual Studio 2015 and using Windows 7 OS.
UPDATE 1: I tried a File.Exists check and it shows me MessageBox from the below code:
if (File.Exists(#"c:\windows\system32\soundrecorder.exe"))
{
ProcessStartInfo psStartInfo = new ProcessStartInfo();
psStartInfo.FileName = #"c:\windows\system32\soundrecorder.exe";
Process ps = Process.Start(psStartInfo);
}
else
{
MessageBox.Show("File not found");
}
Most likely your app is 32-bit, and in 64-bit Windows references to C:\Windows\System32 get transparently redirected to C:\Windows\SysWOW64 for 32-bit apps. calc.exe happens to exist in both places, while soundrecorder.exe exists in the true System32 only.
When you launch from Start / Run the parent process is the 64-bit explorer.exe so no redirection is done, and the 64-bit C:\Windows\System32\soundrecorder.exe is found and started.
From File System Redirector:
In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64.
[ EDIT ] From the same page:
32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32.
So the following would work to start soundrecorder.exe from the (real) C:\Windows\System32.
psStartInfo.FileName = #"C:\Windows\Sysnative\soundrecorder.exe";
Old thread but providing one more possible case
In my case i was using arguments inside Process.Start
System.Diagnostics.Process.Start("C:\\MyAppFolder\\MyApp.exe -silent");
I changed it to
ProcessStartInfo info = new ProcessStartInfo("C:\\MyAppFolder\\MyApp.exe");
info.Arguments = "-silent";
Process.Start(info)
Then it worked.
One more case, similar to Ranadheer Reddy's answer, but different enough to trip me up for awhile.
I was making a simple mistake. I had this:
ProcessStartInfo info = new ProcessStartInfo("C:\\MyAppFolder\\MyApp.exe ");
info.Arguments = "-silent";
Process.Start(info);
See that space after the end of the path to the app? Yeah. It doesn't like that. It will not find your file if you include that.
The solution was to remove the extraneous space. Then it worked.
This is an easy enough mistake to make if you're converting an app from starting processes by launching "cmd.exe /c MyApp.exe -silent" to running "MyApp.exe" directly instead, which is what I was doing. I hope recording my misfortune here will help future developers.
I'm running msiexec.exe with the following code.
Process setupProc = new Process();
setupProc.StartInfo.UseShellExecute = true;
setupProc.StartInfo.CreateNoWindow = true;
setupProc.StartInfo.FileName = "msiexec.exe";
setupProc.StartInfo.Arguments = String.Format("/i \"{0}\" /qn {1}",
sSetupFilePath, installerProperties);
setupProc.StartInfo.Verb = "runas";
setupProc.Start();
I want to change Program Name in the UAC, Is this possible at all to change program name.
Program name coming as "C:\Windows\SysWOW64\msiexec.exe with the arguments I provide to run.
I just want to get rid of the arguments coming the rhe msiexec.exe.
I did lot of rnd but could not get possible solution and I think it is not possible.
You should explain what your actual goal is. For example, if you wish to launch an MSI install from a standalone process, then give that process an elevation manifest so it will request elevation (your program name) and run elevated, and then use the CreateProcess version of your code, UseShellExecute=false.
Or if your code is already running elevated just set UseShellExecute=false.
In both cases msiexec will run elevated and not show elevation requests because you are firing it off in CreateProcess mode.
BTW, if you're running this from a custom action of an MSI install there's a good chance it will fail - this is really not recommended at all.
I need to run "manage-bde" shell command from C# code.
The main application process is already running as administrator and is Elevated.
I used code from : UAC self-elevation example on MS website for confirming the app process is elevated.
(http://code.msdn.microsoft.com/windowsdesktop/CSUACSelfElevation-644673d3)
However, when I try to run manage-bde from the C# code, I get "System can't find file specified".
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\\manage-bde.exe";
p.StartInfo.UseShellExecute = true;
p.Start();
As a workaround, I tried to create a batch file that runs the command.
string batchFileName = DateTime.Now.Ticks + ".bat";
StreamWriter writer = new StreamWriter(batchFileName);
writer.WriteLine("manage-bde");
writer.Flush();
writer.Close();
Process p = new Process();
p.StartInfo.FileName = batchFileName;
p.StartInfo.UseShellExecute = true;
p.Start();
The batch file is written , and executed successfully; However, the command "manage-bde" is not recognized.
I changed the code to use the verb "runas" and use admin password and that works, but I want the batch file to work without the need for providing the admin password. The current logged in user is already administrator on the computer but the batch file is not getting executed with the existing admin privileges . I need the batch file to execute and manage-bde to run successfully.
Your help or advice will be very highly appreciated :)
ps: some commands other than manage-bde work fine without need for admin runas.
The reason of the behavior I encountered was the Windows File System Redirector.
In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64
https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx
My application build was 32 bits. Whenever it tried to access System32 windows automatically redirected it to SysWow64 which does not contain "manage-bde.exe". I changed the build to 64 bits and then the application could access manage-bde.exe from System32
Even if you're running as the Administrator user, you're not fully elevated if UAC is running. Meaning that you'll have either the UAC prompt come up or you'll be prompted for a password.
The only real way you could get around that is to run your application elevated first, or to write a service that runs with elevated permissions to start your new process.
The alternative of course is to disable UAC, but that is undesirable in most situations.
I have a program that needs to run as a normal user most of the time, but once in a while I need to stop and start a service. How do I go about making a program that runs as a normal user most of the time but elevates into administrator mode for some function?
You can't elevate a process once its running but you could either :-
Restart the process as elevated
private void elevateCurrentProcess()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Application.ExecutablePath;
startInfo.Verb = "runas";
try
{
Process p = Process.Start(startInfo);
}
catch
{
// User didn't allow UAC
return;
}
Application.Exit();
}
This method means that your process continues to run elevated and no more UAC promopts - both a good and a bad thing, depends upon your audience.
Put the code that requires elevation into a seperate exe
Set the manifest as requireAdministrator and start it as a separate process. See this sample code
This method means a UAC prompt every time you run the operation.
Best method depends upon your audience (admin types or not) and frequency of the elevated operation.
As far as I know, you need to start a seperate process that runs as the administrator. You can't elevate a process once it's already been started.
See this question.
You need to use what is referred to as Impersonation..
[http://support.microsoft.com/kb/306158][1]
The above shows how it would be accomplished for an ASP.Net app, but the code is probably near identical for your needs.