我的任务是用 C# 编写一个简单的命令行实用程序,它将监视服务器上的一个目录,多个用户将访问该目录以复制/剪切/粘贴/查看数据。我使用FileSystemWatcher来执行此操作,但它缺少一些功能。
是否可以确定访问/修改文件的用户或至少是计算机名称?
(注意:这不必与 FileSystemWatcher 一起使用,我正在寻找任何方法来做到这一点。)
我的任务是用 C# 编写一个简单的命令行实用程序,它将监视服务器上的一个目录,多个用户将访问该目录以复制/剪切/粘贴/查看数据。我使用FileSystemWatcher来执行此操作,但它缺少一些功能。
是否可以确定访问/修改文件的用户或至少是计算机名称?
(注意:这不必与 FileSystemWatcher 一起使用,我正在寻找任何方法来做到这一点。)
我认为您无法直接从 C# 监视它。无论如何,都离不开主机操作系统的帮助。Windows 和 NTFS 允许您审核特定目录并将访问记录在主机的安全事件日志中(因此托管共享的服务器必须审核,而不是客户端)。
来自KB310399 - 如何在 Windows XP 中审核用户对文件、文件夹和打印机的访问权限
审核用户对文件、文件夹和打印机的访问权限
审核日志显示在事件查看器的安全日志中。要启用此功能:
- 单击开始,单击控制面板,单击性能和维护,然后单击管理工具。
- 双击本地安全策略。
- 在左侧窗格中,双击本地策略将其展开。
- 在左侧窗格中,单击审核策略以在右侧窗格中显示各个策略设置。
- 双击审核对象访问。
- 要审核对指定文件、文件夹和打印机的成功访问,请选中成功复选框。
- 要审核对这些对象的不成功访问,请选中“失败”复选框。
- 要启用两者的审核,请选中这两个复选框。
- 单击确定。
指定要审核的文件、文件夹和打印机
启用审核后,您可以指定要审核的文件、文件夹和打印机。为此:
- 在 Windows 资源管理器中,找到要审核的文件或文件夹。要审核打印机,请单击“开始”,然后单击“打印机和传真”找到它。
- 右键单击要审核的文件、文件夹或打印机,然后单击“属性”。
- 单击安全选项卡,然后单击高级。
- 单击审核选项卡,然后单击添加。
- 在“输入要选择的对象名称”框中,键入要审核其访问权限的用户或组的名称。您可以通过单击高级浏览计算机以查找名称,然后单击选择用户或组对话框中的立即查找。
- 单击确定。
- 选中您要审核的操作的成功或失败复选框,然后单击确定。
- 单击确定,然后单击确定。
服务器操作系统和 Windows Vista/Windows 7 的过程类似。如果你走这条路,你可以让 C# 程序读取事件日志(参见EventLog
类)来查找你想要的数据。
注意:从 vista 开始,您必须是(如果需要,UAC 提升)管理员才能从代码中读取它们。
确保在您的 PC 上安装或启用了 WMI,同时确保添加对System.Management
和的引用System.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());
}