【问题标题】:Execute a command line from a service's Execute thread从服务的执行线程执行命令行
【发布时间】:2011-11-23 16:19:03
【问题描述】:

乍一看我没有运气

uses ShellApi;

...

ShellExecute(Handle, pchar('open'), pchar('emf2pdf.exe'), 
             pchar(s), pchar(root), SW_SHOWNORMAL);

其中s为参数字符串,root为命令所在目录。

我得到的错误是“缺少运算符或分号”,还有“实际参数太多”。

可能是我忽略了一些简单的事情,有点压力。甚至不知道从哪里获得句柄。

对于您可以建议的执行命令行的替代方法感到高兴!基本上,该服务会定期查找要转换的文件,所以我只是在寻找一种在 DOS 中形成命令行并执行它的方法,最好不要短暂弹出并关闭窗口,但我会采取什么我可以得到。 :)

我正确安装的 Delphi 可以为我提示参数,但在按 F1 时不会弹出帮助页面(未在索引中找到)。

更新:使用了 DelphiPages 中的 CreateProcess 函数:

Function ExecuteAndWait(sExecutableFile : String; wWindowState : Word = SW_SHOWNORMAL) : Boolean;
var
siInfo : TStartUpInfo;
piInfo : TProcessInformation;
begin
    FillChar(siInfo, SizeOf(siInfo), #0);

    with siInfo do begin
    cb := SizeOf(siInfo);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := wWindowState;
    end;
    Result := CreateProcess(NIL, pChar(sExecutableFile), NIL, NIL, FALSE, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, NIL, pchar(ExtractFilePath(sExecutableFile)),siInfo, piInfo);
    if Result then
    WaitForSingleObject(piInfo.hprocess,INFINITE);
end;

然后用这个命令行调用它,它在粘贴到 'cmd' 时有效,但不能用这段代码:

ExecuteAndWait('D:\EMF2PDF\emf2pdf.exe -append 0 -margin 36x36x36x36 -width 595 -height 420 "D:\EMF2PDF\EMF\example.emf" "D:\EMF2PDF\PDF\example.pdf"');

如果您能提供(链接到)上面控制台应用命令行的工作示例调用(在服务中),我会很高兴。

更新: 有问题的命令不会打开任何窗口,但会在控制台中输入转换的统计信息。我用的软件可以在这里下载:http://www.verydoc.com/emf-to-pdf.html

此外,我直到现在才被告知所讨论的服务器是虚拟服务器,如果这会有所不同的话。

刚刚检查过,当我试用我的服务时,我以远程会话用户身份登录。当 Windows 以登录用户运行时,该服务是否至少能够创建一个调用 emf2pdf 的进程?

如果您能想到在此服务器上(例如批处理用户)在这些条件下或其他情况下使用 Verydoc 软件的替代解决方案,我很乐意尝试!

【问题讨论】:

  • 1.您是否尝试过标准应用程序?那里会发生什么?在它可以从标准应用程序中运行之前,不要尝试从服务中调试它。 2.s有什么价值,root有什么价值? 3. 你在用什么操作系统。如果您使用的是 Vista 或更高版本,则无需担心服务会出现任何 Windows。
  • 1.这在普通应用程序中运行良好,但是粘贴到 Execute 线程中的相同代码行甚至无法如上所述编译。 2. s=misc 特定于 emf2pdf 命令的开关,root='D:\EMF2PDF'。 3. Windows Server 2008 R2 标准版,64 位。
  • 有些事情我不清楚。您调用CreateProcess 的服务是否在系统帐户下运行?您想在某个用户的桌面上运行emf2pdf.exe。你如何识别用户?例如可以使用模拟它吗?您知道哪些信息可以识别用户的会话?另一个问题:您想让进程emf2pdf.exe 在服务凭据下还是在用户凭据下运行?
  • 不,我不想想要在某些用户的桌面上运行它。但似乎有必要?因为 Windows 中没有合适的 shell。至于凭据,它只需要将文件读/写到一个临时文件夹。该服务在本地系统帐户下运行,此虚拟服务器上的任何用户都会收到通知(来自“桌面 0”?)

标签: windows delphi winapi service delphi-7


【解决方案1】:

服务在另一个会话中运行,因此在另一个 win 站内运行,因此您不能使用 ShellExecute,因为服务 win 站根本没有 shell;可能没有登录用户等。唯一但它是一项交互式服务,但在较新的 Windows 版本(如果我没记错的话,从 Vista 及更高版本)不再支持这些服务。

正如大卫在下面的评论中提到的那样:应该可以使用以下方法启动进程:

ShellExecute(0, 'open', 'sleep.exe', '60', '', SW_HIDE);

我使用不同的程序对其进行了测试,但它失败了,因此它可能取决于您希望启动的应用程序,所以显然这个答案是不正确的。它仍然提供了一些洞察信息,所以除非有人问我,否则我将把它留在这里。

【讨论】:

  • 我不知道。我必须承认我有点惊讶。您应该建议使用 CreateProcess 的替代方法。
  • 其实这个答案是不正确的。完全可以从会话 0 隔离服务调用 ShellExecute。我刚刚这样做了。当然,如果有问题的应用程序尝试显示 UI,那么就会出现问题。但是,就其本身而言,没有什么可以阻止您从服务中使用 ShellExecute
  • @David:调用本身并非不可能,但是如果没有任何附加代码,它不会启动可执行文件。我不认为不提及 CreateProcess 会使答案不正确,尽管可能不够完整。您是否有链接或其他内容来支持您在上述评论中的主张?我很想看看您如何让应用程序从服务中正确运行,而无需求助于整个系统调用来正确设置进程。
  • 不正确的是您声明不能从服务中使用 ShellExecute。我刚刚从ServiceStart 做了一个香草德尔福服务应用程序的ShellExecute(0, 'open', 'sleep.exe', '60', '', SW_HIDE);sleep.exe 是一个简单的 Delphi 控制台应用程序,它调用 Windows.Sleep
  • @David:我很惊讶,我做到了,但它失败了(没有创建进程或至少在 Process Explorer 中不可见),可能取决于启动的进程。
【解决方案2】:

您对问题的更新报告称,从标准应用程序运行时调用 CreateProcess 有效,但从服务运行时失败。该问题肯定与会话 0 服务隔离有关。有了这些信息,我可以想到以下解释:

  1. 在服务上下文中,D:\EMF2PDF\... 路径不可用。检查您是否可以在此处创建并打开一个文本文件,以查看此诊断是否正确。
  2. Session 0 隔离只是与emf2pdf 程序不兼容。如果是这样,那么您将需要找到另一个程序来进行转换。这可能很难做到,因为处理 EMF 的程序可能会使用 GDI 命令,并且它们很可能在服务上下文中失败。

到目前为止,最简单的解决方案是将此进程作为标准应用程序运行。我可以看到,对于看似服务器服务的东西来说,这可能不是一个可口的前景。

【讨论】:

  • 1.这是可行的,因为我从中剪切传递给 CreateProcess 的完整命令行的日志文件在那里写得很好。 2. 你的意思是我可以编写一个标准的 Delphi 应用程序(使用 f.ex. ShellExecute 调用 emf2pdf)并使用服务中的参数调用它?我可以使用另一个“中介”,例如编写一个 .bat 文件并使用 CreateProcess 从服务中调用它吗? DETACH_PROCESS 和 CREATE_NEW_PROCESS 标志呢?
  • 在这种情况下,我敢打赌 2 是障碍。
  • 太快了!意外 Enter 按下,添加评论到 2.
  • 我相信您的问题是您无法在会话 0 内运行 emf2pdf。您需要 A) 放弃使用服务,或 B) 找到在会话 0 中工作的转换器或C) 在交互式会话中启动该过程。 C) 可能不是一个很好的选择,因为在服务器操作系统上,您通常没有交互式会话。即使你可以走这条路,也很难做到:blogs.msdn.com/b/winsdk/archive/2009/07/14/…
【解决方案3】:

我们在这里遇到了完全相同的问题。我们还使用命令行工具生成 PDF。

如果您在服务对话框中查看服务的属性,您会在“登录”标签页上看到一个复选框。该复选框的标题为“允许服务与桌面交互”。将此设置为选中。

这里的一个答案表明这在较新的 Windows 版本上不再可能,但它在 Windows 7 和 Windows 2008 服务器上运行良好。

编辑:服务属性中的设置可能改变了它的含义,我不知道。但它解决了我们的问题。选中此复选框后,我们用于生成 PDF 的命令行工具运行良好。

【讨论】:

  • 太好了,因为我的电话肯定有​​问题。您为 CreateProcess 使用了哪些参数?我可以从命令提示符/控制台很好地运行转换命令行,在服务尝试这样做几秒钟后,什么也没发生。
  • “这里的答案之一表明这在较新的 Windows 版本上不再可能,但它在 Windows 7 和 Windows 2008 服务器上运行良好。”我不同意。
  • 我对 Vista 及更高版本的设置的理解是,它允许服务与会话 0 中的隐藏桌面进行交互。因此,该设置不再像 XP 中所做的那样,而是允许服务与之交互登录用户的桌面。这就是说它在Vista中不起作用的意思。也就是说,它可以解决手头的问题。
  • 让它与 ShellExecuteEx 一起工作...现在,如何使交互式服务检测易于管理? :) SW_HIDE...可能吗?
猜你喜欢
  • 2017-08-15
  • 1970-01-01
  • 2015-01-11
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 2011-05-05
相关资源
最近更新 更多