コード例 #1
0
        /// <summary>
        ///   This dispatcher wraps the dispatch of the remote call in a Task (by continuing on the Connect()) which allows the client to continue working asynchronously while the service is doing it's thing.
        /// </summary>
        /// <param name="binder"> </param>
        /// <param name="args"> </param>
        /// <param name="result"> </param>
        /// <returns> </returns>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            if (PackageManagerResponseImpl.EngineRestarting)
            {
                // don't send more calls until it's back.
                EngineServiceManager.WaitForStableMoment();
            }

            result = Connect().Continue(() => PerformCall(binder, args));
            return(true);
        }
コード例 #2
0
ファイル: CoAppService.cs プロジェクト: caoxk/coapp
        private static bool AutoInstallService(string path)
        {
            if (!File.Exists(path))
            {
                return(false);
            }

            var root = PackageManagerSettings.CoAppRootDirectory;
            var coappBinDirectory = Path.Combine(root, "bin");

            if (!Directory.Exists(coappBinDirectory))
            {
                Directory.CreateDirectory(coappBinDirectory);
            }
            var canonicalServiceExePath = Path.Combine(coappBinDirectory, "coapp.service.exe");

            if (Symlink.IsSymlink(path))
            {
                // we found a symlink,
                if (!File.Exists(Symlink.GetActualPath(path)))
                {
                    // it is invalid anyway. trash it, try again.
                    Symlink.DeleteSymlink(path);
                }
                return(false);
            }

            try {
                Symlink.MakeFileLink(canonicalServiceExePath, path);

                // hey we found one where it's supposed to be!
                var processStartInfo = new ProcessStartInfo(canonicalServiceExePath)
                {
                    Arguments       = "--start",
                    CreateNoWindow  = true,
                    WindowStyle     = ProcessWindowStyle.Hidden,
                    UseShellExecute = false,
                };

                var process = Process.Start(processStartInfo);
                process.WaitForExit();

                // after it exits, lets see if we've got an installed service
                if (EngineServiceManager.IsServiceInstalled)
                {
                    // YAY!. We're outta here!
                    EngineServiceManager.TryToStartService();
                    return(true);
                }
            } catch {
                // hmm. not working...
            }
            return(false);
        }
コード例 #3
0
        private Task Connect(string clientName = null, string sessionId = null)
        {
            lock (this) {
                _okToConnect.WaitOne();

                if (IsConnected)
                {
                    return("Completed".AsResultTask());
                }

                clientName = clientName ?? Process.GetCurrentProcess().Id.ToString();

                if (_connectingTask == null)
                {
                    _isBufferReady.Reset();

                    PackageManagerResponseImpl.EngineRestarting = false;
                    _connectingTask = Task.Factory.StartNew(() => {
                        EngineServiceManager.EnsureServiceIsResponding();

                        sessionId = sessionId ?? Process.GetCurrentProcess().Id.ToString() + "/" + _autoConnectionCount++;

                        for (int count = 0; count < 25; count++)
                        {
                            Logger.Message("Connecting...{0}", DateTime.Now.Ticks);
                            _pipe = new NamedPipeClientStream(".", PipeName, PipeDirection.InOut, PipeOptions.Asynchronous, TokenImpersonationLevel.Impersonation);
                            try {
                                _pipe.Connect(400);
                                _pipe.ReadMode = PipeTransmissionMode.Message;
                                break;
                            } catch {
                                // it's not connecting.
                                _pipe = null;
                            }
                        }

                        if (_pipe == null)
                        {
                            throw new CoAppException("Unable to connect to CoApp Service");
                        }

                        StartSession(clientName, sessionId);
                        Task.Factory.StartNew(ProcessMessages, TaskCreationOptions.None).AutoManage();
                    }, TaskCreationOptions.AttachedToParent);
                }
            }
            return(_connectingTask);
        }
コード例 #4
0
        private PackageManagerResponseImpl PerformCall(InvokeMemberBinder binder, object[] args)
        {
            using (var eventQueue = new ManualEventQueue()) {
                // create return message handler
                var responseHandler = new PackageManagerResponseImpl();
                CurrentTask.Events += new GetCurrentRequestId(() => "" + Task.CurrentId);
                // unhook the old one if it's there.
                responseHandler.Clear();

                // send OG message here!
                object callResult;
                base.TryInvokeMember(binder, args, out callResult);

                // will return when the final message comes thru.
                eventQueue.StillWorking = true;

                while (eventQueue.StillWorking && eventQueue.ResetEvent.WaitOne())
                {
                    eventQueue.ResetEvent.Reset();
                    while (eventQueue.Count > 0)
                    {
                        if (!Event <GetResponseDispatcher> .RaiseFirst().DispatchSynchronous(eventQueue.Dequeue()))
                        {
                            eventQueue.StillWorking = false;
                        }
                    }
                }

                if (PackageManagerResponseImpl.EngineRestarting)
                {
                    Logger.Message("Going to try and re issue the call.");
                    // Disconnect();
                    // the service is going to restart, let's call TryInvokeMember again.
                    EngineServiceManager.WaitForStableMoment();
                    Connect().Wait();
                    return(PerformCall(binder, args));
                }

                // this returns the final response back via the Task<*>
                return(responseHandler);
            }
        }
コード例 #5
0
ファイル: CoAppService.cs プロジェクト: caoxk/coapp
        public static int AutoInstall()
        {
            if (EngineServiceManager.IsServiceInstalled)
            {
                EngineServiceManager.TryToStartService();
                return(0);
            }

            var serviceExe = EngineServiceManager.CoAppServiceExecutablePath;

            if (serviceExe != null)
            {
                if (AutoInstallService(serviceExe))
                {
                    return(0);
                }
            }

            return(1);
        }
コード例 #6
0
        public void End()
        {
            if (!_ended)
            {
                _ended = true;

                // remove this session.
                lock (ActiveSessions) {
                    ActiveSessions.Remove(this);
                }

                if (!HasActiveSessions)
                {
                    Task.Factory.StartNew(() => {
                        Thread.Sleep(61 * 60 * 1000); // 11 minutes
                        if (!HasActiveSessions && DateTime.Now.Subtract(LastActivity) > new TimeSpan(0, 60, 0))
                        {
                            // no active sessions
                            // more than 60 minutes since last one.
                            // nighty-night!
                            EngineServiceManager.TryToStopService();
                            Logger.Message("Service getting sleepy. Going nighty-night");
                        }
                    });
                }

                Logger.Message("Ending Client: [{0}]-[{1}]".format(_clientId, _sessionId));

                // end any outstanding tasks as gracefully as we can.
                _cancellationTokenSource.Cancel();

                // drop all our local session data.
                _sessionData = null;

                // close and clean up the pipes.
                Disconnect();

                GC.Collect();
            }
        }
コード例 #7
0
        private int main(IEnumerable <string> args)
        {
            try {
                Environment.CurrentDirectory = Environment.GetEnvironmentVariable("tmp");
                var options    = args.Switches();
                var parameters = args.Parameters();

                Console.CancelKeyPress += (x, y) => {
                    Console.WriteLine("Stopping CoAppService.");
                    Engine.RequestStop();
                };

                #region Parse Options

                foreach (var arg in from arg in options.Keys select arg)
                {
                    var argumentParameters = options[arg];
                    switch (arg)
                    {
                    case "load-config":
                        break;

                    case "auto-install":
                        RequiresAdmin("--auto-install");
                        Environment.Exit(CoAppService.AutoInstall());
                        break;

                    case "start":
                        _start   = true;
                        _install = true;
                        break;

                    case "restart":
                        _stop    = true;
                        _start   = true;
                        _install = true;
                        break;

                    case "stop":
                        _stop = true;
                        break;

                    case "install":
                        _install = true;
                        break;

                    case "uninstall":
                        _stop      = true;
                        _uninstall = true;
                        break;

                    case "username":
                        UseUserAccount = true;
                        _username      = argumentParameters.LastOrDefault();
                        break;

                    case "password":
                        _password = argumentParameters.LastOrDefault();
                        break;

                    case "status":
                        _status = true;
                        break;

                    case "interactive":
                        if (EngineServiceManager.IsServiceRunning)
                        {
                            Console.WriteLine("Shutting down running assembly.");
                            EngineServiceManager.TryToStopService();

                            while (EngineServiceManager.IsServiceRunning)
                            {
                                Console.Write(".");
                                Thread.Sleep(100);
                            }
                        }
                        foreach (var proc in Process.GetProcessesByName("coapp.service").Where(each => each.Id != Process.GetCurrentProcess().Id).ToArray())
                        {
                            try {
                                Console.WriteLine("Killing Process... {0}", proc.Id);
                                proc.Kill();
                            } catch {
                            }
                        }

                        _interactive = true;
                        break;

                    case "help":
                        return(Help());

                    default:
                        Fail("Unrecognized switch [--{0}]", arg);
                        return(Help());
                    }
                }

                #endregion

                Logo();

                if (_interactive)
                {
                    RequiresAdmin("--interactive");
                    if (EngineServiceManager.IsServiceRunning)
                    {
                        throw new ConsoleException(
                                  "The CoApp Service can not be running.\r\nYou must stop it with --stop before using the service interactively.");
                    }
                    Console.WriteLine("Launching CoApp Service interactively.\r\nUse ctrl-c to stop.");

                    var task = Engine.Start(true);

                    Console.WriteLine("[CoApp Interactive -- Press escape to stop.]");

                    // wait for user to cancel task, or when it's actually closed
                    while (!task.Wait(1000))
                    {
                        Console.Write(".");
                        while (Console.KeyAvailable)
                        {
                            if (Console.ReadKey(true).Key == ConsoleKey.Escape)
                            {
                                Engine.RequestStop();
                            }
                        }
                    }
                    return(0);
                }

                if (_stop)
                {
                    RequiresAdmin("--stop");
                    Console.Write("Stopping service:");
                    if (EngineServiceManager.IsServiceInstalled)
                    {
                        EngineServiceManager.TryToStopService();
                    }

                    while (EngineServiceManager.IsServiceRunning)
                    {
                        Console.Write(".");
                        Thread.Sleep(100);
                    }
                    Console.WriteLine(" [Stopped]");
                }

                if (_uninstall)
                {
                    RequiresAdmin("--uninstall");
                    CoAppService.Uninstall();
                    return(0);
                }

                if (_install)
                {
                    RequiresAdmin("--install");
                    CoAppService.Install(_username, _password);
                }

                if (_start)
                {
                    RequiresAdmin("--start");

                    if (EngineServiceManager.IsServiceInstalled)
                    {
                        Console.Write("Starting service:");
                        EngineServiceManager.TryToStartService();

                        while (!EngineServiceManager.IsServiceRunning)
                        {
                            Console.Write(".");
                            Thread.Sleep(100);
                        }
                        Console.WriteLine(" [Started]");
                    }
                    else
                    {
                        throw new ConsoleException("CoApp.Service is not installed.");
                    }
                }

                if (!options.Any() && EngineServiceManager.IsServiceInstalled && parameters.FirstOrDefault() == null)
                {
                    // this lets us run the service
                    ServiceBase.Run(new CoAppService());
                    return(0);
                }

                if (_status)
                {
                    Console.WriteLine("Service installed: {0}", EngineServiceManager.IsServiceInstalled);
                    Console.WriteLine("Service running: {0}", EngineServiceManager.IsServiceRunning);
                    return(0);
                }

                if (!options.Any())
                {
                    throw new ConsoleException("Missing CoApp.Service command. Use --help for information");
                }
            } catch (ConsoleException e) {
                return(Fail(e.Message));
            } catch (Exception ex) {
                return(Fail("{0}\r\n{1}", ex.Message, ex.StackTrace));
            }
            return(0);
        }
コード例 #8
0
ファイル: Engine.cs プロジェクト: caoxk/coapp
        /// <summary>
        ///   Mains this instance.
        /// </summary>
        /// <remarks>
        /// </remarks>
        private Task Main()
        {
            if (IsRunning)
            {
                return(_engineTask);
            }
            Signals.EngineStartupStatus = 0;

            if (!IsInteractive)
            {
                EngineServiceManager.EnsureServiceAclsCorrect();
            }

            var npmi = PackageManagerImpl.Instance;

            _cancellationTokenSource = new CancellationTokenSource();
            _isRunning = true;

            Signals.StartingUp = true;
            // make sure coapp is properly set up.
            Task.Factory.StartNew(() => {
                try {
                    Logger.Warning("CoApp Startup Beginning------------------------------------------");

                    // this ensures that composition rules are run for toolkit.
                    Signals.EngineStartupStatus = 5;
                    EnsureCanonicalFoldersArePresent();
                    Signals.EngineStartupStatus = 10;
                    var v = Package.GetCurrentPackageVersion(CanonicalName.CoAppItself);
                    if (v > 0)
                    {
                        var p = InstalledPackageFeed.Instance.FindPackages(CanonicalName.CoAppItself).HighestPackages().FirstOrDefault();
                        if (p != null)
                        {
                            p.DoPackageComposition();
                            // put the coapp.exe symlink right into the OS directory. Yeah, evil, .... what are ya gonna do about that?
                            var coappexe = Path.Combine(p.PackageDirectory, "coapp.exe");
                            if (File.Exists(coappexe))
                            {
                                Symlink.MakeFileLink(Path.Combine(Environment.GetEnvironmentVariable("SYSTEMROOT") ?? "c:\\windows", "coapp.exe"), coappexe);
                            }
                        }
                    }
                    Signals.EngineStartupStatus = 95;
                    Logger.Warning("CoApp Version : " + v);

                    /*
                     * what can we do if the right version isn't here?
                     *
                     * FourPartVersion thisVersion = Assembly.GetExecutingAssembly().Version();
                     * if( thisVersion > v ) {
                     *
                     * }
                     * */

                    // Completes startup.

                    Signals.EngineStartupStatus = 100;
                    Signals.Available           = true;
                    Logger.Warning("CoApp Startup Finished------------------------------------------");
                } catch (Exception e) {
                    Logger.Error(e);
                    RequestStop();
                }
            });

            _engineTask = Task.Factory.StartNew(() => {
                _pipeSecurity = new PipeSecurity();
                _pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), PipeAccessRights.ReadWrite, AccessControlType.Allow));
                _pipeSecurity.AddAccessRule(new PipeAccessRule(WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow));

                // start a few listeners by default--each listener will also spawn a new empty one.
                StartListener();
                StartListener();
            }, _cancellationTokenSource.Token).AutoManage();

            _engineTask = _engineTask.ContinueWith(antecedent => {
                RequestStop();
                // ensure the sessions are all getting closed.
                Session.CancelAll();
                _engineTask = null;
            }, TaskContinuationOptions.AttachedToParent).AutoManage();
            return(_engineTask);
        }
コード例 #9
0
ファイル: Installer.cs プロジェクト: caoxk/coapp
        public Installer(string filename)
        {
            try {
                MsiFilename = filename;
                Quiet       = ((AppDomain.CurrentDomain.GetData("QUIET") as string) ?? "false").IsTrue();
                Passive     = ((AppDomain.CurrentDomain.GetData("PASSIVE") as string) ?? "false").IsTrue();
                Remove      = ((AppDomain.CurrentDomain.GetData("REMOVE") as string) ?? "false").IsTrue();

                Logger.Message("Quiet {0}/Passive {1}/Remove {2}", Quiet, Passive, Remove);

                // was coapp just installed by the bootstrapper?
                var tsk = Task.Factory.StartNew(() => {
                    if (((AppDomain.CurrentDomain.GetData("COAPP_INSTALLED") as string) ?? "false").IsTrue())
                    {
                        // we'd better make sure that the most recent version of the service is running.
                        EngineServiceManager.InstallAndStartService();
                        EnvironmentUtility.BroadcastChange();
                    }
                    bool wasCreated;
                    var ewhSec = new EventWaitHandleSecurity();
                    ewhSec.AddAccessRule(new EventWaitHandleAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), EventWaitHandleRights.FullControl, AccessControlType.Allow));
                    _ping = new EventWaitHandle(false, EventResetMode.ManualReset, "BootstrapperPing", out wasCreated, ewhSec);
                });

                // force the explorer process to pick up changes to the environment.
                EnvironmentUtility.BroadcastChange();

                var ts2 = tsk.Continue(() => {
                    // gets the package data for the likely suspects.
                    _packageManager.AddSessionFeed(Path.GetDirectoryName(Path.GetFullPath(MsiFilename))).Continue(() => {
                        _packageManager.GetPackageFromFile(Path.GetFullPath(MsiFilename)).Continue(pkg =>
                                                                                                   Task.WaitAll(new[] { pkg.InstalledNewest, pkg.AvailableNewestUpdate, pkg.AvailableNewestUpgrade }
                                                                                                                .Select(each => each != null ? _packageManager.GetPackage(each.CanonicalName, true)
                                                                                                                        .Continue(() => { _packageManager.GetPackageDetails(each.CanonicalName); })
                                : "".AsResultTask())
                                                                                                                .UnionSingleItem(_packageManager.GetPackageDetails(pkg).Continue(() => { PrimaryPackage = pkg; }))
                                                                                                                .ToArray()));
                    });
                });

                tsk.ContinueOnFail(error => {
                    DoError(InstallerFailureState.FailedToGetPackageFromFile, error);
                    ExitQuick();
                });

                try {
                    Application.ResourceAssembly = Assembly.GetExecutingAssembly();
                } catch {
                }

                ts2.Wait();

                if (!Quiet)
                {
                    _window = new InstallerMainWindow(this);
                    if (Remove)
                    {
                        _window.Loaded += (sender, args) => _window.RemoveButtonClick(sender, args);
                    }
                    else if (Passive)
                    {
                        _window.Loaded += (sender, args) => _window.InstallButtonClick(sender, args);
                    }

                    _window.ShowDialog();

                    if (Application.Current != null)
                    {
                        Application.Current.Shutdown(0);
                    }
                }
                else
                {
                    // when quiet
                    var discard  = RemoveChoices.ToArray();
                    var discard2 = InstallChoices.ToArray();

                    if (Remove)
                    {
                        if (CanRemove)
                        {
                            RemoveAll().Wait();
                        }
                    }
                    else
                    {
                        Logger.Message("Thinkin' about installin' {0}", CanInstall);
                        Debugger.Break();
                        if (CanInstall)
                        {
                            Install().Wait();
                        }
                    }
                }
                ExitQuick();
            }
            catch (Exception e) {
                DoError(InstallerFailureState.FailedToGetPackageDetails, e);
            }
        }