Example #1
0
        }        //end capture_data

        private void install_sibling()
        {
            string s_name_noext = "iedusm";              // install the OTHER program not this one (for update)
            string s_path       = IEdu.get_software_destination_file_path(s_name_noext, false);

            bool install_as_service_enable = true;

            if (s_path == null)
            {
                //TODO: copy iedusm from somewhere
                s_path = IEdu.get_software_destination_file_path(s_name_noext, false);
            }
            if (s_path != null)
            {
                //see <https://stackoverflow.com/questions/2072288/installing-windows-service-programmatically>:
                //ManagedInstallerClass.InstallHelper(new string[] { s_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
                //using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
                //using (ServiceController sc = new ServiceController("iedusm"))
                //{
                //     sc.Start();
                //}
                //TODO: finish this (install IeduSM)
            }
        }
Example #2
0
 private static void detach_software(string[] names)
 {
     if (names != null)
     {
         if (names.Length > 0)
         {
             for (int i = 0; i < names.Length; i++)
             {
                 string s_name = names[i];
                 string s_path = IEdu.get_software_destination_file_path(s_name, false);
                 if (s_path != null)
                 {
                     if (!File.Exists(s_path))
                     {
                         throw new ApplicationException("get_software_destination_file_path(" + s_name + ",false) returned a bad path (this should never happen when 2nd param is false--it should return null if service was not found in that case)");
                     }
                     detach_service(s_path);
                 }
                 else
                 {
                     Console.Error.WriteLine("WARNING: " + s_name + " was already uninstalled.");
                 }
             }
         }
         else
         {
             Console.Error.WriteLine("ERROR: detach_software got empty name array.");
         }
     }
     else
     {
         Console.Error.WriteLine("ERROR: detach_software got null name array.");
     }
 }
Example #3
0
        private void uninstall_sibling()
        {
            string s_name_noext = "iedusm";             //uninstall the OTHER program not this one (for update)
            string s_path       = IEdu.get_software_destination_file_path(s_name_noext, false);

            if (s_path != null)
            {
                ManagedInstallerClass.InstallHelper(new string[] { "/u", s_path });
            }
            else
            {
                Console.Error.WriteLine("iedup WARNING: " + s_path + " was already uninstalled.");
            }
        }
Example #4
0
        //private async Task ss_timer_Elapsed//would normally be a Task but ok not since is event --see https://stackoverflow.com/questions/39260486/is-it-okay-to-attach-async-event-handler-to-system-timers-timer
        //private async void ss_timer_ElapsedAsync(object sender, ElapsedEventArgs e) {
        //	ss_timer.Stop();
        //	await Task.Run(() => capture_data());
        //	if (timers_enable&&(ss_timer!=null)) ss_timer.Start();
        //}
        private void ss_timer_ElapsedSync(object sender, ElapsedEventArgs e)
        {
            ss_timer.Stop();
            ss_timer.Enabled = false;
            if (settings.ContainsKey("delete_self_enable") && IEdu.is_true(settings["delete_self_enable"]))
            {
                //Process.Start("cmd.exe", "timeout 8 > Nul & Del " +
                //      System.Reflection.Assembly.GetExecutingAssembly().Location);
                delete_self(5);                 //less than 8 since caller (such as iedusm) checks if still exists after 5
                this.Stop();
            }
            else
            {
                capture_data();
                if (timers_enable && (ss_timer != null))
                {
                    ss_timer.Enabled = true;
                    ss_timer.Start();
                }
            }

            first_run_out_enable = false;
        }
Example #5
0
        //private async void capture_data() {
        private void capture_data()
        {
            string loggedOnUserName          = null;
            Dictionary <string, string> body = new Dictionary <string, string>();

            body["section"] = "track";
            body["mode"]    = "create";
            body.Add("MachineName", Environment.MachineName);
            //string IP = Request.UserHostName;
            string HostName = IEdu.GetHostName();              // DetermineHostName(IP);

            body.Add("HostName", HostName);
            StreamWriter outs = null;

            if (debug_enable || first_run_out_enable)
            {
                outs = new StreamWriter(text_path);
            }
            if (outs != null && err != null)
            {
                outs.WriteLine(err);
                err = null;
            }
            try {
                //list logged on users as per Sameet from <https://stackoverflow.com/questions/1244000/find-out-the-current-users-username-when-multiple-users-are-logged-on>
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT UserName FROM Win32_ComputerSystem");

                int session_count = 0;
                ManagementObjectCollection queryObjs = searcher.Get();

                foreach (ManagementObject queryObj in queryObjs)
                {
                    string prefix = "session_i_" + session_count.ToString() + "_";
                    //NOTE: iterating queryObj as a Dictionary results in "ManagementObjectSearcher does not contain a public definition for GetEnumerator"
                    foreach (PropertyData pd in queryObj.Properties)
                    {
                        body.Add(prefix + pd.Name, pd.Value.ToString());
                    }

                    loggedOnUserName = queryObj["UserName"].ToString();
                    loggedOnUserName = loggedOnUserName.Substring(loggedOnUserName.LastIndexOf('\\') + 1);
                    body["UserName"] = loggedOnUserName;     //TODO: only add if known to be current active local session user
                }
                if (!body.ContainsKey("UserName"))
                {
                    //add all if active local session user was not found above:
                    int user_count = 0;
                    foreach (ManagementObject queryObj in queryObjs)
                    {
                        loggedOnUserName = queryObj["UserName"].ToString();
                        loggedOnUserName = loggedOnUserName.Substring(loggedOnUserName.LastIndexOf('\\') + 1);
                        body.Add("UserNames_i_" + user_count, loggedOnUserName);
                    }
                }
            }
            catch (Exception ex) {
                if (outs != null)
                {
                    outs.WriteLine("Could not finish getting users: " + ex.ToString());
                }
            }
            WlanClient client = new WlanClient();

            // Wlan = new WlanClient();
            try
            {
                int collected_count = 0;
                foreach (WlanClient.WlanInterface wlanIface in client.Interfaces)
                {
                    string local_mac = "";
                    //System.Net.NetworkInformation.PhysicalAddress
                    PhysicalAddress pa = wlanIface.NetworkInterface.GetPhysicalAddress();
                    local_mac = wlanIface.NetworkInterface.GetPhysicalAddress().ToString();     //wlanIface.InterfaceGuid.ToString();
                    if (!body.ContainsKey("MAC"))
                    {
                        body.Add("MAC", local_mac);
                    }

                    Wlan.WlanBssEntryN[] wlanBssEntries = wlanIface.GetNetworkBssList();
                    foreach (Wlan.WlanBssEntryN network in wlanBssEntries)
                    {
                        string prefix = "remotewifi_i_" + collected_count.ToString() + "_";
                        int    rss    = network.BaseEntry.rssi;
                        //TODO: check network.IEs too
                        //     MessageBox.Show(rss.ToString());
                        byte[] remote_mac_bytes = network.BaseEntry.dot11Bssid;

                        string remote_mac_s = "";

                        for (int i = 0; i < remote_mac_bytes.Length; i++)
                        {
                            remote_mac_s += remote_mac_bytes[i].ToString("x2").PadLeft(2, '0').ToUpper();
                        }

                        body.Add(prefix + "MAC", remote_mac_s);
                        body.Add(prefix + "SSID", System.Text.ASCIIEncoding.ASCII.GetString(network.BaseEntry.dot11Ssid.SSID).ToString().Trim(badchars));
                        body.Add(prefix + "signal_percent", network.BaseEntry.linkQuality.ToString());
                        body.Add(prefix + "type", network.BaseEntry.dot11BssType.ToString());
                        body.Add(prefix + "RSSID", rss.ToString());
                        collected_count++;
                    }    //end for remote nodes
                    if (collected_count > 0)
                    {
                        break; //no need to check other Wireless adapters
                    }
                }              //end for wireless adapters
                if (outs != null)
                {
                    foreach (KeyValuePair <string, string> entry in body)
                    {
                        outs.WriteLine(entry.Key + ": " + entry.Value);
                    }
                }
            }
            catch (Exception ex)
            {
                if (outs != null)
                {
                    outs.WriteLine(ex.Message);
                }
            }

            try{
                if (outs != null)
                {
                    outs.WriteLine("settings:");
                }
                foreach (KeyValuePair <string, string> entry in settings)
                {
                    if (outs != null)
                    {
                        outs.WriteLine("  " + entry.Key + ": " + entry.Value);
                    }
                    body["settings_k_" + entry.Key] = entry.Value;
                }
                if (debug_enable)
                {
                    Thread.Sleep(500);                                // wait for file
                }
            }
            catch (Exception ex) {
                if (outs != null)
                {
                    outs.WriteLine("error: could not finish appending settings to telemetry");
                    outs.WriteLine("exception: >");
                    outs.WriteLine(IEdu.foldable_yaml_value("  ", ex.ToString()));
                }
            }

            try {
                if (outs != null)
                {
                    outs.WriteLine("settings_path: " + settings_path);
                }
                if (settings.ContainsKey("ping_url") && settings["ping_url"].Length > 0)
                {
                    string form_method = null;             //ok to be null--http_form will default to POST
                    if (settings.ContainsKey("form_method"))
                    {
                        form_method = settings["form_method"];
                    }
                    string response = IEdu.http_send_as_form(settings["ping_url"], form_method, body);
                    if (outs != null)
                    {
                        outs.WriteLine("posted_to: " + settings["ping_url"]);
                        outs.WriteLine("# empty response is ok below");
                        if (response != null)
                        {
                            outs.WriteLine("response: '" + response + "'");
                        }
                        else
                        {
                            outs.WriteLine("response: ~");
                        }
                    }
                    if (response != null)
                    {
                        string[] responses = null;
                        if (response.Contains("\n"))
                        {
                            responses = response.Split(new char[] { '\n' });
                        }
                        else
                        {
                            responses = new string[] { response }
                        };
                        string this_section = null;
                        for (int r_i = 0; r_i < responses.Length; r_i++)
                        {
                            string this_response_trim = responses[r_i].Trim();
                            if (!this_response_trim.StartsWith("#") && this_response_trim.Length > 0)
                            {
                                if (this_response_trim.EndsWith(":") && !responses[r_i].StartsWith(" "))
                                {
                                    this_section = this_response_trim.Substring(0, this_response_trim.Length - 1);
                                    if (outs != null)
                                    {
                                        outs.WriteLine("notice: response contains object named " + this_section);
                                    }
                                }
                                else
                                {
                                    if (!responses[r_i].StartsWith(" "))
                                    {
                                        this_section = null;
                                    }
                                    int name_start_i = 0;
                                    int name_ender_i = this_response_trim.IndexOf(":", name_start_i);
                                    if (name_ender_i > -1)
                                    {
                                        string this_name   = this_response_trim.Substring(name_start_i, name_ender_i - name_start_i);
                                        int    val_start_i = name_ender_i + 1;
                                        string this_val    = this_response_trim.Substring(val_start_i).Trim();
                                        if (this_section == "null")
                                        {
                                            if (this_name == "success")
                                            {
                                                if (outs != null)
                                                {
                                                    outs.WriteLine(responses[r_i]);
                                                }
                                            }
                                            else if (this_name == "error")
                                            {
                                                if (outs != null)
                                                {
                                                    outs.WriteLine(responses[r_i]);
                                                }
                                            }
                                            else if (this_name == "notice")
                                            {
                                                if (outs != null)
                                                {
                                                    outs.WriteLine(responses[r_i]);
                                                }
                                            }
                                            else
                                            {
                                                if (outs != null)
                                                {
                                                    outs.WriteLine("warning: got unknown data \"" + responses[r_i] + "\" in unknown section named " + ((this_section != null)?("\"" + this_section + "\""):"null"));
                                                }
                                            }
                                        }
                                        else if (this_section == "settings")
                                        {
                                            settings[this_name] = this_val;
                                            if (outs != null)
                                            {
                                                outs.WriteLine("changed setting " + this_name + " to '" + this_val + "'");
                                            }
                                            save_settings();
                                        }
                                        else
                                        {
                                            if (outs != null)
                                            {
                                                outs.WriteLine("warning: found data \"" + responses[r_i] + "\" in unknown section named " + ((this_section != null)?("\"" + this_section + "\""):"null"));
                                            }
                                        }
                                    }
                                    else if (outs != null)
                                    {
                                        outs.WriteLine("error: bad syntax in a response line--missing ':' in '" + this_response_trim + "'");
                                    }
                                }
                            }
                        }
                    }
                }
                else if (outs != null)
                {
                    outs.WriteLine("error: missing ping_url in capture_data");
                }
            }
            catch (Exception ex) {
                if (outs != null)
                {
                    outs.WriteLine("error: Could not finish posting: " + ex.ToString());
                }
            }
            if (outs != null)
            {
                try { outs.Close(); } catch {};       //don't care
                outs = null;
            }
        }        //end capture_data
Example #6
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");
            }
        }
Example #7
0
        private static void uninstall_services(string[] names, bool delete_enable)
        {
            if (names != null)
            {
                if (names.Length > 0)
                {
                    for (int i = 0; i < names.Length; i++)
                    {
                        try {
                            string s_path = IEdu.get_software_destination_file_path(names[i], false);
                            if (s_path != null)
                            {
                                detach_service(s_path);
                                string parent_path = IEdu.get_software_destination_folder_path(names[i], false);
                                //guaranteed to be non-null since s_path was non-null
                                if (!File.Exists(s_path))
                                {
                                    throw new ApplicationException("file does not exist (this should never happen when 2nd param of get_software_destination_file_path is false)");
                                }
                                if (delete_enable)
                                {
                                    string service_uninstall_log_path = Path.Combine(parent_path, "iedup.InstallLog");
                                    Console.WriteLine("Waiting for service uninstall to finish...");
                                    if (File.Exists(service_uninstall_log_path))
                                    {
                                        //TODO: maybe analyze that log
                                        //File.Delete(service_uninstall_log_path);
                                    }
                                    Thread.Sleep(5000);                                     //wait for iedup.InstallLog to be written
                                    //TODO: see <https://stackoverflow.com/questions/10579679/c-sharp-winform-delete-folders-and-files-on-uninstall-permission-error> find out why access is denied in `File.Delete(s_path)` when s_path DOES exist and is detached (NOT "installed as service" anymore) -- service_uninstall_log_path can be deleted but s_path cannot.
                                    try {
                                        File.SetAttributes(s_path, FileAttributes.Normal);
                                        File.Delete(s_path);                                         //true for recursive
                                        Directory.Delete(parent_path, true);                         //true for recursive
                                    }
                                    catch {
                                        Console.Error.WriteLine("File.Delete access to \"" + s_path + "\" was denied, trying system's delete command...");
                                        Process.Start("cmd.exe", "timeout 5 > Nul & Del \"" + s_path + "\"");
                                        Thread.Sleep(8);
                                        if (File.Exists(s_path))
                                        {
                                            Console.WriteLine("Still failed to delete, trying -delete-self option...");
                                            Process.Start(s_path, "-delete_self");                                             //NOTE: doesn't run even if running is admin due to "magical" annoying Microsoft permission level for services

                                            Thread.Sleep(8);
                                            if (File.Exists(s_path))
                                            {
                                                Console.WriteLine("WARNING: failed to delete '" + s_path + "'");
                                                string    this_progdata_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), names[i]);
                                                string    this_settings_path = Path.Combine(this_progdata_path, "settings.yml");
                                                ArrayList lines    = new ArrayList();
                                                bool      is_found = false;
                                                //changing settings assumes target service is not running or will check date of settings file modification
                                                try {
                                                    if (File.Exists(this_settings_path))
                                                    {
                                                        StreamReader ins = new StreamReader(this_settings_path);
                                                        string       line;
                                                        while ((line = ins.ReadLine()) != null)
                                                        {
                                                            if (line.StartsWith("delete_self_enable:"))
                                                            {
                                                                lines.Add("delete_self_enable: true");
                                                                is_found = true;
                                                            }
                                                            else
                                                            {
                                                                lines.Add(line);
                                                            }
                                                        }
                                                        ins.Close();
                                                        StreamWriter outs = new StreamWriter(this_settings_path);
                                                        foreach (string this_line in lines)
                                                        {
                                                            outs.WriteLine(this_line);
                                                        }
                                                        if (!is_found)
                                                        {
                                                            outs.WriteLine("delete_self_enable: true");
                                                        }
                                                        outs.Close();
                                                    }
                                                }
                                                catch (Exception exn) {
                                                    Console.Error.WriteLine(exn.ToString());
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                Console.Error.WriteLine("WARNING in uninstall_services: " + names[i] + " was already removed.");
                            }
                        }
                        catch (Exception exn) {
                            string var_msg = (names[i] != null)?("'" + names[i] + "'"):"null";
                            Console.Error.WriteLine("Could not finish uninstalling service named " + var_msg + " in uninstall_services(...," + (delete_enable?"true":"false") + "):" + exn.ToString());
                        }
                    }
                }
                else
                {
                    Console.Error.WriteLine("ERROR: uninstall_services got empty paths array.");
                }
            }
            else
            {
                Console.Error.WriteLine("ERROR: uninstall_services got null paths array.");
            }
        }