Deny Access to Kiosk program process - c#

I have a kiosk app and have to disable task manager always to prevent closing the program by users .
But some users need the TaskManager to close hanging programs.
Any help would be appropriated.
However, I am sure there is a function in windows to prevent closing a program's process , as when one attempt to kill rundll.exe process. I want to know that function if I can call it with DllImport
Can anyone help with a trick?
A hack?
A function?
Any other solution?
EDIT:
At least if there is not a way to prevent the process from being closed, I need a way to hide it from processes list appeared in the task manager.
EDIT 2:
I can't find the solution so far

One approach, if you could access the process ID in an administrative context, is to deny the PROCESS_TERMINATE permission on the process to end users. Terminating the process (through task manager or other contexts) is by default granted to the owner, but can be explicitly denied. When it is denied, terminating the process would require the owner to manually change the ACL, and then terminate the process. If the user is neither an administrator nor the owner of the process, he will not be able to forcibly terminate the process (e.g., through Task Manager), although the process will be allowed to exit normally.
The following code puts an explicit deny ACE on the process with the PID processid for members of the Everyone group.
#include "Aclapi.h"
#include "Sddl.h"
DWORD RestrictTerminateOnProcessId(DWORD processid)
{
PACL dacl = NULL, newdacl = NULL;
HANDLE ph = NULL;
PSECURITY_DESCRIPTOR* desc = NULL;
PSID everyonesid = NULL;
ph = OpenProcess(WRITE_DAC | READ_CONTROL, false, processid);
if (!ph) goto cleanup;
if (ERROR_SUCCESS != GetSecurityInfo(ph,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&dacl,
NULL,
desc)) goto cleanup;
SID_IDENTIFIER_AUTHORITY WorldAuth = SECURITY_WORLD_SID_AUTHORITY;
if (!AllocateAndInitializeSid(
&WorldAuth,1,SECURITY_WORLD_RID,
0,0,0,0,0,0,0,&everyonesid)) goto cleanup;
// begin copy dacl
_ACL_SIZE_INFORMATION si;
GetAclInformation(dacl,
&si,
sizeof(si),
AclSizeInformation);
DWORD dwNewAclSize = si.AclBytesInUse +
(2*sizeof(ACCESS_DENIED_ACE)) + (2*GetLengthSid(everyonesid)) -
(2*sizeof(DWORD));
newdacl = (PACL)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwNewAclSize);
if (newdacl == NULL) goto cleanup;
if (!InitializeAcl(newdacl, dwNewAclSize, ACL_REVISION_DS))
goto cleanup;
if (!AddAccessDeniedAce(newdacl,
ACL_REVISION_DS,
PROCESS_TERMINATE,
everyonesid)) goto cleanup;
for (int i = 0; i < si.AceCount; i++)
{
LPVOID pace = NULL;
if (!GetAce(dacl, i, &pace)) goto cleanup;
if (!AddAce(newdacl, ACL_REVISION_DS,
MAXDWORD, pace, ((PACE_HEADER)pace)->AceSize))
goto cleanup;
}
// end copy dacl
if (!SetSecurityInfo(ph,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
newdacl,
NULL)) goto cleanup;
SetLastError(0);
cleanup:
DWORD ret = GetLastError();
if (desc) LocalFree(desc);
if (newdacl) HeapFree(GetProcessHeap(), 0, (LPVOID)newdacl);
if (ph) CloseHandle(ph);
if (everyonesid) FreeSid(everyonesid);
return !ret;
}

You could create a service that runs on boot. It then monitors when the user logs in and starts your program. From there you have two choices:
Have it wait on the program and revive it for as long as the user's session persists.
Run it under an administrator account and make sure the users are always running on limited accounts. Windows' privilege enforcement should take care of your program not dying.
If you must allow the users administrative privileges (and they can thus kill your service), make sure to register your service so that the SCM restarts it automatically.
Anything beyond that would require some kernel hacking, as mdm said, or diving into rootkit territory. Which I would suggest you avoid.
If by any chance you're still running Windows XP, instead of a system service, you can register a Winlogon notification package. They're basically unkillable, as they run in the context of winlogon.exe, which is the reason they were removed from Vista and above.

The proper way of doing this is:
Create a user for the Kiosk application. Lets say KioskUser
Create other users that do stuff in the computer. Lets say User1
NONE of them should be administrator. They do not need to be admins right? They can have privileges of course.
You are going to use User1 account as usual.
Then, you run the Kiosk application as the KioskUser. (use runas command)
- add the application to the session and make it visible (see the arguments for more info on this)
While the User1 is loged in and the Kiosk application runs from the KioskUser, the User1 cannot kill the process.
I wouldn't recommend "hacking" the system, nor changing something on the registry.
Also, you can make the Kiosk application a service, and run it under the Kiosk user.

It sounds like you can't prevent a process from being killed - see this question and specifically the link posted to an explanation.
You can however prevent the user from opening the task manager from the taskbar (right click -> open task manager), from pressing Ctrl-Shift-Esc, or from typing taskman at the command prompt using the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableTaskMgr
Setting it to 1 disables the task manager, 0 enables it again.
From the command prompt, disable it like so:
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 1 /f
And you can renable with this command:
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 0 /f
You'll also need to find a way of preventing the user from writing to this key in the registry - although on my Windows 7 64-bit machine I had to open an admin command prompt before I could change the key.
Edit
As suggested in the comments, you could intercept a low level system call to alter the list of processes reported. This answer eludes to it, you will basically have to write a kernel-mode rootkit - probably implemented as a device driver. This will likely only work in Windows XP and below due to kernel changes made in Vista and onwards. It can be done however, a friend of mine created a prototype of this for his BSc final year dissertation.
You'll also have to consider other methods of querying for processes - IIRC NtQuerySystemInformation isn't the only way that processes can be enumerated.

Short of protecting your Kiosk app with some rootkit/driver you can't... although the methods you would need to use in this context are "malware-like" so beware...
Here http://blogs.msdn.com/b/oldnewthing/archive/2004/02/16/73780.aspx you can see on one side why this is a task not really possible and on the other side the several possibilities you would have to defend against... which would be:
deny PROCESS_TERMINATE
deny PROCESS_CREATE_THREAD
deny PROCESS_VM_WRITE
deny PROCESS_SUSPEND_RESUME
Plus any defense you can get your hands on against debuggers - another very tricky business.

Sorry for not posting this as a comment (not enough reputation).
I'm using drfs solution, but it seems to induce a memory leak with the way GetSecurityInfo is used. I changed the code and got rid of the memory leak like this:
Declaration:
PSECURITY_DESCRIPTOR desc = NULL;
Initialisation:
desc = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED, sizeof(PSECURITY_DESCRIPTOR));
Cleanup:
if (desc) GlobalFree(desc);
Call:
GetSecurityInfo(ph, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &desc)
I also found this article on the issue: http://i1.blogs.msdn.com/b/oldnewthing/archive/2012/12/12/10376639.aspx

While you can't prevent an authorized user from killing your process, you can prevent users from having the necessary permissions to kill your process. That said, a local administrator will always have permission to kill any process. Is your hope to prevent closing of your application by any user or just non-admins? If the former, simply running the process under a dedicated user account may be enough to do the trick.

Related

PssCreateSnapshot - access denied odd situation

I've created some code for performing clones of processes using PssCaptureSnapshot and then perform a mini dump of the clone.
However, on some processes I'm getting access denied when running PssCaptureSnapshot (running as elevated). That's not a problem at all, in fact the processes that I cannot perform a clone of, can also not be cloned using ProcDump (tool from SysInternals).
However, what is odd is that if I open a PowerShell PSSession to the localhost and run my application from there... it has no problems creating the clone!
Now what immediately popped to my head was... privileges. So I checked the privileges inside the PSSession against those outside and... Bingo! PSSession has literally all privileges known to man whereas outside the PSSession I have just a handful of privileges.
No biggie, I thought... I'll just start assigning myself privileges, one at a time, calling PssCaptureSnapshot in between. When I stop getting access denied, I know which privilege I need!
The plan was foolproof. That is... until I ran out of privileges to assign and I was still getting access denied...
So now I'm really clutching at straws: why does it work inside a PSSession but not outside, when all of the privileges are (theoretically) the same? How do I troubleshoot this further?
Any help would be appreciated.
PS: I will gladly post code if you think it will help. But bearing in mind I get an access denied, the fact that it works inside a PSSession but not outside and the fact that ProcDump can also not create clones for these processes... I don't think the code is relevant.
EDIT
Results from whoami /all
local session:
USER INFORMATION
----------------
User Name SID
================== ===========================================
xxxxxxxxxxxxxxxxxx S-1-5-21-1509752874-53682476-648048294-1107
GROUP INFORMATION
-----------------
(listing only groups that appear in this session, but don't appear in the other)
NT AUTHORITY\REMOTE INTERACTIVE LOGON Well-known group S-1-5-14 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
=============================== ========================================= ========
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeSecurityPrivilege Manage auditing and security log Disabled
SeTakeOwnershipPrivilege Take ownership of files or other objects Disabled
SeLoadDriverPrivilege Load and unload device drivers Disabled
SeSystemProfilePrivilege Profile system performance Disabled
SeSystemtimePrivilege Change the system time Disabled
SeProfileSingleProcessPrivilege Profile single process Disabled
SeIncreaseBasePriorityPrivilege Increase scheduling priority Disabled
SeCreatePagefilePrivilege Create a pagefile Disabled
SeBackupPrivilege Back up files and directories Disabled
SeRestorePrivilege Restore files and directories Disabled
SeShutdownPrivilege Shut down the system Disabled
SeDebugPrivilege Debug programs Enabled
SeSystemEnvironmentPrivilege Modify firmware environment values Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeRemoteShutdownPrivilege Force shutdown from a remote system Disabled
SeUndockPrivilege Remove computer from docking station Disabled
SeManageVolumePrivilege Perform volume maintenance tasks Disabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
SeCreateSymbolicLinkPrivilege Create symbolic links Disabled
USER CLAIMS INFORMATION
-----------------------
User claims unknown.
Kerberos support for Dynamic Access Control on this device has been disabled.
inside PSSession:
USER INFORMATION
----------------
User Name SID
================== ===========================================
xxxxxxxxxxxxxxxxxx S-1-5-21-1509752874-53682476-648048294-1107
GROUP INFORMATION
-----------------
(listing only groups that appear in this session, but don't appear in the other)
NT AUTHORITY\NETWORK Well-known group S-1-5-2
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
=============================== ========================================= =======
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Enabled
SeSecurityPrivilege Manage auditing and security log Enabled
SeTakeOwnershipPrivilege Take ownership of files or other objects Enabled
SeLoadDriverPrivilege Load and unload device drivers Enabled
SeSystemProfilePrivilege Profile system performance Enabled
SeSystemtimePrivilege Change the system time Enabled
SeProfileSingleProcessPrivilege Profile single process Enabled
SeIncreaseBasePriorityPrivilege Increase scheduling priority Enabled
SeCreatePagefilePrivilege Create a pagefile Enabled
SeBackupPrivilege Back up files and directories Enabled
SeRestorePrivilege Restore files and directories Enabled
SeShutdownPrivilege Shut down the system Enabled
SeDebugPrivilege Debug programs Enabled
SeSystemEnvironmentPrivilege Modify firmware environment values Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeRemoteShutdownPrivilege Force shutdown from a remote system Enabled
SeUndockPrivilege Remove computer from docking station Enabled
SeManageVolumePrivilege Perform volume maintenance tasks Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
SeTimeZonePrivilege Change the time zone Enabled
SeCreateSymbolicLinkPrivilege Create symbolic links Enabled
USER CLAIMS INFORMATION
-----------------------
User claims unknown.
Kerberos support for Dynamic Access Control on this device has been disabled.
after relative long research with cogumel0 we found exactly root of the problem.
first of all we found that PssCaptureSnapshot can failed when and only when it called with PSS_CAPTURE_VA_CLONE flag - so for capture a snapshot of all cloneable pages in the process.
despite we have process handle with all required access to process (say PROCESS_ALL_ACCESS) - for some processes PssCaptureSnapshot return error. why ?
i note that error was only if process is running in the some job. (for determinate this we can use IsProcessInJob) and PssCaptureSnapshot can return in this case 2 different errors:
ERROR_NOT_ENOUGH_QUOTA - i view this in win8.1 and win10 - it
returned say for some chrome.exe processes (not all)
ERROR_ACCESS_DENIED - this error happens only when process which we
want snap - run in another session (compare our process) and this
is only in win8.1 - no this error in win10, even if process in
job and in another session.
for understand why this happens - need look how PssCaptureSnapshot internal implement PSS_CAPTURE_VA_CLONE semantic. it do it by fork target process (yes, fork under windows). for this task used undocumented ZwCreateProcessEx api. when SectionHandle == 0 (win32 CreateProcess always pass here section created on exe file (if say full true now CreateProcess use another api, this was early)) ZwCreateProcessEx clone (fork) process (ParentProcess) instead create new one based on SectionHandle (which based on some exe file)
but if ParentProcess in job - the child (our forked) process also will be placed in this job. and here can be problems.
at first job can have limit for process count in job. if say job have this limit - no more than 1 process in job - ZwCreateProcessEx and fail with error STATUS_QUOTA_EXCEEDED - and as result PssCaptureSnapshot return to us ERROR_NOT_ENOUGH_QUOTA. this is chrome.exe case - for security reasons some chrome processes run in job (with limit in 1 process) (this processes also have Untrusted Mandatory Level but this not related to issue)
but even if job have no limit for active process count (or we not exceed this limit) in win8.1 - in job belong to another session - call fail with STATUS_ACCESS_DENIED. why this ? this already internal implementation details and now (in windows 10) it changed - no more this error - we can fork process even if it in job and another session. some hint why this we can got in AssignProcessToJobObject page:
All processes within a job must run within the same session as the
job.
so here some windows restriction related to job object and cross session.
how reproduce/test this error on windows 8.1 if interesting ? for my look most easy way - take some windows service running in session 0 - this service must be not critical for system (easy can start/stop it) and have own exe. for my look "msdtc.exe" perfect victim here. so open it, try snapshot first, than place in in job and after this - again try snapshot. and view different:
NTSTATUS status;
BOOLEAN b;
if (0 <= (status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &b)))
{
// GetProcessIdByName custom function not shown here
if (ULONG dwProcessId = GetProcessIdByName(L"msdtc.exe"))
{
DbgPrint("found dwProcessId=%x\n", dwProcessId);
if (HANDLE hProcess = OpenProcess(PROCESS_CREATE_PROCESS|PROCESS_QUERY_LIMITED_INFORMATION |
PROCESS_SET_QUOTA|PROCESS_TERMINATE , FALSE, dwProcessId))
{
BOOL bInJob;
if (IsProcessInJob(hProcess, 0, &bInJob))
{
if (!bInJob)
{
HPSS SnapshotHandle;
ULONG err;
if (!(err = PssCaptureSnapshot(hProcess, PSS_CAPTURE_VA_CLONE, 0,&SnapshotHandle)))
{
PssFreeSnapshot(NtCurrentProcess(), SnapshotHandle);
}
DbgPrint("PssCaptureSnapshot=%u\n", err);
if (HANDLE hJob = CreateJobObject(0, 0))
{
bInJob = AssignProcessToJobObject(hJob, hProcess);
CloseHandle(hJob);
if (bInJob)
{
if (IsProcessInJob(hProcess, 0, &bInJob) && bInJob)
{
DbgPrint("process in job now!\n");
if (!(err = PssCaptureSnapshot(hProcess, PSS_CAPTURE_VA_CLONE, 0,&SnapshotHandle)))
{
PssFreeSnapshot(NtCurrentProcess(), SnapshotHandle);
}
DbgPrint("PssCaptureSnapshot=%u\n", err);
}
else
{
DbgPrint("process not in job !?\n");
}
}
else
{
DbgPrint("AssignProcessToJobObject error=%u\n", GetLastError());
}
}
else
{
DbgPrint("CreateJobObject error=%u\n", GetLastError());
}
}
else
{
DbgPrint("process already in job\n");
}
}
else
{
DbgPrint("IsProcessInJob error=%u\n", GetLastError());
}
CloseHandle(hProcess);
}
else
{
DbgPrint("OpenProcess error=%u\n", GetLastError());
}
}
}
else
{
DbgPrint("RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE)=%x\n", status);
}
in windows 8.1 i got next dbgprint:
found dwProcessId=950
PssCaptureSnapshot=0
process in job now!
PssCaptureSnapshot=5
but in windows 10 another picture:
found dwProcessId=4d0
PssCaptureSnapshot=0
process in job now!
PssCaptureSnapshot=0
are this is windows bug or feature - hard to say

Shutdown command is not working while system is locked

(There is a very similar topic that never got solved:here)
Here is my code
for (int i = 0; i < 5; i++)
{
Thread.Sleep(10000);
Console.WriteLine("Hi");
Process.Start("shutdown", "/s /t 0");
}
If I locked my system the shutdown process is not working otherwise it's working fine. When I unlock my system after 2 min it's showing only hi (5 times).
I think the shutdown command requires elevated privilege, so whether you call it your way or use an API, I would expect a UAC prompt to be required. You don't specify which version of Windows you're on but I think it's safe to assume UAC is present.
When the system is locked, a UAC prompt can't be shown and it times out after a while. So without an interactive user's express permission your shutdown can't proceed.
I think, to achieve your aim, you'd need to create a windows service that runs with high privilege, and have it call the correct API to shut the machine down. Then you can have a normal process communicate with your service and tell it to do the shutdown.
I hope somebody else can come up with a simpler solution for you.
Did you try other parameters of shutdown.exe like /p and/or /f?

Find out if another application is running as admin

I'm trying to determine if another application is running as an administrator. There are 100's of SO questions about finding if your application is or not, but not for another application.
If I do var processes = Process.GetProcesses(); and loop through them, they don't appear to have any "Elevated" or "IsAdministrator" properties on them. I also found a function on here to get the Owner but they all come back as "My-Laptop\Me" so that's not working for me the way I hoped it would.
Is there a way to find this? I'm on Win 8.1 and would prefer something that works for 7 as well, but if it only works for 8.1+ that's totally fine.
Thanks!
EDIT:
My application has to run as an administrator.
You can use the technique from this answer, just replace Process.GetCurrentProcess().Handle with the Process.Handle of the other process.
If you look at the code (there's quite a bit of code there) it get the process "user token" (the permissions the process is running under) and checks if this token has the administrator role or not,
Assuming your process is not running as administrator, trying to get information about a process that is elevated via UAC (such as its MainWindowTitle) will throw an AccessDenied exception, where a non-elevated process will permit you access to that information. This assumes you also verify the owner of the process to check that it's you.
try
{
var foo = process.MainWindowTitle;
return false; //Process is not elevated
}
catch (Win32Exception ex)
{
return true; //Process is elevated if ex error code is AccessDenied
}

ApplicationPool user vs StartInfo.Username?

I've been testing ( for the last 4 days) the variety of options to start a Process under iis7 ( asp.net)
I did find a solution.
As long as we don't need to interact with desktop, and only need to run cmd ( or something like that) the solution is simple:
w3wp user-> should be high privileged user.
Process start info (StartInfo.Username)-> should be also high privileged user.
However, there is a catch ( according to my testings):
Both users have to be the same (if we want cmd to execute)! this is the only way it will work.
So here are my 2 questions:
Why they both must be the same? Can't w3wp HighPrivilegedUSerA run (via process.startInfo) cmd as HighPriviligedUSerB?
Both users are domain admins.( which are also admins in my local group). Does only domain admin/local admin can run processes on the local machine?
p.s. All folders permissions are everyone : full controll ( including c:\windows\*.* /s and including cmd.exe permissions) and both users, as mentioned, are admins on local machine with same cloned permissions.IIS7 handler mapping * [static file] is set to read+execute
Also, the full cmd command is:
cmd /c time /t >c:\1.txt. A success is if the file exists.( and I succeed, only when both account were the same).
Full code:
Process proc = new Process();
proc.StartInfo.FileName = "cmd";
proc.StartInfo.UserName = "Royin"; //<-- only if this user is the same as w3wp user , the operation succeed !
proc.StartInfo.Domain = ...;
proc.StartInfo.WorkingFolder = #"c:\windows\system32";
proc.StartInfo.Password = ...
proc.StartInfo.Arguments = #"/c time /t >c:\1.txt"
proc.Start();
Ok, first, I HIGHLY recommend using the excellent SysInternals ProcessMonitor to help troubleshoot any issue like this: Process Monitor.
This app will basically tell you every action a process is attempting to take, so in your situation, you'd see it try to call QueryOpen, ProcessCreate, etc.
Have you checked what the ExitCode of the process is under the failing scenario? I'd be willing to bet real money it's coming back as 0xC0000142 (-1073741502), which means something like "failed to load DLL" or something. Running anything under the system32 path, even with privileged user credentials, is going to run into oddball issues with permissions, again due to the initialization procedure for creating a process.
Basically, the Process.Start flow looks something like this:
(assumptions: UserA == process running w3wp, UserB == impersonation ctx, UserC == credentials specified in process start info)
First, UserB isn't going to have much impact, as we've discussed in other conversations; any process creation stuff is going to be based on the process token of the "launching entity", so the credentials of UserA are the ones we'll be looking at.
The runtime says "Hey, can UserA access the file name specified in StartInfo.FileName?"
Windows responds yes/no, but also "BUT, to use that, you also need to be able to read all these other DLLs"
Runtime responds "Ok, can UserA access those DLLs?"
If the answer to all the above is yes, then the runtime says "Ok, logon this user and try creating a new process with cmd line and arguments..."
You are most-likely running into issues with either #2 or #4, as the default app pool identity has no read-access rights to the System32 folder. This is why when you switch the identity of the w3wp process to a privileged account, it works.
You could try a couple things, but the easiest option is probably switching back to a low-privilege account (like default app pool identity), but grant read-only access to the system32 folder to that account.
I would ABSOLUTELY not run w3wp as a privileged user, though - that is just asking for massive headaches should anything nasty happen, like somebody hacking you.
Oh, last thoughts:
DON'T set UseShellExecute to true if you can help it, it does weird stuff.
DON'T set LoadUserProfile to true if you can help it, it also does weird stuff, and is really slow as well.
DO set CreateNoWindow to true if you can, otherwise you'll see lotsa windows opening/closing on the server
DO use RedirectStandardOutput / RedirectStandardError instead of piping the output, it's way more controllable and gives better feedback when things go wrong.
DO always check the ExitCode of the process if it doesn't look like it worked

In app request for privilege escalation C#.NET

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.

Categories