public ClientInfo TryConnect(Guid extProcID, string address) { var info = new ClientInfo(); ServerExtensionClient client; try { client = new ServerExtensionClient(address); client.RegisterClient(); info.ExtensionID = client.ID; if (client.SingleInstanceOnly) { bool isNotUnique; lock (_clients) isNotUnique = _clients.Any(c => c.ExtensionID == info.ExtensionID); if (isNotUnique) { _logger.Warn("A second instance of the extension \"" + info.ExtensionID + "\" was found, but the extension has specified that only one instance is allowed to run at a time. The second instance will be stopped."); _extProcMgr.Stop(extProcID); return(null); } } info.ExtProcID = extProcID; info.Name = client.Name; info.Description = client.Description; info.Commands = client.GetCommands(); info.Client = client; _logger.Info("Connected to extension: " + info.Name); } catch (Exception ex) { _logger.ErrorException("Exception thrown while trying to connect to extension \"" + info.Name + "\"", ex); return(null); } client.Disconnected += c => { lock (_clients) _clients.Remove(info); _logger.Info("Lost connection to extension: " + info.Name); }; client.NotificationReceived += (src, msg, lvl) => { var handler = ExtensionNotificationReceived; if (handler != null) { handler(info.ExtProcID, info.ExtensionID, info.Name, src, msg, lvl); } }; lock (_clients) _clients.Add(info); return(info); }
private void UpdateRunningExtensions() { _logger.Info("Parsing extensions.txt file..."); IEnumerable <string> lines; try { lines = _file.Exists ? File.ReadLines(_file.FullName) : new string[0]; } catch (IOException ex) { _logger.WarnException("Unable to read extensions file", ex); return; } var bag = new List <KeyValuePair <string, Guid> >(_extProcMgr.GetExtensionProcessList() .Select(p => new KeyValuePair <string, Guid>(string.Concat(p.DirectoryName, '\t', p.RequestedExtensionIDs.Concat(",")).Trim(), p.ID))); foreach (var line in lines) { var linestr = Regex.Replace((line ?? "").Trim(), @"\t+", "\t"); if (string.IsNullOrWhiteSpace(linestr) || linestr.StartsWith("#")) { continue; } var arr = linestr.Split('\t'); if (arr.Length > 2) { continue; } var dir = arr[0].Trim(); string[] ids = null; if (arr.Length == 2) { ids = arr[1].Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(a => a.Trim()).ToArray(); } // linestr becomes the key identifying the extension process. there may be multiple processes with the same linestr. linestr = string.Concat(dir, '\t', ids.Concat(",")).Trim(); // find out if we already have an extension process matching linestr and if so, remove it from the bag so it stays running. var item = bag.FirstOrDefault(b => b.Key == linestr); if (item.Key != null) { _logger.Info("Extension config line matches pre-existing process: " + linestr); bag.Remove(item); } else { // seeing as there were no entries in the bag matching the current linestr, we've identified a new process that needs to be started up _logger.Info("New extension config line found -> starting new extension process: " + linestr); _extProcMgr.Execute(dir, ids ?? new string[0]); } } // anything left in the bag is no longer in the config file and needs to be shut down foreach (var item in bag) { _logger.Info("Existing extension process is no longer in the config file and will be shut down: " + item.Key); _extProcMgr.Stop(item.Value); } _logger.Info("Extensions list successfully updated from config file."); }