Click here to Skip to main content
15,892,746 members
Articles / Programming Languages / Visual Basic

An app to see who has files open on a network server

Rate me:
Please Sign up or sign in to vote.
3.63/5 (7 votes)
29 Jun 2005CPOL5 min read 284.8K   4.8K   60  
An app to see who has files open on a network server.
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.IO;
using System.Data.SqlClient;
namespace OpenFilesServer2
{
	public class OpenFilesService2 : System.ServiceProcess.ServiceBase
	{
		internal System.Timers.Timer Timer1;
		internal System.Data.DataSet DataSetIni;
		internal System.Data.DataTable Settings;
		internal System.Data.DataColumn DataColumn1;
		internal System.Data.DataColumn DataColumn2;
		internal System.Data.DataTable FileServers;
		internal System.Data.DataColumn DataColumn3;
		internal System.Data.DataColumn DataColumn4;
		internal System.Data.DataSet DSFileData;
		internal System.Data.DataTable OFServer;
		internal System.Data.DataColumn DataColumn5;
		internal System.Data.DataColumn DataColumn6;
		internal System.Data.DataColumn DataColumn7;
		internal System.Data.DataColumn DataColumn8;
		internal System.Data.DataColumn DataColumn9;
		internal System.Data.DataColumn DataColumn10;
		internal System.Data.DataColumn DataColumn11;
		internal System.Data.DataTable CurrentTime;
		internal System.Data.DataColumn DataColumn12;
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public OpenFilesService2()
		{
			// This call is required by the Windows.Forms Component Designer.
			InitializeComponent();

			// TODO: Add any initialization after the InitComponent call
		}
		// Declare the variables that will be used to contain the various
		//   required DateTime and TimeSpan objects
		private DateTime timeStart; // Used to note the start time of the service
		private DateTime timeEnd;  // Used to note the end time of the service
		private TimeSpan timeElapsed = new TimeSpan(0); // Initialize to 0
		// Used to calculate difference between timeEnd and TimeStart
		private TimeSpan timeDifference;
		private Boolean isPaused = false; // Notes whether the service is paused
		//other vars
		private string outputDir = String.Empty; //Where to write out the openfiles data file
		private string timerElapse = String.Empty; //How long before the timer event occurs
		private Boolean debugOn= false; //Are we writing extra info out
		private Boolean skipOnce = false; //Used for debugging
		private int lastMinute = 0; //Used to know if we need to write out a new file

		// The main entry point for the process
		static void Main()
		{
			System.ServiceProcess.ServiceBase[] ServicesToRun;
	
			// More than one user Service may run within the same process. To add
			// another service to this process, change the following line to
			// create a second service object. For example,
			//
			//   ServicesToRun = new System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
			//
			ServicesToRun = new System.ServiceProcess.ServiceBase[] { new OpenFilesService2() };

			System.ServiceProcess.ServiceBase.Run(ServicesToRun);
		}

		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.Timer1 = new System.Timers.Timer();
			this.DataSetIni = new System.Data.DataSet();
			this.Settings = new System.Data.DataTable();
			this.DataColumn1 = new System.Data.DataColumn();
			this.DataColumn2 = new System.Data.DataColumn();
			this.FileServers = new System.Data.DataTable();
			this.DataColumn3 = new System.Data.DataColumn();
			this.DataColumn4 = new System.Data.DataColumn();
			this.DSFileData = new System.Data.DataSet();
			this.OFServer = new System.Data.DataTable();
			this.DataColumn5 = new System.Data.DataColumn();
			this.DataColumn6 = new System.Data.DataColumn();
			this.DataColumn7 = new System.Data.DataColumn();
			this.DataColumn8 = new System.Data.DataColumn();
			this.DataColumn9 = new System.Data.DataColumn();
			this.DataColumn10 = new System.Data.DataColumn();
			this.DataColumn11 = new System.Data.DataColumn();
			this.CurrentTime = new System.Data.DataTable();
			this.DataColumn12 = new System.Data.DataColumn();
			((System.ComponentModel.ISupportInitialize)(this.Timer1)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.DataSetIni)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.Settings)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.FileServers)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.DSFileData)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.OFServer)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.CurrentTime)).BeginInit();
			// 
			// Timer1
			// 
			this.Timer1.Enabled = true;
			this.Timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.Timer1_Elapsed);
			// 
			// DataSetIni
			// 
			this.DataSetIni.DataSetName = "NewDataSet";
			this.DataSetIni.Locale = new System.Globalization.CultureInfo("en-US");
			this.DataSetIni.Tables.AddRange(new System.Data.DataTable[] {
																			this.Settings,
																			this.FileServers});
			// 
			// Settings
			// 
			this.Settings.Columns.AddRange(new System.Data.DataColumn[] {
																			this.DataColumn1,
																			this.DataColumn2});
			this.Settings.TableName = "Settings";
			// 
			// DataColumn1
			// 
			this.DataColumn1.AllowDBNull = false;
			this.DataColumn1.ColumnName = "OutputDir";
			this.DataColumn1.DefaultValue = "";
			// 
			// DataColumn2
			// 
			this.DataColumn2.AllowDBNull = false;
			this.DataColumn2.ColumnName = "TimerElapse";
			this.DataColumn2.DefaultValue = "";
			// 
			// FileServers
			// 
			this.FileServers.Columns.AddRange(new System.Data.DataColumn[] {
																			   this.DataColumn3,
																			   this.DataColumn4});
			this.FileServers.TableName = "FileServers";
			// 
			// DataColumn3
			// 
			this.DataColumn3.AllowDBNull = false;
			this.DataColumn3.ColumnName = "FileServerName";
			this.DataColumn3.DefaultValue = "";
			// 
			// DataColumn4
			// 
			this.DataColumn4.AllowDBNull = false;
			this.DataColumn4.ColumnName = "Active_Flag";
			this.DataColumn4.DefaultValue = "";
			// 
			// DSFileData
			// 
			this.DSFileData.DataSetName = "NewDataSet";
			this.DSFileData.Locale = new System.Globalization.CultureInfo("en-US");
			this.DSFileData.Tables.AddRange(new System.Data.DataTable[] {
																			this.OFServer,
																			this.CurrentTime});
			// 
			// OFServer
			// 
			this.OFServer.Columns.AddRange(new System.Data.DataColumn[] {
																			this.DataColumn5,
																			this.DataColumn6,
																			this.DataColumn7,
																			this.DataColumn8,
																			this.DataColumn9,
																			this.DataColumn10,
																			this.DataColumn11});
			this.OFServer.TableName = "OFServer";
			// 
			// DataColumn5
			// 
			this.DataColumn5.AllowDBNull = false;
			this.DataColumn5.ColumnName = "Hostname";
			this.DataColumn5.DefaultValue = "";
			// 
			// DataColumn6
			// 
			this.DataColumn6.AllowDBNull = false;
			this.DataColumn6.ColumnName = "ID";
			this.DataColumn6.DefaultValue = "";
			// 
			// DataColumn7
			// 
			this.DataColumn7.AllowDBNull = false;
			this.DataColumn7.ColumnName = "Access_by";
			this.DataColumn7.DefaultValue = "";
			// 
			// DataColumn8
			// 
			this.DataColumn8.AllowDBNull = false;
			this.DataColumn8.Caption = "Type";
			this.DataColumn8.ColumnName = "Type";
			this.DataColumn8.DefaultValue = "";
			// 
			// DataColumn9
			// 
			this.DataColumn9.AllowDBNull = false;
			this.DataColumn9.ColumnName = "Locks";
			this.DataColumn9.DefaultValue = "";
			// 
			// DataColumn10
			// 
			this.DataColumn10.AllowDBNull = false;
			this.DataColumn10.ColumnName = "Open_Mode";
			this.DataColumn10.DefaultValue = "";
			// 
			// DataColumn11
			// 
			this.DataColumn11.AllowDBNull = false;
			this.DataColumn11.ColumnName = "Open_File";
			this.DataColumn11.DefaultValue = "";
			// 
			// CurrentTime
			// 
			this.CurrentTime.Columns.AddRange(new System.Data.DataColumn[] {
																			   this.DataColumn12});
			this.CurrentTime.TableName = "CurrentTime";
			// 
			// DataColumn12
			// 
			this.DataColumn12.AllowDBNull = false;
			this.DataColumn12.ColumnName = "FileDateTime";
			this.DataColumn12.DataType = typeof(System.DateTime);
			// 
			// OpenFilesService2
			// 
			this.ServiceName = "OpenFilesServer2";
			((System.ComponentModel.ISupportInitialize)(this.Timer1)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.DataSetIni)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.Settings)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.FileServers)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.DSFileData)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.OFServer)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.CurrentTime)).EndInit();

		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		/// <summary>
		/// Set things in motion so your service can do its work.
		/// </summary>
		protected override void OnStart(string[] args)
		{
			// Add code here to start your service. This method should set things
        // in motion so your service can do its work.
        //Get xml / ini info
        readXmlIni(args);
        // Reset timeElapsed to zero. This is necessary since the used can
        //   call Restart without pausing or stopping the service
        timeElapsed = new TimeSpan(0);

        // Initialize the Start time
        timeStart = DateTime.Now;
        isPaused = false;
        Timer1.Enabled = true;
        EventLog.WriteEntry("Open Files Service was Started at " + timeStart.ToString());
		}
		/// <summary>
		/// This procedure reads in the ini file setting from the xml file in the output
		/// directory
		/// </summary>
		/// <param name="inargs"></param>
		private void readXmlIni(string[] inargs)
		{
			//Check to see if the ini xml file exists if it doesn't default the correct data and create it.
			string inputfilepath = String.Empty;

			if (inargs.Length > 0) 
			{
				inputfilepath = inargs[0] + "\\";
				if (inargs.Length >= 1) 
				{
					debugOn = (inargs[1] == "Debug");
				}
			}
			else
			{
				inputfilepath = "c:\\";
			}
			
			//Note I am using a dataset to store ini file like information
			if (!File.Exists(inputfilepath + "OpenFilesini.xml"))
			{
				//This is default info if the ini.xml file doesn't exist
				object[] values = new object[2] {"\\\\servername\\folderforoutput\\","60000"};
				DataSetIni.Tables[0].LoadDataRow(values, true);
				//Default one file server to check
				object[] values2 = new object[2] {"\\\\server","Y"};
				//file server name
				//Active
				DataSetIni.Tables[1].LoadDataRow(values2, true);
				DataSetIni.WriteXml(inputfilepath + "OpenFilesini.xml");
			}
		

			//All the ini file fields are in one row  again the row could be defined as a private var if the info is needed 	'elsewhere
		//Note that you can use the column names you defined in the dataset\settings table
		DataRow tmpRow ;
		DataSetIni.ReadXml(inputfilepath + "OpenFilesini.xml");
		tmpRow = DataSetIni.Tables[0].Rows[0];

		outputDir = tmpRow["OutputDir"].ToString();
		//TimerElapse = tmprow("TimerElapse")
		//We check to see if the minute has changed if it has then we write out a new file
		Timer1.Interval = 10000; //CInt(TimerElapse) //hard code for every 10 seconds
		}
		/// <summary>
		/// Stop this service.
		/// </summary>
		protected override void OnStop()
		{
			
			// Calculate the necessary times. If the Service is not currently paused
			//   the timeElapsed must be changed to consider the time its been
			//   running since a start or continue.
			timeEnd = DateTime.Now;
			if (!isPaused)
			{
				timeDifference = timeEnd.Subtract(timeStart);
				timeElapsed = timeElapsed.Add(timeDifference);
			}
			Timer1.Enabled = false;

			EventLog.WriteEntry("Open Files Service was Stopped at " + timeEnd.ToString());
			EventLog.WriteEntry("Open Files ran for a total time of " + timeElapsed.ToString());
		}

		/// <summary>
		/// This is called by the timer elaspe it checks the xml ini file to see
		/// which servers it should be trying to find and save open file info
		/// </summary>
		private void processFiles()
		{
			if (debugOn) 
			{
				EventLog.WriteEntry("Open Files Service start processfiles event : " + DateTime.Now.ToShortTimeString());

			}

			
			DataView dv;
			//The ini xml file contains rows of server name and active flag
			dv = DataSetIni.Tables[1].DefaultView;
			//We only want the ones that are active
			dv.RowFilter = "Active_Flag = 'Y'";
			DataRowView dvrow ;
			string tmpserver = String.Empty;
			string tmpoutfile = String.Empty;
			//loop through the servers that have active flag = y
			for (int i = 0; i <= dv.Count- 1; i++)
			{
			
			dvrow = dv[i];
			tmpserver = dvrow["FileServerName"].ToString();
				if (debugOn) 
				{
					EventLog.WriteEntry("Open Files Service Processing file " + tmpserver);
				}
			//We use the server name to help identify the output file
			tmpoutfile = outputDir + "\\" + tmpserver.Replace("\\", "") + "_" + DateTime.Now.Minute.ToString() + ".xml";
				if (File.Exists(tmpoutfile))
				{
					File.Delete(tmpoutfile);
				}
			//This will call the openfiles program
			sendCmd(tmpserver, tmpoutfile);
			} // end for

		}
		/// <summary>
		/// This procedure is what calls the openfiles.exe through a process
		/// openfiles.exe returns the list of open files for the server quired
		/// </summary>
		/// <param name="infileserver"></param>
		/// <param name="outfilename"></param>
		private void sendCmd(string infileserver , string outfilename )
		{
		//This will write out a file each minute.
		Process myprocess = new Process();
		//Program you want to launch execute etc.
		myprocess.StartInfo.FileName = "c:\\windows\\system32\\openfiles.exe";
		myprocess.StartInfo.Arguments = "/query /s " + infileserver + " /v";

		//This is important.  Since this is a windows service it will run
		//even though no one is logged in.
		//Therefore there is not desktop available so you better
		//not show any windows dialogs
		myprocess.StartInfo.UseShellExecute = false;
		myprocess.StartInfo.CreateNoWindow = true;
		//We want to redirect the output from the openfiles call to the program
		//Since there won't be any window to display it in
		myprocess.StartInfo.RedirectStandardOutput = true;

		//Create the shell and execute the command
			try
			{
				myprocess.Start();

				if ((myprocess.StandardOutput != null)) 
				{

					//This string is used to contain what openfiles program returns
					string tmpstr2 = String.Empty;
					DSFileData.Tables[0].Clear();
					DSFileData.Tables[1].Clear();
					object[] values = new object[6]; //This storeds the fields from openfiles
					object[] values2 = new object[1] {DateTime.Now}; //This is the current date

					int cnt = 0;

					while (myprocess.StandardOutput.Peek() >= 0)
					{
						tmpstr2 = myprocess.StandardOutput.ReadLine();
						// Add some text to the file.
						cnt += 1;
						//The output is fixed length
						if (cnt > 5) 
						{
							values[0] = tmpstr2.Substring(0, 15).Trim(); //Host name
							values[1] = tmpstr2.Substring(16, 8).Trim() ;//ID
							values[2] = tmpstr2.Substring(25, 20).Trim();//accessed by
							values[3] = tmpstr2.Substring(46, 10).Trim ();//type
							values[4] = tmpstr2.Substring(57, 10).Trim();//locks
							values[5] = tmpstr2.Substring(68, 15).Trim();//open mode
							values[6] = tmpstr2.Substring(84);//open file
							DSFileData.Tables[0].LoadDataRow(values, true);
						}

					}


					//Table(0) has the rows from openfiles
					DSFileData.Tables[0].AcceptChanges();
					//table(1) has the current date
					DSFileData.Tables[1].LoadDataRow(values2, true);
					DSFileData.Tables[1].AcceptChanges();
					//Now we write out the file so the client can read it.
					DSFileData.WriteXml(outfilename);

				}
				//Wait for the process to finish before continuing.
				myprocess.WaitForExit();
			}
			catch (Exception e )
				  {
					  EventLog.WriteEntry("Open Files Service sendcmd error: " + e.Message + " : " + DateTime.Now.ToShortTimeString());

				  }
			finally
			{
				//Free resources
				myprocess.Close();
			}; //end try

		}
		/// <summary>
		/// This is the timer elapse procedure we set it to 10 seconds to we can
		/// know when the minute has changed and we need to write out a new output file.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void Timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
		{
			//This is the auto check for new files
	        if (debugOn) 
			{
				EventLog.WriteEntry("Open Files Service timer event : " + DateTime.Now.ToShortTimeString());
			}
			if (lastMinute == DateTime.Now.Minute)
			{
				return;
			}
			Timer1.Enabled = false;
			//When debugging sometimes we don't want this to first the first time.
			if (skipOnce) 
			{
				skipOnce = false;
			}
			else
			{
				processFiles();
			}
			lastMinute = DateTime.Now.Minute;
			if (!isPaused)
			{
				Timer1.Enabled = true;
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I started my programmer career over 26 years ago doing COBOL and SAS on a MVS mainframe. It didn't take long for me to move into windows programming. I started my windows programming in Delphi (Pascal) with a Microsoft SQL server back end. I started working with vb.net when the beta 2 came out in 2001. After spending most of my programming life as a windows programmer I started to check out asp.net in 2004. I achieved my MCSD.net in April 2005. I have done a lot of MS SQL database stuff. I have a lot of experience with Window Service and Web services as well. I spent three years as a consultant programing in C#. I really enjoyed it and found the switch between vb.net and C# to be mostly syntax. In my current position I am programming in C# working on WPF and MSSql database stuff. Lately I have been using VS2019.

On a personal note I am a born again Christian, if anyone has any questions about what it means to have a right relationship with God or if you have questions about who Jesus Christ is, send me an e-mail. ben.kubicek[at]netzero[dot]com You need to replace the [at] with @ and [dot] with . for the email to work. My relationship with God gives purpose and meaning to my life.

Comments and Discussions