Windows服务与Windows窗体在相同的过程中

我有ac#应用程序作为一个Windows服务控制套接字连接和其他东西运行。 此外,还有另一个Windows窗体应用程序来控制和configuration此服务(系统启动,停止,与configuration参数显示表单)。

我使用.net远程做IPC,这很好,但现在我想显示一些真正的stream量和其他报告和远程处理将不符合我的性能要求。 所以我想把两个应用程序结合在一起。

这是问题:

当我从Windows服务启动窗体时,什么都没有发生。 谷歌search我发现,我必须右键点击该服务,去login和检查“允许服务与桌面交互”选项。 由于我不想问我的用户这样做,我有一些代码再次谷歌search在安装时在用户的registry中设置此选项。 问题是,即使设置这个选项,它不起作用。 我必须打开服务的login选项(它被选中),取消选中并再次检查。

那么,如何解决呢? 如何在同一个进程中拥有一个带有系统托pipe的Windows服务的最佳方式,可供任何用户login?

更新:感谢迄今为止的意见,伙计们。 我同意使用IPC更好,我知道混合windows服务和用户界面是不好的。 即使如此,我想知道如何做到这一点。

Solutions Collecting From Web of "Windows服务与Windows窗体在相同的过程中"

两个独立的流程使用您选择的技术进行交流。 使用UI的服务是一个坏主意 。 不要走这条路 – 你会后悔的。

通过一个简单的套接字连接,我得到了非常好的服务交流 – 良好地记录您的服务协议,尽可能简单,并且比您想象的要容易。

在实践中,您不应该将您的服务与管理界面连接起来。

我同意格雷格。 也许你可以研究一个不同的IPC机制。 也许使用套接字和你自己的协议。 或者,如果您的服务控制应用程序只能控制本地计算机上的服务,则可以使用命名管道(甚至更快)。

这是混合服务和表单的一种方式

http://www.codeproject.com/KB/system/SystemTrayIconInSvc.aspx

我想通过这篇文章 (点击“方法”表格中的“更改”链接)做到这一点 。

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); } 

我有几个步骤的解决方案,这是计划

  1. 我们不打算用windows窗体创建一个服务项目,而是创建一个包含windows服务项目,一个windows窗体项目和一个安装项目的visual studio解决方案。

  2. 这个想法是有一个数据库或文件或任何你喜欢存储的数据,你将在其中存储你的Windows服务将始终用来运行的参数。 所以你的Windows服务和Windows窗体应用程序应该能够修改和检索它的数据。

  3. 在Windows应用程序的主窗体上,在窗体上拖放一个NotifyIcon,在属性选项卡中,浏览并选择一个.ico图像(您可以在Visual Studio中创建一个,但这是您可以在Google上获得的另一个主题或与我联系)当您运行应用程序并且主窗体处于活动状态或显示状态时,它将显示在系统托盘中,请尝试运行该应用程序。

  4. 在解决方案的安装项目中添加它们作为输出。 要将项目添加到安装项目,他们必须在相同的解决方案中。 右键单击解决方案资源管理器中的安装项目,突出显示添加,然后选择项目输出,添加Windows服务和Windows窗体输出,您将在安装项目下的解决方案资源管理器中看到它们。

  5. 添加一个Windows服务比这更进一步,但这也是谷歌的另一个话题

  6. 创建Windows应用程序的快捷方式,并将其添加到启动文件夹也是谷歌或与我联系的另一个话题。

    注意以这样一种方式编程你的表单,关闭按钮不显示,表单变为Me.visible = false,双击系统托盘中的图标是设置me.visible = true的唯一方法。随时电脑启动,你的Windows窗体应用程序也启动,可见立即设置为false,但由于它有一个图标图像notifyicon,它会显示在系统托盘中,双击它使窗体可见编辑设置,你正在为服务存储,服务也会自动启动,因为您将在设置项目中设置服务。 我的邮件是iamjavademon@gmail.com更好的插图使用屏幕截图并全面解释

这非常简单 – 您需要为执行应用程序事件创建一个线程。 像这样(CLR的C ++源代码,但你可以在C#中做到这一点):

 ref class RunWindow{ public: static void MakeWindow(Object^ data) { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew TMainForm()); }; }; 

并在主要创建线程

 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; } 

互动服务的主要问题是:

  • 安全性 – 其他进程可以通过消息泵发送消息,从而获得进入SYSTEM / LOCAL进程的权限。

  • 不完整性 – 交互式服务从不会看到shell消息,因此无法与“通知区域”图标进行交互。

我们经常使用TCP和UDP连接将信息从服务传递到其他exes,在某些情况下,还可以使用MSMQ。