【问题标题】:C# console app using Interop.domino.dll - failing when running as Scheduled Task使用 Interop.domino.dll 的 C# 控制台应用程序 - 作为计划任务运行时失败
【发布时间】:2012-04-20 04:11:43
【问题描述】:

我编写了一个 C# 控制台应用程序,它使用 Interop.domino.dll 程序集与 domino/notes 交互以创建、更新和删除文档。当通过 cmd 提示符或通过 Visual Studio 手动运行应用程序时,应用程序运行成功。但是,当我们尝试将应用程序设置为计划任务(在域服务帐户下运行)时,它会失败并出现以下错误:

  • System.Runtime.InteropServices.COMException:检索具有 CLSID {29131539-2EED-1069-BF5D-00DD011186B7} 的组件的 COM 类工厂失败,原因如下 错误:80004005 未指定的错误(HRESULT 异常:0x80004005 (E_FAIL))。

一旦我们尝试使用 Interop.domino.dll 中的对象,特别是尝试按照以下方式创建 NotesSession 对象的实例时,就会发生错误:

  • ISession notesSession = new NotesSession();

经过一番调查,我发现互操作程序集需要一个桌面才能与之交互,并且如果我们使用登录到计算机的服务帐户运行计划任务,那么计划任务上运行的计划将成功运行。以服务帐户登录时,您可以看到应用程序在运行时会弹出一个 svchost.exe 窗口,这就是它需要桌面的原因。

但是,让服务帐户一直登录到计算机不是一个可接受的解决方案,因为这意味着每次服务器重新启动时都必须重新登录该帐户。允许服务帐户登录机器也存在一些安全问题。

所以,我想知道是否有人对如何解决这个问题有任何建议?有没有办法抑制程序集试图显示的任何 UI?或者,任何人都可以建议一个可以达到类似结果的计划任务的替代方案。我们需要做的是:

  • 让应用程序以设定的时间间隔运行(IE - 每天一次/每小时一次)
  • 理想情况下,让它在域服务帐户(而不是本地系统帐户)下运行
  • 运行时无需将服务帐户登录到计算机/来自 Interop.domino.dll 的 UI 元素被抑制

我们考虑过使用notes Web 服务而不是Interop 组件编写一个类似的应用程序,如果我们不能让控制台应用程序作为计划任务运行,我们将沿着这条路走下去。但是,如果可能的话,我们想利用我已经写过的东西。

2012 年 1 月 5 日更新

我已尝试按照@dna-man 解决方案设置 NOTESNTSERVICE OS 环境变量。但是,这并没有解决问题。

目前,我们已将应用程序设置为在本地系统帐户下运行的 Windows 服务,并允许与桌面交互。这并不理想,因为它不允许我们轻松地安排它并且它不在域服务帐户下运行,但应用程序确实可以工作,所以我们现在将采用这种方法。

有一个答案建议采用这种方法,但它似乎已被删除,因此我无法将其标记为正确。我可能会让这个问题稍微开放一下,看看其他人是否有任何建议。

【问题讨论】:

  • 如果您有 Domino 服务器,为什么不运行本机 Notes 代理?
  • 这与互操作程序集没有任何关系,它只包含声明,没有代码。联系 IBM 以获得支持。
  • @leyrer - 如果我们无法让 C# 应用程序工作,我们可能最终会走上编写笔记代理来执行任务的路径。但是,在应用程序开发的后期才发现这个问题,我们希望尽可能利用我们已经编写的内容。
  • 如果您(第一次)通过 cmd 提示手动运行 Notes 密码,是否会提示您输入密码?
  • @leyrer - 不,当我们手动运行它时,我们没有得到那个提示。但是,我们将用户名和密码提供给 Initialize(在这种情况下只是密码)/ InitializeUsingNotesUserName 方法。

标签: c# com lotus-domino interop-domino


【解决方案1】:

如果您的代码在 Domino 服务器上运行,您必须确保设置了操作系统环境变量 NOTESNTSERVICE=1。您可以在 Lotus C API 文档中找到有关此环境变量的更多信息,但它在作为服务运行时也适用于 COM API。早在 2003 年,我就创建了一个必须作为服务运行的 VB.NET 应用程序,而设置这个环境变量是关键。如果未设置,则服务将在我注销机器后立即停止工作。为了确保将来安装服务时不会忘记设置此环境变量,我只是让我的服务管理器启动代码在启动时使用对 SetEnvironmentVariable 的 VB.NET 调用直接设置此环境变量。它必须在创建 Domino 会话对象之前设置。

【讨论】:

  • 谢谢,我会考虑这个作为一个潜在的解决方案。我们使用的是计划任务而不是服务,但从您的解释来看,我猜测设置该环境变量也可能适用于计划任务。
  • 我对此进行了调查,但设置此环境变量并没有解决问题。可能确实需要设置它,但它看起来并没有抑制与桌面交互的需要。
【解决方案2】:

很难确切地说出原因,但我相信它无法读取 Lotus 互操作类的注册表信息。显然条目在那里,否则在手动运行时它将不起作用。所以让我们考虑其他可能性。

我什至不知道这是否可能,但是您的应用程序在手动运行时以 32 位运行,但在计划时运行为 64 位? IBM 不支持 Win64 上的 Domino COM 类,我很确定第一个症状是注册表 l

更常见的可能性是服务帐户无权读取机器上安装的 Notes/Domino 的注册表项,可能是因为该软件安装在特定用户帐户下。

【讨论】:

  • 我没有查看服务帐户的注册表权限,但我不确定它是否解释了为什么当运行计划任务的服务帐户登录到计算机时它可以正常运行。如果服务帐户没有读取注册表的权限,那么即使服务帐户登录到机器上,它也可能会失败。因此,这似乎不太可能是注册表权限问题。
  • 关于 32 位与 64 位的建议,当服务帐户登录机器时,计划任务确实有效,它并没有完全失败。如果是因为这个,那么它可能不会一直工作。所以,我认为我们可以排除这种可能性。
  • 好吧,我仍然认为这是注册表读取错误,我能想到的最佳答案是,由于某种原因,域服务帐户没有权限,除非它实际登录。机器上是否安装了任何反恶意软件/防火墙/入侵防护软件?通过谷歌搜索错误代码 0x80004005,我发现在少数情况下会出现这种情况。我唯一的其他建议是使用域服务帐户重新安装 Domino(如果它是在其他帐户下安装的),或者如果您有有效的支持合同,请致电 IBM。
【解决方案3】:

我最终稍微修改了应用程序,将其设置为在本地系统帐户下运行的 Windows 服务,并允许与桌面交互。这并不理想,因为它不允许我们轻松地安排它并且它不在域服务帐户下运行。但是,这种方法确实允许应用程序在不需要帐户始终登录的情况下运行,并且允许显示互操作 UI 元素(从而避免错误)。

为了安排 Windows 服务以设定的时间间隔(我每天设置一次)执行任务,我使用了建议的 Timer 解决方案 here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多