1

我有一个应用程序,用户可以以两种不同的方式启动,作为普通应用程序或作为 Windows 服务。当服务已经运行时(系统托盘中有一个图标)并且用户尝试启动应用程序(不仅仅是通过单击托盘图标打开,而是再次单击开始>应用程序>等等),它说:“应用程序已经作为服务运行,您要关闭服务并启动应用程序吗? ” 当用户单击“是”时,应用程序将关闭服务并作为普通应用程序启动自身。

发生这种情况时,我放置了一个标志,表明用户曾经停止过服务,并且当他们关闭应用程序时,软件会看到该标志并且服务必须重新开始运行,因为它在作为普通应用程序启动之前已关闭。

我试着说:

WinExec(PChar('NET START MyApplicationName'),SW_shownormal);

OnClose事件中,在此行之前:

ExitProcess(0);

但它说该服务已经在运行并关闭应用程序而不启动该服务,如果我把它放在该行之后,它根本不会做任何事情。
有没有办法做到这一点?

当我在它之前放置该行时,ExitProcess(0);它会打开一个带有以下消息的 cmd 窗口:

“服务没有响应控制功能”

然后它关闭应用程序,关闭 cmd 窗口并且它不启动服务。

4

2 回答 2

7

在我看来,您使问题过于复杂。启动和停止服务是一项复杂的操作,而且对于非管理员用户来说,默认情况下是禁止的。这一事实将使您的应用程序使用起来非常烦人。您将限制其对管理员用户的使用,并且还使用 UAC 对话框对他们进行装饰。没有人喜欢这样的应用程序。

另一种方法是让您的服务一直运行,但在标准桌面应用程序运行时使其处于非活动状态。当桌面应用程序启动时,它会使用某种形式的 IPC 与服务进行通信,并要求服务停止工作。该服务执行此操作,然后桌面应用程序继续执行。当桌面应用程序关闭时,会要求该服务恢复工作。您可能希望始终保持通信通道打开,以防止桌面应用程序异常终止——如果发生这种情况,服务将简单地重新启动。

现在,如果你真的想把工作做好,你可以让所有的工作处理总是发生在服务中。桌面应用程序只是服务的前端。在我看来,这似乎是这个应用程序最有效和最合乎逻辑的设计。

于 2012-05-23T13:34:02.063 回答
0

像这样写一个简单的批处理文件

@ECHO OFF
ping 1.1.1.1 -n 1 -w 10000 > NUL
NET START MyApplicationName

然后在关闭程序之前运行执行此批处理文件。

ShellExecute(0, 'Open', YourBatchFile, nil, nil, SW_HIDE)
于 2012-05-23T12:45:41.903 回答