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

本文关键字:修改 文件 用户 Windows 编程 方式确 | 更新日期: 2023-09-27 18:17:03

我的任务是用c#编写一个简单的命令行实用程序,它将监视服务器上的目录,多个用户将访问该目录以复制/剪切/粘贴/查看数据。我用FileSystemWatcher来做这件事,但是它缺少一些功能。

是否有可能确定用户或至少计算机名从文件被访问/修改?

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

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

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

来自KB310399 -如何审计Windows XP中文件、文件夹和打印机的用户访问

审计文件、文件夹和打印机的用户访问

审计日志出现在事件查看器的安全日志中。要启用此功能:

  1. 单击开始,单击控制面板,单击性能和维护,然后单击管理工具。
  2. 双击本地安全策略。
  3. 在左侧窗格中,双击Local Policies展开
  4. 在左窗格中单击Audit Policy,在右窗格中显示各个策略设置。
  5. 双击审计对象访问。
  6. 选中"成功"复选框,对指定文件、文件夹和打印机的成功访问进行审计。
  7. 要审计对这些对象的不成功访问,请选中Failure复选框。
  8. 要同时启用审计,选中两个复选框。
  9. 单击OK。

指定要审计的文件、文件夹和打印机

启用审计后,您可以指定要审计的文件、文件夹和打印机。

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

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

注意:从vista开始,你必须是一个(UAC升高如果需要)管理员从代码中读取它们

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

这里有一些东西可以让你开始

    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());
    }