Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当客户端登录时,如何在服务器上的网络服务帐户中触发服务?_C#_Triggers_Windows Services_Network Service - Fatal编程技术网

C# 当客户端登录时,如何在服务器上的网络服务帐户中触发服务?

C# 当客户端登录时,如何在服务器上的网络服务帐户中触发服务?,c#,triggers,windows-services,network-service,C#,Triggers,Windows Services,Network Service,我们有一个现有系统,其中启用网络服务的windows服务托管在服务器上的网络服务帐户上。每个客户机上都安装了windows服务,一旦用户通过每个客户机登录,这些服务就会自动启动,并且客户机上的这些服务会触发服务器上的服务,告知服务器,例如客户机a已登录 我要做的是创建一个网络服务并将其托管在服务器上,然后直接触发它,而无需在每个客户端上安装单独的windows服务。可能吗?我希望每个客户机使用现有的网络服务,并在登录时通知其已联机。有点像是在服务器上随时间维护一个用户登录日志。我使用了。下面是我

我们有一个现有系统,其中启用网络服务的windows服务托管在服务器上的网络服务帐户上。每个客户机上都安装了windows服务,一旦用户通过每个客户机登录,这些服务就会自动启动,并且客户机上的这些服务会触发服务器上的服务,告知服务器,例如客户机a已登录

我要做的是创建一个网络服务并将其托管在服务器上,然后直接触发它,而无需在每个客户端上安装单独的windows服务。可能吗?我希望每个客户机使用现有的网络服务,并在登录时通知其已联机。有点像是在服务器上随时间维护一个用户登录日志。

我使用了。下面是我在WPF客户端上使用的代码片段

public static async Task ToggleServiceStatus(this EdiServiceInfo serviceInfo)
        {
            await Task.Factory.StartNew(() =>
            {
                using (
                    Impersonation.LogonUser(serviceInfo.Domain, serviceInfo.User, serviceInfo.Pswd,
                        Environment.MachineName.Equals(serviceInfo.ComputerName,
                            StringComparison.InvariantCultureIgnoreCase)
                            ? LogonType.Network
                            : LogonType.Interactive))
                {
                    var service = new ServiceController(serviceInfo.ServiceName, serviceInfo.ComputerName);
                    if (service.Status == ServiceControllerStatus.Stopped)
                    {
                        service.Start();
                        service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(60));
                    }
                    else
                    {
                        service.Stop();
                        service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(60));
                    }
                }
            });
        }
如果您想从客户端触发服务,这很有用。但是,如果服务已经在工作并且只想响应登录,那么您可以维护一个带有DidLoggedIn标志的客户机表,并且您的windows服务应该有一个长时间运行的任务来监视此标志。这里的想法是,每当客户端登录时,您都会将标志设置为true,并且在服务器端,windows服务的长时间运行任务将检测到这一点,并且会执行您希望它执行的任何操作

希望能有帮助

编辑>>>我有一个这样做的应用程序。让我分享一些片段

public virtual async Task InitAsync()
        {
            EdiDataAccess.ResetServiceFlags();
            EdiDataAccess.SetServiceAsWorking();
            var startMonitorTask = new Func<Task>(StartAllWorkersAsync)
                .CyclicalTask(TimeSpan.FromSeconds(MonitorSeconds), MonitorCancellationToken);
            var stopMonitorTask = new Func<Task>(StopRequestsMonitor)
                .CyclicalTask(TimeSpan.FromSeconds(MonitorSeconds), MonitorCancellationToken);
            await TaskEx.WhenAll(startMonitorTask, stopMonitorTask);
        }
其中EdiDataAccess.GetEdiCostumersToStart()检索所有请求登录的客户


“我的窗口”服务可以检测到客户何时请求开始会话。

好的,我正在了解您在那里做的事情。所以基本上,我必须在每个客户机上添加代码片段或可能的程序,才能实现这一点?我真正想要的是消除通过客户端上的服务/程序触发网络服务的开销。服务器上的网络服务应该能够检测特定客户端的登录,并将其信息保存在服务器上的日志文件中。我不想为此配置每个客户端,否则我会在所有客户端上安装一个服务,而不会为此而烦恼。当你说客户端时,你指的是像WPF或WindowsForms这样的客户端应用程序吗?不,我指的是使用服务器信息的客户端,即连接到网络服务器的一系列计算机。可能是这个问题可以帮助您PsLoggedOn v1.34有一些功能可以帮助您。您只需包装shell即可将输出重定向到windows服务
public static Task CyclicalTask(this Func<Task> task, TimeSpan waitTimeSpan,
            CancellationToken token = default(CancellationToken))
        {
            return TaskEx.Run(async () =>
            {
                while (true)
                {
                    token.ThrowIfCancellationRequested();
                    await task();
                    token.WaitHandle.WaitOne(waitTimeSpan);
                }
            }, token);
        }
protected virtual async Task StartAllWorkersAsync()
        {
            var ediCustomersToStart = EdiDataAccess.GetEdiCostumersToStart();
            var ediTasks = ediCustomersToStart
                .Select(StartWorkerAsync)
                .ToList();
            await TaskEx.WhenAll(ediTasks);
        }