I trying to make a program which connect to a game ("quick connect").
When i start the application as an administrator and connect to the game, it have weird issues (e.g. shortkeys doesn't respond for the ingame keys and the game doesn't load some model files), but when i start without admin rights it works fine, however i need the admin rights for other purposes (file operations).
I tried to rerun the program with the runas commandline command, the app had no admin rights, but the game still doesn't work right.
// OnClick event
ProcessStartInfo proc = new ProcessStartInfo("cmd.exe", "/c runas /trustlevel:0x20000 \"myapp.exe rerun\"");
proc.WorkingDirectory = Application.StartupPath;
proc.CreateNoWindow = true;
proc.UseShellExecute = false;
Process.Start(proc);
// Program.cs
if(!admin && args[0].Equals("rerun"))
{
ProcessStartInfo proc = new ProcessStartInfo("cmd.exe", "/c game.exe ipAndPortToConnect");
proc.WorkingDirectory = Application.StartupPath;
proc.CreateNoWindow = true;
proc.UseShellExecute = false;
Process.Start(proc);
}
I tried many combinations but none of them worked.
I can't figure out what the hell causing it...
If you check the Task Manager, you'll see the game still runs as a different user, namely Administrator. This most likely means the game saves some information in the user profile, for example under AppSettings (like hotkeys in configuration files), or game modifications that are stored in AppData, which could cause the issues you mentioned.
The user who 'reruns' your program is still the elevated user, albeit with less permissions, and that user launches the game. You cannot "unimpersonate" a process properly to the point the OS thinks it runs as the logged in user, so you'll have to do something else.
You can either see if you can move the user-specific resources to a path relative to the game, not the user, or start the process by any other means but directly from yours, for example using a Scheduled Task.
But why didn't you update your existing question?
Related
I have an ASP.NET application that is already deployed in an Azure virtual machine. The situation is as follows:
This application, OCREngine, is deployed on the server along with other 3rd party applications. OCREngine is executed on the server by using a service reference to the web service. It runs fine most of the time. But there is one exception: one of the branches of execution won't run the program it needs to run. Both of the branches have to run a program (both are being run in the same way), but one works and the other one doesn't.
This one works: CleanJPEG.exe
proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "CleanJPEG.exe";
proc.StartInfo.Arguments = "\"" + tempPages + "Color Info.JPEG\"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
And this one doesn't: cpctool.exe
proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "cpctool.exe";
proc.StartInfo.Arguments = "\"" + file + "\" -o \"" + tempPages + "page.tiff\"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
They are both in the same folder, which has full permissions for the AppPool and so does %TEMP%.
If I run the application from the server, everything works fine. But when I run it through the web service, an instance of cpctool.exe gets created (can be seen on Background processes in the task manager) but it doesn't do it's job. And thus the execution of OCREngine never finishes.
This last part is what made me think it was a problem with permissions, but I don't know what else to give permissions to.
I run Folder Changes View on cpctool.exe and it showed access to the folder where the files are stored and one file being saved in %TEMP% (which, funny enough, doesn't appear when running Folder Changes View on the server).
Can anyone think of any special folder that needs permission that I might be forgetting?
You are completely correct to concentrrate on the permissions as that is usually the issue.
If an EXE process starts and does nothing, then it's probably only made for interactive use, and is prompting for something.
Looking at this page it says:
The FIRST TIME the CPCTool.exe runs the user is prompted to read/accept a User Agreement from Cartesian – this agreement MUST be accepted or the converter will not work.
I reckon that's what it's doing. Try logging in as the application pool user, start the program and accept the agreement.
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 an application that under rare circumstances needs to change its registry setting. Also during it's first execution it needs to create a new key. I'm developing this in Windows 7. I get ThrowUnauthorizedAccessException. How do I force Windows to give me a UAC prompt to temporarily elevate my permissions?
Thanks in advance.
Should all users be allowed to modify this setting? If so, the simplest solution is to modify your installation program to give Users Full Control of the registry key.
If only administrators should be able to modify this setting, then you will need to launch another copy of your program, asking Windows to elevate it:
ProcessStartInfo startInfo = new ProcessStartInfo("C:\Path\To\MyApplication.exe");
startInfo.Verb = "runas"; //trigger a UAC prompt (if UAC is enabled)
System.Diagnostics.Process.Start(startInfo);
If you were smart you would include some command line arguments, so you can tell "yourself" that it should jump straight to the part of the software that the user needs to deal with. Or your command line arguments could just say what you want done:
ProcessStartInfo startInfo = new ProcessStartInfo(
"C:\Path\To\MyApplication.exe",
"/setLoggingEnabled yes");
startInfo.Verb = "runas"; //trigger a UAC prompt (if UAC is enabled)
System.Diagnostics.Process.Start(startInfo);
Have your application check for the setLoggingEnabled switch, make the change, and then exit.
Update: A common situation is players of World of Warcraft. Since the game is allowed to update itself while running, all users must be allowed to modify the game data sitting in Program Files. The correct and valid action is to modify the ACLs on the
C:\Program Files\Blizzard\World of Warcraft
folder so that all users have full control. In fact, before Blizzard got their act together, Microsoft released an application compatibility update that gives all users full control to the WoW folder next time it run as an administrator.
Another common case is when the Blizzard Launcher is launched with administrative privelages, it updates a registry key in HKLM, recording where the game is. This happens when, for example, i move WoW from a hard drive to an SSD drive
run the launcher once as an administator so that the updaters work correctly.
I have a winforms app that installs other apps in a loop. This works properly on an administrator account in Windows 7, but I have serious issues in a standard account - the app requires elevation in order to write to "Program Files(x86)" folder.
Therefore I am trying to ask for elevation for a specific method (the one that runs the installers) in a winforms c# app, using this code:
[System.Security.Permissions.PrincipalPermission(System.Security.Permissions.SecurityAction.Demand, Role = #"BUILTIN\Administrators")]
After receiving an error, I learned from the web that before calling the method which carries the above attribute, I need to write this:
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
I did this, and the method still throws the following error:
Request for principal permission failed.
Step by step debugging passes the SetPrincipalPolicy line but, when it reaches the method with the Demand atribute, it just throws the same error, as if the SetPrincipalPolicy never existed.
Am I doing something wrong in setting the Demand attribute properly?
Thank you in advance.
LATER EDIT: as requested here is the code that is supposed to trigger the elevation request when installing the app silently (but does not work):
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool hasAdministrativeRight = principal.IsInRole(WindowsBuiltInRole.Administrator);
if (!hasAdministrativeRight)
{
ProcessStartInfo psi = new ProcessStartInfo(file);
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = true;
psi.Verb = "runas";
//psi.CreateNoWindow = true;
psi.Arguments = modifiers;
try
{
using (Process process = Process.Start(psi))
{
process.WaitForExit();
if (process.HasExited)
return process.ExitCode;
}
}
catch (Win32Exception wex)
{
}
}
What I need, is for that process to pop a dialog asking for username and password for admin, if the app was ran under a Windows Standard User. Only the process started programmatically above should run as admin, the main app itself can remain as a standard user.
This is just not the way UAC works. It is process based, the user only ever gets the "please let me mess with your machine" prompt when you start a new process. With the proper incantation of "I need the user's consent to mess with the machine, please say Yes" signal embedded in the program. Which you do by this answer.
Death to the idea of making it method based. Unreasonable to a programmer, makes sense to a user. User wins.
You can either force your app to always run as an admin. This is how you do that. It is not recommended however for your app to need admin privileges to run.
If you start a Process to run the installer, you can check here how to run the process as an admin.
A third option which Visual Studio uses is that when you do something where you need admin privileges you are prompted to restart the app and it then restarts the app as an admin and you can perform the tasks. Just use the code from the second way to start your app.
The method you've posted to run as admin will check if the user is admin and then start the process as an admin. If the user doesn't have admin rights the app won't even start. A better solution is to always try to run the process as an admin. Then the user will get an UAC prompt with password and username, which an admin can fill in.
public static int RunAsAdmin(string fileName)
{
ProcessStartInfo psi = new ProcessStartInfo(fileName);
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = true;
psi.Verb = "runas";
psi.Arguments = modifiers;
try
{
using (Process process = Process.Start(psi))
{
process.WaitForExit();
if (process.HasExited)
return process.ExitCode;
}
}
catch (Win32Exception wex)
{
}
return 0;
}
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.