以编程方式确定上次在 Windows 上修改文件的用户?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8406720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatically determine user who last modified file on Windows?
提问by Jamie Curtis
I've been tasked with writing a simple command line utility in C# that will monitor a directory on a server that several users will be accessing to copy/cut/paste/view data. I used FileSystemWatcherto do this but it's lacking a couple features.
我的任务是用 C# 编写一个简单的命令行实用程序,该实用程序将监视服务器上的目录,多个用户将访问该目录以复制/剪切/粘贴/查看数据。我使用FileSystemWatcher来做到这一点,但它缺少一些功能。
Is it possible to determine the useror at least the computer namefrom where the file is being accessed/modified?
是否可以确定访问/修改文件的用户或至少是计算机名称?
(Note: This doesn't have to be with FileSystemWatcher, I'm looking for ANY way to do this.)
(注意:这不必与 FileSystemWatcher 相关,我正在寻找任何方法来做到这一点。)
采纳答案by Joshua
I don't think you'll be able to monitor this from C# directly. Not without the help of the host operating system anyway. Windows and NTFS allow you to audit a particular directory and log the accesses in the Security event log for the host machine (so the server hosting the share would have to audit, not the client).
我认为您无法直接从 C# 监视它。无论如何,都离不开主机操作系统的帮助。Windows 和 NTFS 允许您审核特定目录并在主机的安全事件日志中记录访问(因此托管共享的服务器必须审核,而不是客户端)。
From KB310399 - How to audit user access of files, folders, and printers in Windows XP
来自KB310399 - 如何在 Windows XP 中审核用户对文件、文件夹和打印机的访问
Auditing User Access of Files, Folders, and Printers
The audit log appears in the Security log in Event Viewer. To enable this feature:
- Click Start, click Control Panel, click Performance and Maintenance, and then click Administrative Tools.
- Double-click Local Security Policy.
- In the left pane, double-click Local Policies to expand it.
- In the left pane, click Audit Policy to display the individual policy settings in the right pane.
- Double-click Audit object access.
- To audit successful access of specified files, folders and printers, select the Success check box.
- To audit unsuccessful access to these objects, select the Failure check box.
- To enable auditing of both, select both check boxes.
- Click OK.
Specifying Files, Folders, and Printers to Audit
After you enable auditing, you can specify the files, folders, and printers that you want audited. To do so:
- In Windows Explorer, locate the file or folder you want to audit. To audit a printer, locate it by clicking Start, and then clicking Printers and Faxes.
- Right-click the file, folder, or printer that you want to audit, and then click Properties.
- Click the Security tab, and then click Advanced.
- Click the Auditing tab, and then click Add.
- In the Enter the object name to select box, type the name of the user or group whose access you want to audit. You can browse the computer for names by clicking Advanced, and then clicking Find Now in the Select User or Group dialog box.
- Click OK.
- Select the Successful or Failed check boxes for the actions you want to audit, and then click OK.
- Click OK, and then click OK.
审核用户对文件、文件夹和打印机的访问
审核日志出现在事件查看器的安全日志中。要启用此功能:
- 单击开始,单击控制面板,单击性能和维护,然后单击管理工具。
- 双击本地安全策略。
- 在左窗格中,双击本地策略以将其展开。
- 在左窗格中,单击审核策略以在右窗格中显示各个策略设置。
- 双击审计对象访问。
- 要审核对指定文件、文件夹和打印机的成功访问,请选中“成功”复选框。
- 要审核对这些对象的不成功访问,请选中“失败”复选框。
- 要启用对两者的审核,请选中两个复选框。
- 单击确定。
指定要审核的文件、文件夹和打印机
启用审核后,您可以指定要审核的文件、文件夹和打印机。这样做:
- 在 Windows 资源管理器中,找到要审核的文件或文件夹。要审核打印机,请单击“开始”,然后单击“打印机和传真”来找到它。
- 右键单击要审核的文件、文件夹或打印机,然后单击“属性”。
- 单击安全选项卡,然后单击高级。
- 单击审核选项卡,然后单击添加。
- 在“输入要选择的对象名称”框中,键入要审核其访问权限的用户或组的名称。您可以通过单击“高级”,然后单击“选择用户或组”对话框中的“立即查找”来浏览计算机的名称。
- 单击确定。
- 为要审核的操作选中成功或失败复选框,然后单击确定。
- 单击确定,然后单击确定。
The process is similar for the server operating systems and Windows Vista/Windows 7. If you go this route, you can have the C# program read the event log (See EventLog
class) to look for the data you want.
服务器操作系统和 Windows Vista/Windows 7 的过程是相似的。如果你走这条路,你可以让 C# 程序读取事件日志(参见EventLog
类)来寻找你想要的数据。
Note: Starting with vista you must be and (UAC elevated if needed) administrator to read them from code.
注意:从 vista 开始,您必须是(如果需要,UAC 提升)管理员才能从代码中读取它们。
回答by MethodMan
Make sure to have WMI installed or enabled on your PC, also make sure to add a reference to System.Management
and System.Management.Instrumentation
as well. There is also a C# and VB WMI scripting application GUI that you can download to run and test WMI Queries against as well Google that one. Since I work for Dept of Defense there are certain things that I can get to from here in regards to the web other things are blocked out so please forgive me if I don't post certain web links.
确保在您的 PC 上安装或启用 WMI,同时确保添加对System.Management
和的引用System.Management.Instrumentation
。还有一个 C# 和 VB WMI 脚本应用程序 GUI,您可以下载它来运行和测试 WMI 查询以及谷歌那个。因为我在国防部工作,所以我可以从这里获得一些关于网络的东西,其他东西被屏蔽了,所以如果我没有发布某些网络链接,请原谅我。
Here is something to get you started
这里有一些东西可以让你开始
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());
}