3

I have to monitor a shared folder on the server for changes taking place in that folder by a computer connected in the network(it's hostname). I implemented monitoring of directory and files using C#. But, it only monitors events like Created, Renamed, Changed, Deleted and Error events. I also need help with monitoring the hostname/IP address of the computer accessing or doing changes to the shared folder and the time when the event took place. Here is my code :

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

I have tried this approach, but still I am not able to get the hostname. Please help me where I am going wrong.

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()
        {
        }
    }
}
beginner
  • 163
  • 2
  • 2
  • 12
  • 4
    I am pretty sure that is not possible with `FileSystemWatcher` and not from another machine in the network. I guess you have to look into putting that code on the machine sharing that folder and check relevant Windows APIs if it is possible at all to monitor this. – Patrick Hofman Dec 04 '17 at 08:47
  • 1
    Do you *really* need the machine/IP from where the change came in or is it in fact more interesting to get the *User* who did it? My guess would be that the latter is easier. – Fildor Dec 04 '17 at 08:52
  • @Fildor Yes, we require to identify the client machine's hostname on the server which are making changes to the shared folder – beginner Dec 04 '17 at 09:03
  • Maybe have a look into the answers to this question: https://stackoverflow.com/q/1286137/982149 It's from 2009 and about Users, so I am deliberately NOT marking it a duplicate. – Fildor Dec 04 '17 at 09:12
  • This is not a problem you should solve in your code. If you want to register which user makes changes to a shared folder on a server, you need to configure auditing on that server. You can then read the audit log on that server. A FileSystemWatcher is not the solution to this problem. – CodeCaster Dec 04 '17 at 09:41
  • @CodeCaster I already tried auditing. When I perform auditing on the server, it gives me the Server's name as the user instead of the client name who made the changes – beginner Dec 04 '17 at 09:46
  • @beginner Why do you want the hostname of the machine. What value does that provide? – Erik Philips Oct 24 '18 at 22:52

1 Answers1

1

To my knowledge you can use WMI to at least get the ones which are connected to the share. You need to reference System.Management.dll, create an instance of ManagementObjectSearcher and there you go.

The problem is usally finding the correct classes, the reference for WMI can be found here under WMI Reference. For your use case you will need the Win32_ConnectionShare class. Take into consideration that the application needs to run with admin priviledges in order to access data from that class.

A little example code for your use case (according to the above mentioned documentation antecedent represents the server side while dependent represents the client side):

// 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());
}
Markus Safar
  • 6,324
  • 5
  • 28
  • 44