以编程方式确定在Windows上上次修改文件的用户?

时间:2011-12-06 20:56:20

标签: c# windows network-drive

我的任务是在C#中编写一个简单的命令行实用程序,它将监视服务器上的一个目录,该目录将由多个用户访问以复制/剪切/粘贴/查看数据。我使用FileSystemWatcher来执行此操作,但它缺少一些功能。

是否可以从访问/修改文件的位置确定用户或至少计算机名称

(注意:这不一定是FileSystemWatcher,我正在寻找任何方法来做到这一点。)

2 个答案:

答案 0 :(得分:7)

我认为你不能直接从C#监听这个。无论如何,并非没有主机操作系统的帮助。 Windows和NTFS允许您审核特定目录并在主机的安全事件日志中记录访问(因此托管共享的服务器必须审核,而不是客户端)。

来自KB310399 - How to audit user access of files, folders, and printers in Windows XP

  

审核文件,文件夹和打印机的用户访问

     

审核日志显示在事件查看器的安全日志中。要启用此功能:

     
      
  1. 单击“开始”,单击“控制面板”,单击“性能和维护”,然后单击“管理工具”。
  2.   
  3. 双击“本地安全策略”。
  4.   
  5. 在左窗格中,双击“本地策略”将其展开。
  6.   
  7. 在左窗格中,单击“审核策略”以在右窗格中显示各个策略设置。
  8.   
  9. 双击“审核对象访问权”。
  10.   
  11. 要审核指定文件,文件夹和打印机的成功访问,请选中“成功”复选框。
  12.   
  13. 要审核对这些对象的不成功访问,请选中“失败”复选框。
  14.   
  15. 要启用对两者的审核,请同时选中两个复选框。
  16.   
  17. 单击“确定”。
  18.         

    指定要审核的文件,文件夹和打印机

         

    启用审核后,您可以指定要审核的文件,文件夹和打印机。为此:

         
        
    1. 在Windows资源管理器中,找到要审核的文件或文件夹。要审核打印机,请单击“开始”,然后单击“打印机和传真”以找到它。
    2.   
    3. 右键单击要审核的文件,文件夹或打印机,然后单击“属性”。
    4.   
    5. 单击“安全”选项卡,然后单击“高级”。
    6.   
    7. 单击“审核”选项卡,然后单击“添加”。
    8.   
    9. 在“输入要选择的对象名称”框中,键入要审核其访问权限的用户或组的名称。通过单击“高级”,然后在“选择用户或组”对话框中单击“立即查找”,可以浏览计算机中的名称。
    10.   
    11. 单击“确定”。
    12.   
    13. 选择要审核的操作的“成功”或“失败”复选框,然后单击“确定”。
    14.   
    15. 单击“确定”,然后单击“确定”。
    16.   

服务器操作系统和Windows Vista / Windows 7的过程类似。如果你走这条路,你可以让C#程序读取事件日志(参见EventLog类)来查找你的数据想。

注意:从vista开始,您必须(并在需要时提升UAC)管理员才能从代码中读取它们。

答案 1 :(得分:0)

确保在您的PC上安装或启用了WMI,同时确保添加对System.ManagementSystem.Management.Instrumentation的引用。还有一个C#和VB WMI脚本应用程序GUI,您可以下载它以运行和测试WMI查询以及Google那个。因为我在国防部工作,所以我可以从这里得到一些关于网络的其他事情被阻止的事情所以如果我不发布某些网络链接,请原谅我。

这是让你入门的东西

    ManagementScope mgtScope = new ManagementScope("\\\\ComputerName\\root\\cimv2");
    // you could also replace the username in the select with * to query all objects
    ObjectQuery objQuery = new ObjectQuery("SELECT username FROM Win32_ComputerSystem");

    ManagementObjectSearcher srcSearcher = new ManagementObjectSearcher(mgtScope, objQuery);

    ManagementObjectCollection colCollection = srcSearcher.Get();

    foreach (ManagementObject curObjCurObject in colCollection)
    {

        Console.WriteLine(curObjCurObject["username"].ToString());
    } 

  //if you want ot get the name of the machine that changed it once it gets into that  Event change the query to look like this. I just tested this locally and it does work 

    ManagementObjectSearcher mosQuery = new ManagementObjectSearcher("SELECT * FROM Win32_Process WHERE ProcessId = " + Process.GetCurrentProcess().Id.ToString());
    ManagementObjectCollection queryCollection1 = mosQuery.Get();
    foreach (ManagementObject manObject in queryCollection1)
    {
        Console.WriteLine("Name : " + manObject["name"].ToString());
        Console.WriteLine("Version : " + manObject["version"].ToString());
        Console.WriteLine("Manufacturer : " + manObject["Manufacturer"].ToString());
        Console.WriteLine("Computer Name : " + manObject["csname"].ToString());
        Console.WriteLine("Windows Directory : " + manObject["WindowsDirectory"].ToString());
    }