2009-10-03 58 views
1

当我在Windows应用程序中使用下面的代码时,它总是触发WOrkBookOpen事件。WorkbookOpen事件不会与Windows服务一起触发,而它会在Windows应用程序中触发

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组件的对象。

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

感谢 帕雷什

+0

我已阅读由divo发表的评论。如果我可以建议,你可以创建一个Excel插件来做同样的事情?这是否是一个更好的选择? – shahkalpesh 2009-10-04 06:01:54

回答

1

下运行什么帐户的服务?如果是SYSTEM,请确保选项允许服务与桌面交互被选中。或者,尝试在正常用户帐户下运行您的服务。

+0

是它正在运行的系统帐户,并检查相同的选项。 另外我尝试与其他用户有管理权限。但没有成功。 – 2009-10-03 17:52:01

+0

无论如何,我不明白你为什么需要这些事件,因为你完全通过你的服务来控制应用程序,也就是你使用'Application.Documents.Open'等自己打开,激活文档等。 – 2009-10-03 18:12:47

+0

我需要跟踪所有办公室文件在机器上打开。我想为这个文件创建日志。那为什么我使用这个事件来跟踪这个。 – 2009-10-04 04:27:57

1

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

Excel.Application对象将在您的应用程序中的服务帐户下创建。根据您的服务设置,此服务可能可以或不可以与桌面进行交互。但是,用户将始终能够在其用户帐户中打开Excel应用程序。

其次,如果您正在从系统帐户运行excel对象服务,那么您将面临巨大的安全问题。 Office文档是各种恶意软件的巨大来源,您可以根据它开放一些对系统的访问级别,甚至不需要管理员。您不应该在没有考虑安全后果的情况下在特权帐户下打开文档。第三,excel中的很多事件都是针对gui的,如果它们不是可见的窗口,它们可能不会触发。在2000年以前,我在2000年以前很难了解到这一点,从那以后,我真的限制了我对它们的依赖。

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

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

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

+0

感谢您提供详细的解释。 但我认为NTFS的文件审计不适用于我,因为我想审核共享文件夹中的文件。 – 2009-10-07 11:09:38

+0

然后您可以考虑在托管该文件的服务器上设置日志记录。这将是监控文件访问/更改的唯一100%有效的方法。 如果您可以完全访问目标计算机,则可以在计算机上注册一个可信证书并写入一个宏来响应文件打开。您将不得不为宏设置密码。 通过用可信证书对其进行签名,它不会提示用户在文件打开时禁用宏。但是,请注意,您仍然可以在禁用宏的情况下打开文件(只需按住Shift键)。 – Cub 2009-10-15 18:10:01