Как узнать имя хоста/IP-адрес компьютера, который вносит изменения в общую папку на сервере

Мне нужно отслеживать общую папку на сервере на предмет изменений, происходящих в этой папке с помощью компьютера, подключенного к сети (это имя хоста). Я реализовал мониторинг каталогов и файлов с помощью C#. Но он отслеживает только такие события, как Created, Renamed, Changed, Deleted и Error. Мне также нужна помощь в отслеживании имени хоста/IP-адреса компьютера, который получает доступ или вносит изменения в общую папку, а также времени, когда произошло событие. Вот мой код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace a1ashiishFileSystemWatcher
{
    public partial class MainForm : Form
    {
        public ListBoxlistBox;
        public const String startMonitoring = “Start Minitoring…”;
        public const String stopMonitoring = “Stop Minitoring…”;
        public MainForm()
        {
            InitializeComponent();
            //Create a listBox to show activities of all Events.
            listBox = new ListBox();
            listBox.FormattingEnabled = true;
            listBox.Location = new System.Drawing.Point(23, 121);
            listBox.Name = “listBox”;
            listBox.Size = new System.Drawing.Size(571, 238);
            listBox.TabIndex = 2;
            this.Controls.Add(listBox);
        }
        private voidbutton1_Click(object sender, EventArgs e)
        {
            // Create FolderBrowserDialog object.
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            // Show a button to create a new folder.
            folderBrowserDialog.ShowNewFolderButton = true;
            DialogResult dialogResult = folderBrowserDialog.ShowDialog();
            // Get selected path from FolderBrowserDialog control.
            if (dialogResult == DialogResult.OK)
            {
                textBox1.Text = folderBrowserDialog.SelectedPath;
                Environment.SpecialFolderroot = folderBrowserDialog.RootFolder;
            }
        }
        private voidbutton2_Click(object sender, EventArgs e)
        {
            // Create a new FileSystemWatcher object.
            FileSystemWatcher fsWatcher = new FileSystemWatcher();
            switch (button2.Text)
            {
                // Start Monitoring…
                case startMonitoring:
                    if (!textBox1.Text.Equals(String.Empty))
                    {
                        listBox.Items.Add(“Started FileSystemWatcher Service…”);
                        fsWatcher.Path = textBox1.Text;
                        // Set Filter.
                        fsWatcher.Filter = (textBox2.Text.Equals(String.Empty)) ? “*.*” : textBox2.Text;
                        // Monitor files and subdirectories.
                        fsWatcher.IncludeSubdirectories = true;
                        // Monitor all changes specified in the NotifyFilters.
                        fsWatcher.NotifyFilter = NotifyFilters.Attributes |
                                                 NotifyFilters.CreationTime |
                                                 NotifyFilters.DirectoryName |
                                                 NotifyFilters.FileName |
                                                 NotifyFilters.LastAccess |
                                                 NotifyFilters.LastWrite |
                                                 NotifyFilters.Security |
                                                 NotifyFilters.Size;
                        fsWatcher.EnableRaisingEvents = true;
                        // Raise Event handlers.
                        fsWatcher.Changed += new FileSystemEventHandler(OnChanged);
                        fsWatcher.Created += new FileSystemEventHandler(OnCreated);
                        fsWatcher.Deleted += new FileSystemEventHandler(OnDeleted);
                        fsWatcher.Renamed += new RenamedEventHandler(OnRenamed);
                        fsWatcher.Error += new ErrorEventHandler(OnError);
                        button2.Text = stopMonitoring;
                        textBox1.Enabled = false;
                        textBox2.Enabled = false;
                    }
                    else
                    {
                        listBox.Items.Add(“Please select folder to monitor….”);
                    }
                    break;
                // Stop Monitoring…
                case stopMonitoring:
                default:
                    fsWatcher.EnableRaisingEvents = false;
                    fsWatcher = null;
                    button2.Text = startMonitoring;
                    textBox1.Enabled = true;
                    textBox2.Enabled = true;
                    listBox.Items.Add(“Stopped FileSystemWatcher Service…”);
                    break;
            }
        }
        // FileSystemWatcher – OnCreated Event Handler
        public voidOnCreated(object sender, FileSystemEventArgs e)
        {
            // Add event details in listbox.
            this.Invoke((MethodInvoker)delegate { listBox.Items.Add(String.Format(“Path : “{0}”   || Action : {1}”, e.FullPath, e.ChangeType)); });
        }
        // FileSystemWatcher – OnChanged Event Handler
        public voidOnChanged(object sender, FileSystemEventArgs e)
        {
            // Add event details in listbox.
            this.Invoke((MethodInvoker)delegate { listBox.Items.Add(String.Format(“Path : “{0}”   || Action : {1}”, e.FullPath, e.ChangeType)); });
        }
        // FileSystemWatcher – OnRenamed Event Handler
        public voidOnRenamed(object sender, RenamedEventArgs e)
        {
            // Add event details in listbox.
            this.Invoke((MethodInvoker)delegate { listBox.Items.Add(String.Format(“Path : “{0}”   || Action : {1} to “{2}””, e.FullPath, e.ChangeType, e.Name)); });
        }
        // FileSystemWatcher – OnDeleted Event Handler
        public voidOnDeleted(object sender, FileSystemEventArgs e)
        {
            // Add event details in listbox.
            this.Invoke((MethodInvoker)delegate { listBox.Items.Add(String.Format(“Path : “{0}”   || Action : {1}”, e.FullPath, e.ChangeType)); });
        }
        // FileSystemWatcher – OnError Event Handler
        public void OnError(object sender, ErrorEventArgse)
        {
            // Add event details in listbox.
            this.Invoke((MethodInvoker)delegate { listBox.Items.Add(String.Format(“Error : {0}”, e.GetException().Message)); });
        }
    }
}

Я пробовал этот подход, но все же не могу получить имя хоста. Пожалуйста, помогите мне, где я ошибаюсь.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace MonitorShare
{
    public partial class Monitor : ServiceBase
    {
        public Monitor()
        {
            InitializeComponent();
            string dDirectory = @"E:\SharedFolder\Shares";
            DirectoryInfo info = new DirectoryInfo(dDirectory);
            string[] filePath = Directory.GetFiles(dDirectory, "*.*");

            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.BeginInit();
            watcher.filePath = dDirectory;
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | 

NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watcher.Changed += new FileSystemEventHandler(watcher_Changed);
            watcher.Created += new FileSystemEventHandler(watcher_Created);
            watcher.Deleted += new FileSystemEventHandler(watcher_Deleted);
            watcher.Filter = "*.*";
            watcher.EnableRaisingEvents = true;
            watcher.EndInit();
        }

        protected void watcher_Deleted(object sender, FileSystemEventArgs e)
        {
            var process = new Process();
            process.StartInfo.FileName = "openfiles.exe";
            process.StartInfo.Arguments = "/query /FO CSV /v";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            try
            {
                process.Start();
                if ((process.StandardOutput != null))
                {
                    var result = process.StandardOutput.ReadToEnd().Trim().Replace("\"", 

"");
                    var lines = result.Split('\n');

                    var firstLineIndex = 1 + lines.Cast<string>().ToList().FindIndex(l => 

l.Contains("Hostname"));
                    for (var i = firstLineIndex; i < lines.Count() && firstLineIndex > 0; i

++)
                    {
                        var fields = lines[i].Split(',');
                        var time = DateTime.Now;
                        FileStream fs = new FileStream(@"C:\SFD\log.txt", FileMode.Append);
                        StreamWriter sw = new StreamWriter(fs);

                        if(firstLineIndex.ToString()=="Hostname")
                        {
                             Console.SetOut(sw);
                             Console.WriteLine(e.FullPath + "\t" + e.ChangeType + "\t" + 

time + "\t" + e.Name + "\t" + fields[0]);
                             sw.Close();
                        }
                    }
                }
                process.WaitForExit();
            }
            catch (Exception ex)
            {

            }
            finally
            {
                process.Close();
            }
        }

        protected void watcher_Created(object sender, FileSystemEventArgs e)
        {
            var process = new Process();
            process.StartInfo.FileName = "openfiles.exe";
            process.StartInfo.Arguments = "/query /FO CSV /v";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            try
            {
                process.Start();
                if ((process.StandardOutput != null))
                {
                    var result = process.StandardOutput.ReadToEnd().Trim().Replace("\"", 

"");
                    var lines = result.Split('\n');

                    var firstLineIndex = 1 + lines.Cast<string>().ToList().FindIndex(l => 

l.Contains("Hostname"));
                    for (var i = firstLineIndex; i < lines.Count() && firstLineIndex > 0; i

++)
                    {
                        var fields = lines[i].Split(',');
                        var time = DateTime.Now;
                        FileStream fs = new FileStream(@"C:\SFD\log.txt", FileMode.Append);
                        StreamWriter sw = new StreamWriter(fs);

                        if(firstLineIndex.ToString()=="Hostname")
                        {
                             Console.SetOut(sw);
                             Console.WriteLine(e.FullPath + "\t" + e.ChangeType + "\t" + 

time + "\t" + e.Name + "\t" + fields[0]);
                             sw.Close();
                        }
                    }
                }
                process.WaitForExit();
            }
            catch (Exception ex)
            {

            }
            finally
            {
                process.Close();
            }

        }

        protected override void OnStart(string[] args)
        {
        }

        protected override void OnStop()
        {
        }
    }
}

person beginner    schedule 04.12.2017    source источник
comment
Я почти уверен, что это невозможно с FileSystemWatcher, а не с другой машины в сети. Я думаю, вам нужно подумать о том, чтобы поместить этот код на машину, совместно использующую эту папку, и проверить соответствующие API-интерфейсы Windows, если это вообще возможно отслеживать.   -  person Patrick Hofman    schedule 04.12.2017
comment
Вам действительно нужен компьютер/IP, с которого произошло изменение, или на самом деле интереснее узнать пользователя, который это сделал? Я предполагаю, что последнее легче.   -  person Fildor    schedule 04.12.2017
comment
@Fildor Да, нам нужно указать имя хоста клиентского компьютера на сервере, который вносит изменения в общую папку.   -  person beginner    schedule 04.12.2017
comment
Возможно, посмотрите ответы на этот вопрос: stackoverflow.com/q/1286137/982149 Это с 2009 года и о пользователях , поэтому я намеренно НЕ отмечаю его как дубликат.   -  person Fildor    schedule 04.12.2017
comment
Это не проблема, которую вы должны решать в своем коде. Если вы хотите зарегистрировать, какой пользователь вносит изменения в общую папку на сервере, вам необходимо настроить аудит на этом сервере. Затем вы можете прочитать журнал аудита на этом сервере. FileSystemWatcher не является решением этой проблемы.   -  person CodeCaster    schedule 04.12.2017
comment
@CodeCaster Я уже пробовал проводить аудит. Когда я выполняю аудит на сервере, он дает мне имя сервера в качестве пользователя вместо имени клиента, который внес изменения   -  person beginner    schedule 04.12.2017
comment
@beginner Зачем тебе имя хоста машины. Какую ценность это дает?   -  person Erik Philips    schedule 25.10.2018


Ответы (1)


Насколько мне известно, вы можете использовать WMI, чтобы, по крайней мере, получить те, которые подключены к акции. Вам нужно сослаться на System.Management.dll, создать экземпляр ManagementObjectSearcher и все.

Обычно проблема заключается в поиске правильных классов, ссылку на WMI можно найти здесь в разделе Справочник по WMI. В вашем случае вам понадобится класс Win32_ConnectionShare. Учтите, что приложение должно работать с правами администратора, чтобы получить доступ к данным из этого класса.

Небольшой пример кода для вашего варианта использования (согласно вышеупомянутой документации antecedent представляет серверную часть, а dependent представляет клиентскую сторону):

// Create a query
SelectQuery query = new SelectQuery("SELECT * FROM Win32_ConnectionShare");

// Initialize an object searcher with this query
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

// Get the resulting collection and loop through it
foreach (ManagementObject mo in searcher.Get())
{
    string antecedent = mo["antecedent"].ToString();
    string dependent = mo["dependent"].ToString();

    ManagementObject share = new ManagementObject(antecedent);
    ManagementObject server = new ManagementObject(dependent);

    Console.WriteLine(server["UserName"].ToString());
    Console.WriteLine(server["ComputerName"].ToString());
    Console.WriteLine(server["ShareName"].ToString());
}
person Markus Safar    schedule 04.12.2017