Workbook_Open事件不会触发Windows服务,而它会触发Windows应用程序

时间:2009-10-03 17:42:35

标签: c# .net windows service

当我在Windows应用程序中使用下面的代码时,它总是触发WOrkBookOpen事件。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    Microsoft.Office.Interop.Excel.Application app;
    private void button1_Click(object sender, EventArgs e)
    {
        app = new Microsoft.Office.Interop.Excel.Application();
        app.WorkbookOpen += new Microsoft.Office.Interop.Excel.AppEvents_WorkbookOpenEventHandler(app_WorkbookOpen);
        app.WorkbookActivate += new Microsoft.Office.Interop.Excel.AppEvents_WorkbookActivateEventHandler(app_WorkbookActivate);
    }

    void app_WorkbookActivate(Microsoft.Office.Interop.Excel.Workbook Wb)
    {
        MessageBox.Show(Wb.FullName);
    }

    void app_WorkbookOpen(Microsoft.Office.Interop.Excel.Workbook Wb)
    {
        MessageBox.Show(Wb.FullName);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        app.Quit();
        Marshal.FinalReleaseComObject(app);
    }
}

但是,当我想使用Windows服务触发相同的事件时,它不会触发。以下是用于服务的代码。我在服务的OnStart()中创建Excel互操作对象并附加相同的事件。但在安装服务后,这个事件并没有发生。而在同一个Windows应用程序中,它会激活。这里出于测试目的,我在磁盘上创建FIle以检查事件是否正在触发。

public partial class Service1 : ServiceBase
{

    Microsoft.Office.Interop.Excel.Application excel;
    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        try
        {
            File.Create("C:\\SampleService\\Start - " + DateTime.Now.Ticks.ToString());

            excel = new Microsoft.Office.Interop.Excel.Application();
            excel.WorkbookOpen += new Microsoft.Office.Interop.Excel.AppEvents_WorkbookOpenEventHandler(excel_WorkbookOpen);
            excel.WorkbookActivate += new Microsoft.Office.Interop.Excel.AppEvents_WorkbookActivateEventHandler(excel_WorkbookActivate);
            File.Create("C:\\SampleService\\Start - " + DateTime.Now.Ticks.ToString());

        }
        catch (Exception e)
        {
            using (StreamWriter stream = new StreamWriter(@"C:\SampleService\Err.txt", true))
            {
                stream.Write(e.Message);
            }
        }
    }

    void excel_WorkbookActivate(Microsoft.Office.Interop.Excel.Workbook Wb)
    {
        File.Create("C:\\SampleService\\EXCEL - " + DateTime.Now.Ticks.ToString());
    }

    public void excel_WorkbookOpen(Microsoft.Office.Interop.Excel.Workbook Wb)
    {
        File.Create("C:\\SampleService\\EXCEL - " + DateTime.Now.Ticks.ToString());
    }

    protected override void OnStop()
    {
        if (excel != null)
        {
            excel.Quit();
            Marshal.FinalReleaseComObject(excel);
        }
    }
}

我也使用serviceInstaller,我在机器上安装服务。我正在为服务创建适当的权限来创建Excel.Application com组件的对象。

有人遇到过这样的问题吗?或者你发现我遗失了什么?

由于 帕雷什

2 个答案:

答案 0 :(得分:1)

您的服务在哪个帐户下运行?如果是SYSTEM,请确保选中允许服务与桌面交互选项。或者,尝试在普通用户帐户下运行您的服务。

答案 1 :(得分:1)

首先,您似乎正在尝试使用service和excel.application对象记录打开的excel文件。这不是一个非常好的解决方案,你会发现它最多会产生不一致的结果。

将在您的应用程序中的服务帐户下创建Excel.Application对象。此服务可能会也可能无法与桌面交互,具体取决于您的服务设置。但是,用户始终可以在其用户帐户中打开Excel应用程序。

其次,如果您正在从系统帐户运行excel对象服务,那么您将面临巨大的安全问题。 Office文档是各种恶意软件的巨大来源,您将在其下打开任何可以访问您系统的权限,甚至不是管理员。您不应在未考虑安全后果的情况下在特权帐户下打开文档。

第三,excel中的许多事件都是针对gui的,如果它们不是一个可见的窗口,它们可能不会触发。多年前我在2000年以前的努力学到了这一点,从那以后我确实限制了我对它们的依赖。

如果我可以提出一些建议,

  • 如果您的目的是监控谁打开文件,请考虑使用内置于Windows中的文件系统安全性/日志记录。可以将其设置为审核文件,并在访问文件时写入安全事件日志。可以使用WMI通过网络轻松检索此信息。
  • 除非您确定要执行的操作,否则请勿在特权帐户下运行任何内容。您的excel文件现在可能没问题,但是一个用户引入宏病毒可能是灾难性的。
  • 如果您必须编写自己的“日志记录”,请考虑使用全局挂钩来监视(仅监视,不更改或修改)excel打开的文件。只在打开excel文件时记录的quickie hook应用程序不会影响系统性能,并且比您建议的更安全,更稳定。如果您不熟悉钩子,desaware曾经为钩子和子类化制作了一些很棒的组件,你应该检查它们。但是,除非您非常熟悉程序正在执行的操作,否则只会监视消息,不要尝试为excel“处理”它们。
  • Excel插件只是一个向Excel添加自定义功能或功能的文件,它最常见于xll或xla文件中的VBA。如果您需要安全性,请不要依赖插件监视文件访问,因为它们很容易被禁用。

监视谁打开文件的最有效方法是使用内置于NTFS中的文件审核。