Scheduling tasks with 'schtasks' without admin privileges C# - c#

I am trying to schedule the tasks from my application using schtasks instead of using the Windows Task Scheduler COM/managed API.
Creating a task here is easier by using this on command line schtasks /Create /tn "MyApp" /tr c:\myapp.exe /sc onlogon but I opened the command line as an administrator to get the task created (otherwise I get access denied)
From my application, to create the task I use
string args = #"/Create /tn MyApp /tr c:\myapp.exe /sc onlogon";
Process.Start("schtasks", args);
However, the task gets created only if I run my application as an administrator. I need to avoid this, so that any user can create the task without the hassle of running the app as admin. Any suggestions on how ca this be done?

You can try with a sort of RunAs that allow to run a process with a specified user :
ProcessStartInfo psi = new ProcessStartInfo("schtasks");
psi.UseShellExecute = false;
psi.UserName = "Username";
psi.Password = "password";
Process.Start(psi);
The Process class through ProcessStartInfo provides a mechanism which allows you to specify the user context that the new process should run under, so you can specify the user in which you want to run the command even if the user that start the program is different. In your case you can specify Administrator credentials to the ProcessStartInfo without having to run the program with an Administrator user ...

Why should that require user interruption each time in an exhibition
booth PC which is mounted just for exposition purpose?
If you want a hidden program that will run on a PC whenever it is booted, and your task is not harmful, you can add it to the following registry key:
HKCU\Software\Windows\CurrentVersion\Run
programmatically. I can provide code if needed.

Contents of TextBox: "SCHTASKS.exe /Create /ST 06:30 /SC DAILY /TN report /TR notepad.exe"
I was able to use Process.Start(ProcessStartInfo);
ProcessStartInfo psinfo = new ProcessStartInfo();
psinfo.Filename = "powershell.exe";
psinfo.Args = textbox1.text;
Process.Start(psinfo);
**Of course, this will only work on machines that have powershell installed, using cmd.exe failed to create the scheduled task...

Related

Asynchronous task using Task.Factory.StartNew()

At some point of execution of our project we are using Task.Factory.StartNew() for creating asynchronous tasks. which are required to delete some temporary files. following is the code i am using for this :
Task.Factory.StartNew(Function() deleteTempDocs(path))
The problem is that some folders may have privilege restrictions. so i need to run this tasks with Administrator Rights. even if my project is not running in admin Rights. is it possible to set rights like this?
It isn't possible to run a task with Administrator rights, as rights are assigned on a process level. You would have to start a new process, for example a batch file, and get it to run as administrator.
var process = new Process();
var processStartInfo = new ProcessStartInfo();
processStartInfo.Verb = "runas"; // runs as Administrator
processStartInfo.FileName = "myFileDeleter.exe";
process.StartInfo = processStartInfo;
process.Start();
process.WaitForExit();

Program running in administrative mode needs to run another application in non-administrative mode?

I have a program that runs in administrative mode. This program should run another application. Since my application is run in administrative mode, the new application is run in administrative too. How to run this new application in non-administrative mode?
What you want is Process.Start passing a StartInfo object specifies the credentials of the use you want to start the process as.
Process.Start Method (ProcessStartInfo)
Something like this should get you started . . .
var startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = "Myexe.exe";
startInfo.UserName = "Myuser";
startInfo.Password = "MyUsersPassword";
System.Diagnostics.Process.Start(startInfo);
If you want it to run as the current user, but not in admin mode, try passing the current users credentials, I haven't tested it, but it might work.

Run process under current user

There is "Setup project" in VS. During installation I launch another process:
System.Diagnostics.Process process = new System.Diagnostics.Process();
//fill StartInfo and run call Start()
process.Start();
If I run installer under Windows 7 and install for "Everyone", process start under the SYSTEM. If I install "Just for me", process start under Current user. How do I always start process under Current user?
I have found very simple solution. All that you need it just create a new class and copy text from this link.
To launch the process call ProcessAsUser.Launch("program name");
I had a similar problem: My setup extension (custom action) needed Admin privileges which brought up an elevation box. After I start my application at the end of "Just for Me" the process had settings that were made for the admin context. For example my user account likes to see all extensions of files in Windows Explorer but the admin account was configured to hide them. So in every file open box I couldn't see the extensions. To cure this this piece of code worked:
ProcessStartInfo startInfo = new ProcessStartInfo(ShortcutTarget);
startInfo.LoadUserProfile = true;
startInfo.UseShellExecute = false;
Process.Start(startInfo);
It works only in "Just for Me" mode, in "Everyone" the admin's settings are used. But this is ok for me.
Use ProcessStartInfo class and its property UserName, then use it as argument for Process.Start static method.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Process.Start(startInfo);

Admin rights for a single method

Is it possible to require administrator rights for one single method?
Something like this:
[RequireAdminRightsForThisMethod()]
private void TheMethod(){
// Do something
}
You can add a PrincipalPermission attribute to your method to demand administrative privileges for its execution:
[PrincipalPermission(SecurityAction.Demand, Role = #"BUILTIN\Administrators")]
public void MyMethod()
{
}
This is described in more detail in the following article:
Security Principles and Local Admin Rights in C# .Net
If you are looking for a way to elevate an already existing process I doubt that this is possible as administrator privileges are given on process-level to a process upon startup (see this related question). You would have to run your application "as administrator" to get the desired behavior.
However, there are some tricks that might allow you to do what you want, but be warned that this might open up severe security risks. See the following thread in the MSDN forums:
Launching MyElevatedCom Server without prompting Administrator credentialls from Standard User
Update (from comment)
It seems that if an update requires elevation your application update is best done by a separate process (either another executable, or your application called with a command line switch). For that separate process you can request elevation as follows:
var psi = new ProcessStartInfo();
psi.FileName = "path to update.exe";
psi.Arguments = "arguments for update.exe";
psi.Verb = "runas";
var process = new Process();
process.StartInfo = psi;
process.Start();
process.WaitForExit();
A method can require administrative privileges to run, but it's not possible to automatically elevate to Admin when executing a method.

Elevating process privilege programmatically?

I'm trying to install a service using InstallUtil.exe but invoked through Process.Start. Here's the code:
ProcessStartInfo startInfo = new ProcessStartInfo (m_strInstallUtil, strExePath);
System.Diagnostics.Process.Start (startInfo);
where m_strInstallUtil is the fully qualified path and exe to "InstallUtil.exe" and strExePath is the fully qualified path/name to my service.
Running the command line syntax from an elevated command prompt works; running from my app (using the above code) does not. I assume I'm dealing with some process elevation issue, so how would I run my process in an elevated state? Do I need to look at ShellExecute for this?
This is all on Windows Vista. I am running the process in the VS2008 debugger elevated to admin privilege.
I also tried setting startInfo.Verb = "runas"; but it didn't seem to solve the problem.
You can indicate the new process should be started with elevated permissions by setting the Verb property of your startInfo object to 'runas', as follows:
startInfo.Verb = "runas";
This will cause Windows to behave as if the process has been started from Explorer with the "Run as Administrator" menu command.
This does mean the UAC prompt will come up and will need to be acknowledged by the user: if this is undesirable (for example because it would happen in the middle of a lengthy process), you'll need to run your entire host process with elevated permissions by Create and Embed an Application Manifest (UAC) to require the 'highestAvailable' execution level: this will cause the UAC prompt to appear as soon as your app is started, and cause all child processes to run with elevated permissions without additional prompting.
Edit: I see you just edited your question to state that "runas" didn't work for you. That's really strange, as it should (and does for me in several production apps). Requiring the parent process to run with elevated rights by embedding the manifest should definitely work, though.
This code puts the above all together and restarts the current wpf app with admin privs:
if (IsAdministrator() == false)
{
// Restart program and run as admin
var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
ProcessStartInfo startInfo = new ProcessStartInfo(exeName);
startInfo.Verb = "runas";
System.Diagnostics.Process.Start(startInfo);
Application.Current.Shutdown();
return;
}
private static bool IsAdministrator()
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
// To run as admin, alter exe manifest file after building.
// Or create shortcut with "as admin" checked.
// Or ShellExecute(C# Process.Start) can elevate - use verb "runas".
// Or an elevate vbs script can launch programs as admin.
// (does not work: "runas /user:admin" from cmd-line prompts for admin pass)
Update: The app manifest way is preferred:
Right click project in visual studio, add, new application manifest file, change the file so you have requireAdministrator set as shown in the above.
A problem with the original way: If you put the restart code in app.xaml.cs OnStartup, it still may start the main window briefly even though Shutdown was called. My main window blew up if app.xaml.cs init was not run and in certain race conditions it would do this.
According to the article Chris Corio: Teach Your Apps To Play Nicely With Windows Vista User Account Control, MSDN Magazine, Jan. 2007, only ShellExecute checks the embedded manifest and prompts the user for elevation if needed, while CreateProcess and other APIs don't. Hope it helps.
See also: same article as .chm.
[PrincipalPermission(SecurityAction.Demand, Role = #"BUILTIN\Administrators")]
This will do it without UAC - no need to start a new process. If the running user is member of Admin group as for my case.
i know this is a very old post, but i just wanted to share my solution:
System.Diagnostics.ProcessStartInfo StartInfo = new System.Diagnostics.ProcessStartInfo
{
UseShellExecute = true, //<- for elevation
Verb = "runas", //<- for elevation
WorkingDirectory = Environment.CurrentDirectory,
FileName = "EDHM_UI_Patcher.exe",
Arguments = #"\D -FF"
};
System.Diagnostics.Process p = System.Diagnostics.Process.Start(StartInfo);
NOTE: If VisualStudio is already running Elevated then the UAC dialog won't show up, to test it run the exe from the bin folder.
You should use Impersonation to elevate the state.
WindowsIdentity identity = new WindowsIdentity(accessToken);
WindowsImpersonationContext context = identity.Impersonate();
Don't forget to undo the impersonated context when you are done.

Categories

Resources