【问题标题】:Get Username of an Accesed File获取已访问文件的用户名
【发布时间】:2023-04-01 03:58:01
【问题描述】:

我想获取访问文件的用户名(添加、删除、重命名...)。 实际上,我使用 filesystemwatcher 来监视文件访问,并且我已经激活了对目录的对象访问,以通过事件日志获取用户信息。这个解决方案并不完美,因为文件事件很多,并且事件日志消息没有那么详细。写入数据只有一个事件 id。这用于添加文件,重命名,移动,......每次写入数据。此外,我必须交叉检查 eventlog 消息是否与 filesystemwatcher 事件匹配。我宁愿更好地处理这个问题。所以我花了很多时间谷歌搜索,阅读,......我知道在stackoverflow上还有另一篇文章

Get username of opened file

但我认为应该有一个可能的解决方案,因为 Windows 事件可以获取用户名。

通过阅读几页,我发现应该有一个使用 netapi32.dll 的可能解决方案。上的示例代码 http://vbcity.com/forums/t/133307.aspx?PageIndex=2 对我不起作用。我无法获取文件ID,所以我将代码更改为

private ulong GetFileIdFromPath(string filePath)
{

  WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo = new WinAPI.BY_HANDLE_FILE_INFORMATION();

  Thread.Sleep(200);

  FileInfo fi = new FileInfo(filePath);

  FileStream fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read);

  WinAPI.GetFileInformationByHandle(fs.Handle, out objectFileInfo);


  fs.Close();


 ulong fileIndex = ((ulong)objectFileInfo.FileIndexHigh << 32) + (ulong)objectFileInfo.FileIndexLow;

  return fileIndex; 

}

使用此代码我可以获取 fileid,但使用 fileid 和示例代码我无法获取用户名。

【问题讨论】:

  • 你在问什么?你需要说清楚。有关事件日志等的所有信息似乎与您的实际问题无关。
  • 我想我的问题很清楚。我想获取访问服务器上文件的用户的用户名。有关事件日志的所有信息都非常重要,因为另一篇文章的内容是“这是不可能的”。
  • 请不要以“C#”开头你的标题。我们在Stack Overflow 上使用标签。另请参阅meta.stackexchange.com/questions/2950/…
  • 您的问题不清楚。 “访问文件的用户名”与“访问文件的用户名”不同。
  • @user1008764:如果有人要求您澄清您的问题,这应该是一个非常明确的迹象,表明您的问题对于您以外的人不清楚

标签: c# filesystemwatcher netapi32


【解决方案1】:

来自我的上一个程序(2 周前) - 我被要求审核文件更改(也是用户名)

解决方案是通过 filesystemwatcher 并在事件发生后 -> 转到 windows 的事件日志并进行 Xpath 搜索 - 查找执行操作的用户。

   public static EventUnit DisplayEventAndLogInformation(string fileToSearch, DateTime actionTime)
        {
            StringBuilder sb = new StringBuilder();
            const string queryString = @"<QueryList>
  <Query Id=""0"" Path=""Security"">
    <Select Path=""Security"">*</Select>
  </Query>
</QueryList>";
            EventLogQuery eventsQuery = new EventLogQuery("Security", PathType.LogName, queryString);
            eventsQuery.ReverseDirection = true;
            EventLogReader logReader = new EventLogReader(eventsQuery);
            EventUnit e = new EventUnit();
            bool isStop = false;
            for (EventRecord eventInstance = logReader.ReadEvent(); null != eventInstance; eventInstance = logReader.ReadEvent())
            {
                foreach (var VARIABLE in eventInstance.Properties)
                    if (VARIABLE.Value.ToString().ToLower().Contains(fileToSearch.ToLower()) && actionTime.ToString("d/M/yyyy HH:mm:ss") == eventInstance.TimeCreated.Value.ToString("d/M/yyyy HH:mm:ss"))
                    {
                        foreach (var VARIABLE2 in eventInstance.Properties) sb.AppendLine(VARIABLE2.Value.ToString());
                        e.Message = sb.ToString();
                        e.User = (eventInstance.Properties.Count > 1) ? eventInstance.Properties[1].Value.ToString() : "n/a";
                        e.File = fileToSearch;
                        isStop = true;
                        break;
                    }
                if (isStop) break;
                try
                {
                    //    Console.WriteLine("Description: {0}", eventInstance.FormatDescription());
                }
                catch (Exception e2)
                {
                }
            }
            return e;
        }

【讨论】:

  • 这接近我的解决方案。我有一个事件日志处理程序。但我不确定这是最好的解决方案。
  • 如果您使用的是系统文件观察器。你别无选择。网上有一个代码可以通过导入 dll 捕获 - 一些事件,如删除和创建,但不能重命名或更多。相信我。这是浪费时间。如果你使用 XPATH 搜索,它是最快的。
  • 我已经浪费了很多时间。为什么 XPATH 搜索比事件日志处理程序更好?
  • @因为您不希望 any 事件出现在您的 c# 程序中,然后过滤需要的内容和不需要的内容(通过事件 ID 等...)。最好的方法是让 systemFileWatcher 工作。然后在 x 秒延迟后(在新线程中)转到 EventLog 并使用 EventLogQuery eventsQuery = new EventLogQuery("Security", PathType.LogName, queryString); eventsQuery.ReverseDirection = true; EventLogReader logReader = new EventLogReader(eventsQuery); 您应该读取包含文件名的顶部插入记录。使用 xpath 只需 2 秒即可阅读全部内容(我的日志为 200mb)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 2012-02-28
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
相关资源
最近更新 更多