Beispiel #1
0
        /// <summary>
        /// This method starts the service.
        /// </summary>
        static void Main(string[] args)
        {
            //normally Main is one line (and no args above) for services:
            // To run more than one service you have to add them here
            //ServiceBase.Run(new ServiceBase[] { new iedusm() });
            //but let's implement self-install as per <https://stackoverflow.com/questions/2072288/installing-windows-service-programmatically>:
            if (System.Environment.UserInteractive)
            {
                Console.Error.WriteLine("This program would normally be run as a service");
                if (args.Length > 0)
                {
                    switch (args[0])
                    {
                    case "-install":
                    {
                        Console.Error.WriteLine(" but found " + args[0] + " option so continuing with that...");
                        ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
                        //starting it as per codemonkey from <https://stackoverflow.com/questions/1036713/automatically-start-a-windows-service-on-install>:
                        //results in access denied (same if done manually, unless "Log on as" is changed from LocalService to Local System
                        //serviceInstaller
                        //using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
                        //using (ServiceController sc = new ServiceController("iedusm"))
                        //{
                        //     sc.Start();
                        //}
                        break;
                    }

                    case "-uninstall":
                    {
                        Console.Error.WriteLine(" but found " + args[0] + " option so continuing with that...");
                        ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
                        break;
                    }

                    case "-detach_managed_software":
                    {
                        Console.Error.WriteLine(" but found " + args[0] + " option so continuing with that...");
                        IEduSM.uninstall_services(false);
                        break;
                    }

                    case "-delete_managed_software":
                    {
                        Console.Error.WriteLine(" but found " + args[0] + " option so continuing with that...");
                        IEduSM.uninstall_services(true);
                        break;
                    }

                    case "-install_managed_software":
                    {
                        Console.Error.WriteLine(" but found " + args[0] + " option so continuing with that...");
                        IEduSM.update_software();
                        break;
                    }

                    case "-update_managed_software":
                    {
                        Console.Error.WriteLine(" but found " + args[0] + " option so continuing with that...");
                        IEduSM.update_software();
                        break;
                    }

                    default:
                    {
                        Console.Error.WriteLine(" ERROR: unknown option '" + args[0] + "'");
                        break;
                    }
                    }
                }
                else
                {
                    //make sure other program are install (such as if someone right-clicked this to run as Administrator)
                    //Console.Error.WriteLine(" or be run with -install, -uninstall -services_install or -services_uninstall option.");
                    Console.Error.WriteLine(" so taking defensive measures...");
                    IEduSM.update_software();
                }
            }
            else
            {
                Console.Error.WriteLine("Running service...");
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] { new IEduSM() };
                ServiceBase.Run(ServicesToRun);
            }
        }        //end  Main
Beispiel #2
0
        private static void update_software(string[] names)
        {
            if (names != null)
            {
                if (names.Length > 0)
                {
                    Console.Error.WriteLine("update_software will check for already-installed versions in (list may have dups since forces check for x86 in environment variables):");
                    string[] destination_dir_paths = IEdu.get_software_destination_possible_folder_paths(names[0]);
                    for (int j = 0; j < destination_dir_paths.Length; j++)
                    {
                        Console.Error.WriteLine("  - " + destination_dir_paths[j].Replace(char.ToString(Path.DirectorySeparatorChar) + names[0], ""));
                    }
                    Console.Error.WriteLine();
                    for (int i = 0; i < names.Length; i++)
                    {
                        bool   copyfiles_enable = false;
                        string s_name           = names[i];
                        try {
                            string source_file_path = IEdu.get_software_source_file_path(s_name);
                            if (source_file_path == null)
                            {
                                string   msg     = "A source for " + s_name + " could not be found in:";
                                string[] sources = IEdu.get_software_source_expected_paths(s_name);
                                for (int l = 0; l < sources.Length; l++)
                                {
                                    msg += "\n  - " + sources[l];
                                }
                                throw new ApplicationException(msg);
                            }
                            string destination_file_path = IEdu.get_software_destination_file_path(s_name, false);
                            //TODO: also update
                            bool update_enable = true;                             //TODO: only enable if version changed
                            if (destination_file_path == null)
                            {
                                Console.Error.WriteLine("update_software did not find the program " + s_name + ", so installing...");
                                string destination_folder_path = IEdu.get_software_destination_folder_path(s_name, true);
                                if (source_file_path != null && File.Exists(source_file_path))
                                {
                                    //setup (copy files to destination)
                                    //guaranteed to not to return null when 2nd param is true
                                    if (!Directory.Exists(destination_folder_path))
                                    {
                                        Directory.CreateDirectory(destination_folder_path);
                                    }
                                    copyfiles_enable = true;
                                }
                                else
                                {
                                    Console.Error.WriteLine("ERROR: The missing service was not copied to " + destination_folder_path + " because the installer service could not find the install source in any of the following locations:");
                                    string[] possible_sources = IEdu.get_software_source_expected_paths(s_name);
                                    for (int k = 0; k < possible_sources.Length; k++)
                                    {
                                        Console.Error.WriteLine("  - " + possible_sources[k]);
                                    }
                                    Console.Error.WriteLine();
                                }
                            }
                            else
                            {
                                if (update_enable)
                                {
                                    IEduSM.detach_service(IEdu.get_software_destination_file_path(s_name, false));
                                    copyfiles_enable = true;
                                }
                            }

                            if (copyfiles_enable)
                            {
                                //we are already assured by get_service_path that the following doesn't exist since fell through to github:
                                string new_s_path = IEdu.get_software_destination_file_path(s_name, true);
                                Console.Error.WriteLine("Copying '" + s_name + "' from GitHub build folder to '" + new_s_path + "'");
                                try {
                                    if (File.Exists(new_s_path))
                                    {
                                        File.Delete(new_s_path);
                                    }
                                }
                                catch (Exception exn) {
                                    Console.Error.WriteLine("Could not finish deleting old version of " + s_name + ": " + exn.ToString());
                                }
                                if (!File.Exists(new_s_path))
                                {
                                    File.Copy(source_file_path, new_s_path);
                                    if (!File.Exists(new_s_path))
                                    {
                                        Console.Error.WriteLine("Could not copy '" + source_file_path + "' to destination directory '" + IEdu.get_software_destination_folder_path(s_name, true) + "'. You must run this as Administrator.");
                                    }
                                    else
                                    {
                                        destination_file_path = IEdu.get_software_destination_file_path(s_name, false);
                                    }
                                }
                                else
                                {
                                    Console.Error.WriteLine("Could not install " + s_name + " since old version couldn't be deleted (maybe you didn't have permission to delete the file, or didn't have permission to detach (\"uninstall\") a service [or stop services which would have to be done first if running])!");
                                }
                            }

                            if (destination_file_path != null)
                            {
                                if (copyfiles_enable)
                                {
                                    //already copied files, but now need to install service SINCE they were (updated/added).
                                    //NOTE: get_service_path assures that s_path exists in this case
                                    //      (if it was in GitHub folder, install to ProgramFiles was already tried,
                                    //      and s_path changed to Program Files*\<s_name>\<s_name>.exe).

                                    // see <https://docs.microsoft.com/en-us/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer#code-snippet-1>
                                    // via <https://stackoverflow.com/questions/2072288/installing-windows-service-programmatically>:

                                    //detach_software(new string[] {s_name});
                                    //detach_service(s_path); //already done if existed0
                                    ManagedInstallerClass.InstallHelper(new string[] { destination_file_path });

                                    //Starting it as per codemonkey from <https://stackoverflow.com/questions/1036713/automatically-start-a-windows-service-on-install>:
                                    // results in access denied (same if done manually, unless "Log on as" is changed from LocalService to Local System
                                    //serviceInstaller
                                    //ServiceProcessInstaller serviceProcessInstaller1 = new ServiceProcessInstaller();
                                    //serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
                                    //serviceProcessInstaller1.Installers
                                    //using (ServiceController sc = new ServiceController(s_name)) {
                                    //	sc.ServiceType = ServiceType.InteractiveProcess;//TODO: is this correct?
                                    //	sc.Start();
                                    //}
                                    // and doesn't have a way to set account, so set in IEduInstaller.cs which inherits from Installer and don't call it manually

                                    /*
                                     * // --below won't work either since Commit is called by install utilities which know the state of the service (but don't need overload since can start it manually)
                                     * Installer installer;
                                     *
                                     *
                                     * installer = new Installer();
                                     * ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
                                     * serviceProcessInstaller.Account = ServiceAccount.LocalSystem; // Or whatever account you want
                                     * ServiceInstaller si = new ServiceInstaller();
                                     * si.DelayedAutoStart = true;
                                     * si.DisplayName = s_name;
                                     * si.Description = s_name;
                                     * si.DisplayName = s_name;
                                     * //si.HelpText
                                     * //si.Installers
                                     * //si.Parent //do set since not child
                                     * si.ServiceName = s_name;
                                     * //si.ServicesDependedOn //do not set since not parent either
                                     * //si.Site // I dont' know what this does
                                     * si.StartType = ServiceStartMode.Automatic;
                                     *
                                     * //var serviceInstaller = new ServiceInstaller
                                     * //{
                                     * //    DisplayName = "Insert the display name here",
                                     * //    StartType = ServiceStartMode.Automatic, // Or whatever startup type you want
                                     * //    Description = "Insert a description for your service here",
                                     * //    ServiceName = "Insert the service name here"
                                     * //};
                                     * installer.Installers.Add(serviceProcessInstaller);  // why was this _serviceProcessInstaller fre0n?
                                     * installer.Installers.Add(si);
                                     * installer.Commit();
                                     */
                                    Console.WriteLine("Trying to start service manually...");
                                    ServiceController sc = new ServiceController(s_name);                              // using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
                                    //sc.ServiceType = ServiceType.InteractiveProcess;  // TODO: why is this readonly and should it be changed somehow?
                                    sc.Start();


                                    //or use IEduPServiceInstaller (see its cs file) based on fre0n's answer from <https://stackoverflow.com/questions/2253051/credentials-when-installing-windows-service/2253140#2253140>:
                                }
                                else
                                {
                                    Console.Error.WriteLine("Update for " + s_name + " was not enabled/needed.");
                                }
                            }
                            else
                            {
                                Console.Error.WriteLine("ERROR: Path to " + s_name + " could not be detected.");
                            }
                        }
                        catch (Exception exn) {
                            string var_msg = (names[i] != null)?("'" + names[i] + "'"):"null";
                            Console.Error.WriteLine("Could not finish update_software named " + var_msg + ":" + exn.ToString());
                        }
                    }                    //end for i<names.Length
                }
                else
                {
                    Console.Error.WriteLine("ERROR: update_software got empty names array");
                }
            }
            else
            {
                Console.Error.WriteLine("ERROR: update_software got null names array");
            }
        }