C# 在同一进程中使用Windows窗体的Windows服务
我有一个c#应用程序,它作为windows服务运行,控制套接字连接和其他东西。 此外,还有另一个windows窗体应用程序来控制和配置此服务(带启动、停止、带配置参数的显示窗体的systray) 我正在使用.net远程处理来完成IPC,这很好,但现在我想显示一些真实的流量和其他报告,远程处理将无法满足我的性能要求。因此,我想将这两个应用程序合并到一个应用程序中 问题是: 当我从windows服务启动表单时,什么都没有发生。通过谷歌搜索,我发现我必须右键单击该服务,登录并选中“允许服务与桌面交互”选项。因为我不想让我的用户这么做,所以在安装期间,我又在谷歌上搜索了一些代码,在用户的regedit中设置了这个选项。问题是,即使设置此选项,它也不起作用。我必须打开服务的登录选项(已选中),取消选中,然后再次选中 那么,如何解决这个问题呢?如何让任何登录用户都能在同一进程中使用带有systray控件的windows服务,这是最好的方法?C# 在同一进程中使用Windows窗体的Windows服务,c#,windows,windows-services,C#,Windows,Windows Services,我有一个c#应用程序,它作为windows服务运行,控制套接字连接和其他东西。 此外,还有另一个windows窗体应用程序来控制和配置此服务(带启动、停止、带配置参数的显示窗体的systray) 我正在使用.net远程处理来完成IPC,这很好,但现在我想显示一些真实的流量和其他报告,远程处理将无法满足我的性能要求。因此,我想将这两个应用程序合并到一个应用程序中 问题是: 当我从windows服务启动表单时,什么都没有发生。通过谷歌搜索,我发现我必须右键单击该服务,登录并选中“允许服务与桌面交互”
更新:谢谢你们的评论,伙计们。我同意使用IPC更好,我知道混合使用windows服务和用户界面是不好的。尽管如此,我还是想知道如何做到这一点。两个独立的进程使用您选择的技术进行通信。带有UI的服务是一个坏主意。不要走这条路,你会后悔的
通过一个简单的套接字连接进行服务通信,我取得了很好的效果-很好地记录您的服务协议,使其尽可能简单,这将比您想象的更容易。实际上,您不应该将您的服务与管理UI结合起来。我同意Greg的观点。也许您可以研究一种不同的IPC机制。也许使用套接字和您自己的协议。或者,如果您的服务控制应用程序只能控制本地计算机上的服务,您可以使用命名管道(甚至更快)。非常简单-您需要为执行应用程序事件创建一个线程。 像这样(C++源代码CLR,但是你可以用C语言做这个): 并在main中创建线程
int main(array<System::String ^> ^args)
{
bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");
if (bService)
{
System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
thread->Start();
ServiceBase::Run(gcnew simpleWinService());
Application::Exit();
}
else
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew TMainForm());
}
return 0;
}
int main(数组^args)
{
bool bService=RunaService(L“SimpleService with IConTrayandWindow”);
如果(b服务)
{
System::Threading::Thread^Thread=gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
线程->开始();
ServiceBase::Run(gcnewsimplewinservice());
Application::Exit();
}
其他的
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
//创建主窗口并运行它
应用程序::运行(gcnew tmaninform());
}
返回0;
}
交互式服务的主要问题是:
- 安全性—其他进程可以通过其消息泵向其发送消息,从而获得对系统/本地进程的访问权
- 不完整性-交互式服务从未看到外壳消息,因此无法与通知区域图标交互
我们经常使用TCP和UDP连接将信息从服务传递到其他EXE,在某些情况下,还有MSMQ。这里有一种将服务和表单混合的方法
我从(单击“方法”表中的“更改”链接)了解了如何执行此操作
我有几个步骤的解决方案,这是计划
我完全同意这一点。如果可能的话,我会考虑一些沟通
int main(array<System::String ^> ^args)
{
bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");
if (bService)
{
System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
thread->Start();
ServiceBase::Run(gcnew simpleWinService());
Application::Exit();
}
else
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew TMainForm());
}
return 0;
}
string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'";
using (ManagementObject service = new ManagementObject(wmiPath))
{
object[] parameters = new object[11];
parameters[5] = true; // Enable desktop interaction
service.InvokeMethod("Change", parameters);
}