Windows 运行 c# 编译代码时的调度程序功能

Windows Scheduler Capabilities when running c# compiled code

好吧,我有一个应用程序 运行 每小时通过 windows 调度程序。它 运行 成功了,我可以通过 windows 调度程序来判断。当我单击可执行文件时,应用程序 运行 没有问题。

当我通过 windows 调度程序 运行 相同的应用程序时,它无法按预期工作。

它会正常关闭 outlook,但不会重新打开它。 相反,它会启动可执行文件,但 Outlook 应用程序不会出现在我的桌面上。

我的应用程序应该这样做:关闭我的电子邮件,发送电子邮件,打开 outlook。

我首先需要关闭 Outlook,因为如果我在尝试发送电子邮件之前不关闭它,它将尝试访问数据文件,而且因为我事先已经将电子邮件放在桌面上windows 调度程序无法打开数据文件。

static void Main(string[] args)
    {        
        foreach(Process proc in Process.GetProcesses())
        {
            if(proc.ProcessName.Equals("OUTLOOK"))
            {
                proc.Kill();
            }
        }

        //Removed code which sends emails.

        openOutlook();
    }

private static void openOutlook()
    {
        Thread.Sleep(1000);
        Process.Start(@"C:\Program Files (x86)\Microsoft Office\Office14\OUTLOOK.exe");
    }

调度程序是在不同于当前登录用户的本地用户上下文中运行的服务。 Outlook 将在该用户上下文中打开,当前登录的用户将看不到它。

从 windows 调度程序(服务)自动化 Outlook 不是一个好主意。

Microsoft 目前不推荐也不支持来自任何无人值守的 non-interactive 客户端应用程序或组件(包括 ASP、ASP.NET、DCOM 和 NT 服务),因为当 Office 在此环境中处于 运行 时,Office 可能会表现出不稳定的行为 and/or 死锁。

如果您要在 server-side 上下文中构建 运行 的解决方案,您应该尝试使用已确保无人值守执行安全的组件。或者,您应该尝试找到至少允许部分代码为 运行 client-side 的替代方案。如果您使用来自 server-side 解决方案的 Office 应用程序,该应用程序将缺少许多 运行 成功所必需的功能。此外,您将承担整体解决方案稳定性的风险。在 Considerations for server-side Automation of Office 文章中阅读更多相关信息。

作为解决方法,您可以考虑使用 low-level API - 扩展 MAPI。或围绕 API 的任何 third-party 包装器,例如 Redemption。

我想到的最佳解决方案是在发送电子邮件之前关闭 Outlook。

If a process of Outlook is open then kill all instances; proceed with sending emails as needed. Open Outlook manually after the program has finished.

一种可能的替代方法是创建一些 VBA 在特定时间附加电子邮件。您还可以查看此页面上提供的其他链接。