|
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.
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.