将 Windows Forms 应用程序作为服务运行?

6
我有一个Windows Forms应用程序,它监控收件箱和数据库。客户告诉我需要在服务器重新启动时运行该应用程序。对不起,让客户改变需求是我的错。
我在想...是否有办法将Windows Forms应用程序作为服务运行,以便它可以自动启动?
澄清:如果可能的话,我希望尽量不编写更多代码!
8个回答

9

这个答案已经过时,因为链接的文章在2012年被删除。然而,StackOverflow不允许删除被接受的答案。所以,请不要给这个答案投反对票,因为我已经告诉你它已经过时了。

备用链接: https://web.archive.org/web/20111221041348/http://www.codeproject.com/kb/system/xyntservice.aspx

C++源代码(或使用该文章上的Browse Code选项卡):https://web.archive.org/web/20111228050501/http://www.codeproject.com/KB/system/xyntservice.aspx

不幸的是,Zip文件源代码下载在备用链接中无法使用。

从NT服务启动Windows程序

看看这篇文章:http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=719&av=49654

虽然这是一篇很旧的文章,但它已经运行了8年,并且作者一直在更新。它可以做你想要的事情。


我找到了类似的东西,它附带于Windows资源工具包中...http://support.microsoft.com/kb/137890 - mattruma
这怎么又变成1票了?我几个小时前给它投了2票,而且我也看不出任何贬低它的理由。 - Stephen Martin
2
该链接的文章已不再提供。 - RMuesi
1
你仍然可以在 WayBack 机器上找到这篇文章:https://web.archive.org/web/20111228050501/http://www.codeproject.com/KB/system/xyntservice.aspx - Claudio Nastasi Junior
很遗憾,WayBack机器链接上的Zip文件源代码下载无法使用,但是可以浏览源文件CPP。 - EnocNRoll - AnandaGopal Pardue
显示剩余2条评论

5
如果您确定应用程序可以安全地无人值守运行(这意味着它绝对不会弹出模态UI元素,如消息框),并且在关闭之前不需要任何交互,只需终止它,则将其作为定时任务运行,并将触发器设置为系统启动。
如果它可以无人值守运行,但可能需要手动关闭和重新启动,或者不能在关闭时仅被终止,则使用XYNTService,正如EnocNRoll所推荐的那样。这是一个可怕的hack,但它可以实现您想要的功能。
但是,远离最佳解决方案是将程序的功能与用户界面分离,并编写正确的服务。对于生产服务器,我不会允许其他任何东西。如果难以分离,则应该查看一些设计问题。

我在这里假设MattRuma只是想快速实现这一点。否则,我完全同意。然而,在某些东西投入生产后,要按正确的方式做事往往是一个难以战胜的挑战。 - EnocNRoll - AnandaGopal Pardue
是的...我正在寻找快速而简单的方法...我没有时间或奢侈条件来做得很好...至少现在不行。 - mattruma
是的,我知道那种感觉。你可以使用XYNTService或任务计划程序,但一定要非常仔细地检查你的应用程序,以避免任何可能的未经监控的UI问题。 - Stephen Martin

1

你可以将WinForms应用程序作为服务运行,但你将无法看到它--它将显示在所谓的虚拟桌面上,这个桌面无法在你的监视器上查看。


这就是我想要做的。 - mattruma
好的,很酷,那么在没有登录上下文的情况下启动UI线程就没有问题了吗?太好了!那么迄今为止发布的两篇文章中的任何一篇理论上都应该可以使用。 - EnocNRoll - AnandaGopal Pardue

1
您可能还想考虑AlwaysUp,这是一款商业应用程序,可以将任何应用程序作为Windows服务运行。它类似于EnocNRoll提到的XYNTService,但具有更多功能并得到全面支持。
祝您好运!

0
唯一考虑这个的方法是确保应用程序没有任何UI元素,因为在非Vista机器上必须跳过许多麻烦才能使其工作,在Vista上则根本无法与桌面交互。
相反,您最好将功能重构为一组共享库,然后创建一个使用这些库的服务,并将其安装在客户端。

哦,所以没有办法进入Windows服务并让它像服务一样运行我的应用程序吗? - mattruma
1
不,一个服务需要一个派生自ServiceBase类的类和一个ServiceInstaller类来安装在Windows服务中。 - Ricardo Villamil

0

您可以使用InstallUtil将您的应用程序安装为服务,但您需要确保它不依赖于GUI,并且我建议您更改应用程序的启动方式,以便它不会尝试创建任何窗体。


要使用InstallUtil,您需要一个派生自Installer的类,还需要在您的安装程序类中定义ServiceProcessInstaller()和ServiceInstaller()对象。 InstallUtil在您的exe项目中查找这些对象。 - Ricardo Villamil
也许我想的不是InstallUtil。我已经使用命令行工具多次将“普通”应用程序安装为服务了。SC 有点印象。 - Steven Robbins

0
如果您的表单应用程序中有一个良好的解耦功能,那么创建一个带有安装程序的服务类并在服务的OnStart方法中启动处理器类应该是很简单的。
    protected override void OnStart(string[] args)
    {
                    Processor processor = new Processor();
        Thread workerThread = new Thread(processor.OnStart);
        workerThread.IsBackground = true;

        try
        {
            workerThread.Start();
        }
        catch
        {
                      //...
        }
    }

-1
发现了这篇文章,名为如何创建用户定义服务

应该可以运行,但似乎不是一个很可靠的解决方案。我贴出来的链接提供了一种更简洁的方法。 - EnocNRoll - AnandaGopal Pardue
EnocNRoll是正确的!不要使用那篇文章中的东西。它早已过时,提供的实际价值很少。 - Stephen Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接