C# Elevate Current Running Process as SYSTEM - c#

How can I elevate current running process as system, not administrator.
try
{
var ps = new ProcessStartInfo();
ps.FileName = Process.GetCurrentProcess().ProcessName.ToString() + ".exe";
ps.Verb = "runas";
this.Close();
var process = new Process();
process.StartInfo = ps;
process.Start();
}
catch (Exception re)
{
this.TopMost = true;
MessageBox.Show(re.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
Application.Exit();
}
above code restarts current running program to administrator privilege, like wise how can I get SYSTEM privilege?
c# 4.5
Any chance to create a new process as SYSTEM ? cause I see some apps(RunAsSystem) can make a file start as SYSTEM process.
Thanks.

PsExec from Microsoft SysInternals PsTools can start cmd as SYSTEM and from there you can do almost anything.
I am also searching for another way to do it.

There is no way starting a process as system. This can be achieved only for boot time/kernel level scenarios, drivers, services etc.
It would be a security risk if that could be done. Create windows service if it is cruicial to you to run your logic as system.

Related

How can i start the same process two times, but only with one uac?

Following problem:
I want to start the cmd as administrator in C# with a process to get the UAC befor the code:
var process = new Process();
var ps= new ProcessStartInfo();
ps.CreateNoWindow = true;
ps.FileName = #"cmd.exe";
ps.Verb = "runas";
process.Start();
After i confirm the UAC, i want to run code. After the code i want to start the same process but this time with arguments and without the UAC. Is that possible? Target is that i get a exe with the running code. I need the exe to run the arguments in the cmd. But the UAC should pop up before the exe will be appear. (the code should run after the uac, and the arguments after code). PS: I need the administrator priviliges to run the arguments.
You can elevate the program self first. If the process has got the right, run the wix installer. You can find IsUserAdministrator here.
public static void Main()
{
var isAdmin = IsUserAdministrator();
if(isAdmin)
{
Installation();
AfterInstallation();
}
else
{
var p = new Process();
var si = p.StartInfo;
si.CreateNoWindow = true;
si.UseShellExecute = true;
si.FileName = Process.GetCurrentProcess().MainModule.FileName;
si.Verb = "runas";
p.Start(); // UAC will show here only once
}
}
I have limited knowledge about this but I think you can:
Start your application (InstanceA) without admin.
From InstanceA, run the application with admin (InstanceB). You can run InstanceB with a /Install parameter and InstaceB knows that must start the installation.
Install the application from InstanceB.
InstanceA can wait until installations is finished and then, do whatever you want.
You may need some type of communication (pipes, memory mapping, sockets...) between both instances or something what you can monitor from InstanceA (registry key...) to check if the installations is completed and if you want more control about the whole process.

IIS hosted WCF service is not able to start a process

I have a WCF service on a server,when I send a request from client application, the service will run a process to communicate with network nodes,this process is critical in my service and if it doesn't run the entire service is useless. the problem is this process never runs :(
I have been reading solutions for about two days but none of them helped me , I have give the service administrator privileges and check if the .exe file path is correct here is my code any help would be appreciate.
try
{
myprocess.StartInfo.UseShellExecute = false;
myprocess.StartInfo.CreateNoWindow = true;
myprocess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
myprocess.StartInfo.RedirectStandardOutput = true;
myprocess.StartInfo.FileName = myprocessPathAndName;
myprocess.StartInfo.WorkingDirectory =
Path.GetDirectoryName(myprocessPathAndName);
myprocess.StartInfo.Arguments = ConfigName;
myprocess.Start();
Log("myprocess Runnig " , sw);
Log(myprocessPathAndName, sw);
Log(myprocess.StartInfo.WorkingDirectory, sw);
}
catch (Exception e)
{
Log("Failed to run myprocess : " + e.Message, sw);
}
here is the log
7/26/2017 4:05:15 AM : myprocessRunnig
7/26/2017 4:05:15 AM : C:\inetpub\wwwroot\Station\COM\Dn\myprocess.exe
7/26/2017 4:05:15 AM : C:\inetpub\wwwroot\Station\COM\Dn
First:
Check the return value of your myprocess.Start() method call. If the process has started successfully, it would return true. Log the return value.
Process.Start()
Second: (you may be already doing this)
After the process has started, you should have to have a wait call for the process to run and complete.
Process.WaitForExit()
Third:
How do you determine that the process has not started ? Are you able to check the process in Task Manager ? It is possible that the process is starting and failing. Is there any log created by your process ? Have you checked the event log ?
Fourth:
Does your process have any UI component ? Do note that when running as a Service (in Windows Vista and later), the service cannot show a UI. It would just hang.
Fifth:
Are you able to manually run your process with the same user ID as your Service ? You can use RunAs or PsExec to run your process under the appropriate user ID.
Sixth:
You can redirect the standard error as well and read from it to see whether your process has written any exception
e.g.,
process.StartInfo.RedirectStandardError = true;
string errResult = process.StandardError.ReadToEnd();
You can log the result and check it.
Seventh:
You should also log the exit code of your process
process.WaitForExit();
var exitCode = process.ExitCode;

Why would Process.WaitForExit throw a "no process" exception even when a process does exist?

I have a windows service containing this code:
public static void ExtractTextInner(string source, string destination)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = EXTRACTOR_EXE_FILEPATH
startInfo.Arguments = "\"" + source + "\" \"" + destination + "\"";
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
int exitCode = process.ExitCode;
process.Close();
if (exitCode != 0)
{
switch (exitCode)
{
case 1:
throw new ApplicationException("IFilter Extraction Failed");
default:
throw new ApplicationException("Unknown Exit Code:" + exitCode.ToString());
}
}
}
The purpose of this code is run an IFilter extract on a document, we use a seperate process because some IFilters are notoriously flaky.
Now this code runs perfectly fine on Windows 7 and Server 2008 R2 boxes but on a Windows Server 2003 the WaitForExit immediately throws a "There is no process associated with this Process object" exception. The process does exist and completes its task without a problem.
Anyone seen this? Can anyone shed any light on why WaitForExit would thow this error?
Additional Info
If I place this code in a Console App and run it works fine on the Windws Server 2003 box as well, hence it would appear to be a specific problem running this in a Service on a Windows Server 2003 box.
When starting processes, with the System.Diagnostics.Process class, the system can either use CreateProcess or ShellExecuteEx Win32 function. When using CreateProcess only executable files can be started. When using ShellExecuteEx, any file which can be started using the "Start->Run" command from the shell.
However these are completely different ways of starting processes. ShellExecuteEx involves the shell, and can, for example, re-use an existing instance of Word or Excel to open a document, by using the information stored under the HKCR\<progid>\shell\<verb> registry key. This may involve for example using DDE to search for and then activate an existing Excel instance.
See documentation on ShellExecuteEx's SHELLEXECUTEINFO:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb759784(v=vs.85).aspx
Note that ShellExecuteEx may or may not return an hProcess depending on whether a new process was started. This is the behavior which you are seeing.
CreateProcess is a lower-level function and creates a process directly, and simply passes the equivalent arguments. It always returns a process handle.
Note: Since you seem to be starting an executable file, it is a bit surprising that no hProcess is returned by ShellExecuteEx. Nevertheless, if you want to ensure you get a process handle, using UseShellExecute = false is the correct thing to do.

Why won't "cmd.exe /C command" end when called via Process.Start()?

I'm trying to run a command via command prompt from an ASP.Net web application. I can see the process start in task manager on the web server, however the process just sits there and never exits nor does it run the commands I specified.
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C " +command;
startInfo.UserName = "myuser";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.Domain = "mydomain";
startInfo.CreateNoWindow = true;
String pass = "mypass";
System.Security.SecureString secPass = new System.Security.SecureString();
foreach (char c in pass.ToCharArray())
{
secPass.AppendChar(c);
}
secPass.MakeReadOnly();
startInfo.Password = secPass;
process.StartInfo = startInfo;
process.Start();
//output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Close();
I've tried both with and without reading the standard output.
The application will hang on process.WaitForExit(); until I kill the process via task manager.
I think we need to understand what commands you are actually trying to process in order to determine what's going on. Also we need to know what OS the server is running.
For example, I did see in your comments where you tried "echo test > C:\test.txt" Under Windows Server 2008 (and Windows 7) the root directory requires administrator permissions in order to create files. If this is executing under IIS, my guess is that your IIS user isn't an administrator and you are getting security exceptions.
Also, a number of commands may require elevated priviledges due to UAC. I don't remember exactly, but I'm guessing that if those commands are being caught by UAC then the process is waiting for UAC confirmation... Which I believe you cannot supply via a command line.
This type of problem won't be seen if you log into the machine and execute it directly... unless you are logging in with the worker process user account.
So, the very first thing you need to do is figure out what it is you are trying to run and see if the user the worker process is executing under can even perform those actions. Security is there to protect you, so be careful about granting additional permissions to the user.
The reason why it might work on one machine versus another again depends on the OS's those machines are running and the configuration of the user the commands are executing under.
If this is truly a security issue, as I suspect, then you should post a question on serverfault.com to ask what permission sets you need to execute various commands under your worker process user.
You might look at the machines event logs to see if there were any warnings or errors thrown about the command. Sometimes things like this can show up there to give you a bit more information as to what happened.
Once passed to CMD, the control has passed to the shell. It's better to add a close it like this:
private void closeSubProcess()
{
Process[] currentProcesses = Process.GetProcesses();
foreach (Process p in currentProcesses)
{
string s = p.ProcessName;
s = s.ToLower();
if (s.CompareTo("YOURPROGRAMNAMEHERE") == 0)
{
p.CloseMainWindow();
p.Close();
}
}
}
I am calling cmd.exe to start a node module in Windows. npm obviously must be installed first, along with the node module I need, and then I can call the module with args in C#. Problem was, the cmd.exe would not shut off, I'd have to use Task Mgr (just like this question!).
//This requires npm, and the module installed by npm...
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = true; //closes command window
psi.Arguments = "/c <nodemodulename>" + file1 + ".txt " + file2 + ".log";
Process p = Process.Start(psi);
p.Close();
The /c argument was key to closing down cmd.exe. When I started out, I had put in the /K argument, which keeps the darned thing running. Solved. Hope this helps. (This is like ancient, but we always forget)

programmatically kill a process in vista/windows 7 in C#

I want to kill a process programmatically in vista/windows 7 (I'm not sure if there's significant problems in the implementation of the UAC between the two to make a difference).
Right now, my code looks like:
if(killProcess){
System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("MyProcessName");
// Before starting the new process make sure no other MyProcessName is running.
foreach (System.Diagnostics.Process p in process)
{
p.Kill();
}
myProcess = System.Diagnostics.Process.Start(psi);
}
I have to do this because I need to make sure that if the user crashes the program or exits abruptly, this secondary process is restarted when the application is restarted, or if the user wants to change the parameters for this secondary process.
The code works fine in XP, but fails in Windows 7 (and I assume in Vista) with an 'access is denied' message. From what the Almighty Google has told me, I need to run my killing program as administrator to get around this problem, but that's just weak sauce. The other potential answer is to use LinkDemand, but I don't understand the msdn page for LinkDemand as it pertains to processes.
I could move the code into a thread, but that has a whole host of other difficulties inherent to it that I really don't want to discover.
You are correct in that it's because you don't have administrative priveleges. You can solve this by installing a service under the local system user and running a custom command against it as needed.
In your windows form app:
private enum SimpleServiceCustomCommands { KillProcess = 128 };
ServiceControllerPermission scp = new ServiceControllerPermission(ServiceControllerPermissionAccess.Control, Environment.MachineName, "SERVICE_NAME");
scp.Assert();
System.ServiceProcess.ServiceController serviceCon = new System.ServiceProcess.ServiceController("SERVICE_NAME", Environment.MachineName);
serviceCon.ExecuteCommand((int)SimpleServiceCustomCommands.KillProcess);
myProcess = System.Diagnostics.Process.Start(psi);
In your service:
private enum SimpleServiceCustomCommands { KillProcess = 128 };
protected override void OnCustomCommand(int command)
{
switch (command)
{
case (int)SimpleServiceCustomCommands.KillProcess:
if(killProcess)
{
System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("MyProcessName");
// Before starting the new process make sure no other MyProcessName is running.
foreach (System.Diagnostics.Process p in process)
{
p.Kill();
}
}
break;
default:
break;
}
}
I'll add the code for Simon Buchan's suggestion. It makes sense and should work as well, assuming your windows form is what launched the process in the first place.
Here's where you create the process. Notice the variable myProc. That's your handle on it:
System.Diagnostics.Process myProc = new System.Diagnostics.Process();
myProc.EnableRaisingEvents=false;
myProc.StartInfo.FileName="PATH_TO_EXE";
myProc.Start();
Later, just kill it with:
myProc.Kill();

Categories

Resources