November Wallpaper L’Impero dei Draghi (3)

Implementation details

Both ServiceBase.OnCustomCommand and ServiceController.ExecuteCommand methods can deal only with an integer value: the only values for a custom command that you can define in your application or use in OnCustomCommand are those between 128 and 256. Integers below 128 correspond to system-reserved values. So this is the reason why the IPC is obtained throught a file: the ExecutedCommand only send a "signal" to the service, then the actual command and arguments to execute are stored in the file.

MVPrivilegedExecuter.dll

using System;
using System.IO;
using System.ServiceProcess;

namespace MV
{
    public class MVPrivilegedExecuter
    {

        public static bool Execute(
            string IPCFile,
            string ApplicationToExecute,
            string ApplicationArguments,
            out string ErrorMessage)
        {

            try
            {

				// Delete the existing file
                if (File.Exists(IPCFile))
                    File.Delete(IPCFile);


				// Write the command to the IPC file
                using (StreamWriter sw = File.CreateText(IPCFile))
                {
                    sw.WriteLine(ApplicationToExecute + "|||" + ApplicationArguments);
                }


				// Invokes the service
                string ServiceName = "MV Executer";

                ServiceController sc = new ServiceController(ServiceName);
                sc.ExecuteCommand(255);
                
                
				// Empty error message, invocation successful
                ErrorMessage = "";
                
                // Return success
                return true;
            }
            catch(Exception ex)
            {
            	// Put the error message in the out variable
                ErrorMessage = ex.Message;
                
                // Return failure
                return false;
            }

            
        }
    }
}

MV Executer Service

Below the relevant code for the task goal:

        public enum commands
        {

            ExecuteCommand = 255

        }
        protected override void OnCustomCommand(int command)
        {
            base.OnCustomCommand(command);
            if (command == (int)commands.ExecuteCommand)
            {
                ExecuteCommand();
            }
        }

        private void ExecuteCommand()
        {


            string inFile = Properties.Settings.Default.CommandFile;
            try
            {

                string command = File.ReadAllText(inFile, Encoding.UTF8);

                Utils.WriteEventLog("Executing command: " + command, EventLogEntryType.Information, 1);


                File.Delete(inFile);



                string[] v = command.Split(
                    new string[] { Properties.Settings.Default.CommandSeparator }, 
                    StringSplitOptions.RemoveEmptyEntries);

                if (v.Length > 2)
                    throw new Exception("Invalid command length: " + v.Length);

                string file = v[0];
                string arguments = "";
                if (v.Length > 1) arguments = v[1];

                System.Diagnostics.Process p = new System.Diagnostics.Process();

                System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();
                info.UseShellExecute = false;
                info.FileName = file;
                info.Arguments = arguments;
                info.RedirectStandardOutput = true;
                info.RedirectStandardError = true;

                p.StartInfo = info;

                p.Start();


                string error = p.StandardError.ReadToEnd();
                string output = p.StandardOutput.ReadToEnd();

                p.WaitForExit();

                Utils.WriteEventLog("Executed command:\r\n" + output, EventLogEntryType.Information, 2);
                
                if (error != null && error != "")
                    Utils.WriteEventLog("Executed command errors:\r\n" + error, EventLogEntryType.Error, 0);

                
            }
            catch (Exception ex)
            {

                Utils.WriteEventLog("Error executing command: " + ex.Message + "\r\n" + ex.ToString(), EventLogEntryType.Error);
            }
        }

As you can see, the service will write relevant activities to the system event log.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Technorati
  • Sphinn
  • Facebook
  • LinkedIn
  • Live
Pages: 1 2 3
Improve Microon Lounge rating this post
Tell me what do you think about "Run commands with administrator privileges from asp.net page": I'll write better and better entries.
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading ... Loading ...

Leave a Reply


your name
your e-mail address
your website/url

Isn't this worth at least €1?

Any donation is appreciated, consider a €1 donation for each download (or maybe €1.35 since PayPal takes €0.35 from a €1.00 donation). Your support allows me to continue to create free software.