I have managed to get the Service working, along with the FileSystemEventHandler inserting into a text file, but this now needs to be changed to insert into a database and a text file.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace WindowsServiceTest
{
public partial class Service1 : ServiceBase
{
Timer timer = new Timer(); // name space(using System.Timers;)
public static string path = ConfigurationManager.AppSettings["findpath"];
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WriteToFile("Service is started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 10000; //number in milisecinds
timer.Enabled = true;
FileSystemWatcher watcher = new FileSystemWatcher
{
Path = path,
NotifyFilter = NotifyFilters.LastWrite,
};
watcher.Created += new FileSystemEventHandler(FileSystemWatcher_Changed);
watcher.Renamed += new RenamedEventHandler(FileSystemWatcher_Renamed);
watcher.Changed += new FileSystemEventHandler(FileSystemWatcher_Changed);
watcher.EnableRaisingEvents = true;
}
public static void FileSystemWatcher_Changed(object source, FileSystemEventArgs e)
{
using (SqlConnection con = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Database=ServiceTest;Integrated Security=True;"))
{
try
{
con.Open();
var command = new SqlCommand("Insert into test(URL, Location) values(#URL, #agendaname);", con);
command.Parameters.Add("#URL", System.Data.SqlDbType.VarChar, 100).Value = e.Name;
command.Parameters.Add("#agendaname", System.Data.SqlDbType.VarChar, 100).Value = "Case History";
command.ExecuteNonQuery();
}
catch
{
WriteToFile($"Failed to insert: {e.Name} into the database");
}
}
}
public static void FileSystemWatcher_Renamed(object source, RenamedEventArgs e)
{
WriteToFile($"File Renamed: {e.OldFullPath} renamed to {e.FullPath}");
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
WriteToFile("Service is recalled at " + DateTime.Now);
}
protected override void OnStop()
{
WriteToFile("Service is stopped at " + DateTime.Now);
}
public static void WriteToFile(string Message)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
else
{
using (StreamWriter sw = File.AppendText(filepath))
{
sw.WriteLine(Message);
}
}
}
}
}
I think that I've done the database insert wrong because the catch block is being inserted into the text file. However, I've run the code by itself in a separate project and was inserting into the database in a Console Application.
Any help is appreciated, kind regards.
Windows services run under a different security context than console apps. As the comments have disclosed, the exception is related to your connection string.
If we analyze the connectiong string we can see that you are authenticating with IntegratedSecurity="True". Because your windows service is running under
a service account authentication is failing. I've specified 2 options for resolving this.
Option 1: Have Service run as windows account (Not recommended but will work for testing)
Open run box (Win Flag + R)
Type Services.MSC
Locate your service and right click properties
Choose the logon tab
Enter your windows auth username and password for service to run as
Option 2: Create SQL Server account
Create username and password in SQL for database
Update connection string to specify new username and password created
Related
I am making a service to put on my kid's computer, to make sure that they can't stop Qustodio, and they are quite tech-savvy. They know how to stop a service by going to Run >> services.msc, and I need to make the service NOT_STOPPABLE, like Kaspersky. But when I add the line: CanStop = false;, I can't start the service and it gives me an error. This is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace MyFirstService
{
public partial class Service1 : ServiceBase
{
Timer timer = new Timer();
ServiceController qengine = new ServiceController("qengine");
protected override void OnStart(string[] args)
{
WriteToFile("Service is started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 5000; //number in milisecinds
timer.Enabled = true;
CanStop = false;
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
qengine.Start();
WriteToFile("qengine attemped start at: " + DateTime.Now);
}
public void WriteToFile(string Message)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
else
{
using (StreamWriter sw = File.AppendText(filepath))
{
sw.WriteLine(Message);
}
}
}
}
}
So I created a service to run on a server and look at different folder shares and put them in a database table for a customized search but it pulls a datatable of search locations in and iterates through them one at a time which worked great with small test folders. Now that I tried to use it for real it does not make it through the first folder path before my timer restarts it. I could make it time longer but I basically want this to run constantly and start over as soon as the first one is done or not sure if I can run all paths at the same time. I had it running every 30 Minutes but definitely not long enough.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace MFTSearchService
{
public partial class MFTSearchService : ServiceBase
{
Timer timer = new Timer(); // name space(using System.Timers;)
public MFTSearchService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WriteToFile("Service is started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = TimeSpan.FromMinutes(10).TotalMilliseconds; //number in milisecinds
timer.Enabled = true;
//global::MFTSearchService.Search.SearchStart();
}
protected override void OnStop()
{
WriteToFile("Service is stopped at " + DateTime.Now);
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
WriteToFile("Service is recall at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = TimeSpan.FromMinutes(30).TotalMilliseconds; //number in milisecinds
timer.Enabled = true;
global::MFTSearchService.Search.SearchStart();
}
public void WriteToFile(string Message)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
else
{
using (StreamWriter sw = File.AppendText(filepath))
{
sw.WriteLine(Message);
}
}
}
}
}
Instead of calling
global::MFTSearchService.Search.SearchStart();
in your timer, you can add a BackgroundWorker and start it in your timer. For every tick on your timer, you can check if Backgroundworker is busy or not. BackgroundWorker will not run until it's done if you check it before running it.
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
WriteToFile("Service is recall at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = TimeSpan.FromMinutes(30).TotalMilliseconds; //number in milisecinds
timer.Enabled = true;
if (!backgroundWorker1.IsBusy())
{
backgroundWorker1.RunWorkerAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
global::MFTSearchService.Search.SearchStart();
}
Background worker will not lock your main thread so your timer will continue looping. So you're free to put any interval to it.
I'm trying to create an app that communicate with a Firebird 3.0 embedded database.
I need that two or more of my app instances can connect and edit the same database at the same time.
I had create the connection part and it works.
When I start the first instance it connects correctly, but when I try to access to the database with another app it raise this error: Error while trying to open file -Impossible to open the file.
I also had try to connect with different account for example user2 and user1 (manually created with isql) but without results.
I search on google all day but I found nothing.
Any suggestion? Thanks in advance
This is the acutal code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Firebird;
namespace Firebird_multiuser
{
public partial class Form1 : Form
{
//private TextBox console = new TextBox();
Firebird.Firebird conn = new Firebird.Firebird();
public Form1()
{
InitializeComponent();
input_box.Text = #"G:\Coding\oribruniv8\Firebird\Firebird_multiuser\test.fdb";
}
private void button1_Click(object sender, EventArgs e)
{
if (conn.connect(input_box.Text))
console.AppendText("Successfully connect to database\n");
else
{
console.AppendText("Error during connection ...\n");
return;
}
}
}
}
Firebird class
using FirebirdSql.Data.FirebirdClient;
using FirebirdSql.Data.Isql;
namespace Firebird
{
public class Firebird
{
FbConnectionStringBuilder csb = new FbConnectionStringBuilder();
int pageSize = 8192;
bool forcedWrites = true;
bool overwrite = true;
FbConnection conn;
public Firebird()
{
csb.ClientLibrary = **correct path to fbclient.dll**;
csb.UserID = "sysdba";
csb.Password = "masterkey";
csb.ServerType = FbServerType.Embedded;
}
public bool create(string path)
{
csb.Database = path;
FbConnection.CreateDatabase(csb.ToString(), pageSize, forcedWrites, overwrite);
this.conn = new FbConnection(csb.ToString());
this.conn.Open();
return this.connection_check();
}
public bool connect(string path)
{
csb.Database = path;
this.conn = new FbConnection(csb.ToString());
this.conn.Open();
return this.connection_check();
}
public void query(string SQLquery)
{
this.conn.Open();
using (var transaction = this.conn.BeginTransaction())
using (var command = new FbCommand())
{
command.Connection = this.conn;
command.Transaction = transaction;
command.CommandText = SQLquery;
command.ExecuteNonQuery();
transaction.Commit();
}
}
private bool connection_check()
{
if (this.conn.State == ConnectionState.Open)
{
conn.Close();
return true;
}
else
{
return false;
}
}
}
}
If you want two or more apps to connect to the same database, it is time to consider installing Firebird server instead.
That said, if you are using Firebird 3 embedded, it is possible. By default, Firebird 3 embedded will require exclusive access to the database. This can be changed by making sure there is a firebird.conf in the same location as your fbclient.dll used by your application, and setting the ServerMode setting to SuperClassic (or ThreadedShared).
Doing this carries a small risk. If the database is shared, then all processes must use the same lock files. By default that is the case, but if applications have different FIREBIRD_LOCK environment variable settings, this can corrupt a database as each process will think it doesn't have contenders for its locks.
Is there a way to detect a configuration changes in printers using C#?
I have thread in c# which usually sleeps and I want it to be notified when there is any change in configuration (like someone adds/removes/updates the printer or someone changes the default printer). Once it is notified, it will display simple message.
Is this possible using C#.NET or Using WMI? I have already gone through the solution available but none of them seems to be suitable for the requirement I have.
You can monitor the printer configuration changes using the __InstanceModificationEvent event and the Win32_Printer WMI class
Try this sample.
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace GetWMI_Info
{
public class EventWatcherAsync
{
private void WmiEventHandler(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("TargetInstance.Name : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Name"]);
}
public EventWatcherAsync()
{
try
{
string ComputerName = "localhost";
string WmiQuery;
ManagementEventWatcher Watcher;
ManagementScope Scope;
if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "";
Conn.Password = "";
Conn.Authority = "ntlmdomain:DOMAIN";
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
Scope.Connect();
WmiQuery = "Select * From __InstanceModificationEvent Within 1 " +
"Where TargetInstance ISA 'Win32_Printer' ";
Watcher = new ManagementEventWatcher(Scope, new EventQuery(WmiQuery));
Watcher.EventArrived += new EventArrivedEventHandler(this.WmiEventHandler);
Watcher.Start();
Console.Read();
Watcher.Stop();
}
catch (Exception e)
{
Console.WriteLine("Exception {0} Trace {1}", e.Message, e.StackTrace);
}
}
public static void Main(string[] args)
{
Console.WriteLine("Listening {0}", "__InstanceModificationEvent");
Console.WriteLine("Press Enter to exit");
EventWatcherAsync eventWatcher = new EventWatcherAsync();
Console.Read();
}
}
}
Need to zip text files from a predefined location & save the zipped files in another location of hard disk using windows services & delete the old text file (a scheduled service)
I tried the following code in which i used 'icsharpcode' for zipping the files. But after installing the service.. i am getting a message that "this services has started & then stopped..." without showing any required output.
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Diagnostics.Design;
using System.Diagnostics.Eventing;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Timers;
using ICSharpCode.SharpZipLib.Zip;
namespace createzip
{
public partial class createzip : ServiceBase
{
Timer timer1 = new Timer();
public createzip()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer1.Elapsed += new ElapsedEventHandler(onelapsedtime);
timer1.Enabled = true;
timer1.Interval = 60000;
}
protected override void OnStop()
{
timer1.Enabled = false;
}
private void onelapsedtime(object source, ElapsedEventArgs e)
{
string folder = "#E:\\zipped files";
Directory.SetCurrentDirectory(folder);
string output = "#E:\\output";
string outputfilename = Path.Combine(output, "this file is zipped");
using (var x = new ZipFile(output))
{
foreach (var f in Directory.GetFiles(folder))
x.Add(f);
}
string[] filenames = Directory.GetFiles(folder);
using ( ZipOutputStream s = new
ZipOutputStream(File.Create(output))) //(args[1])))
{
s.SetLevel(9);
byte[] buffer = new byte[4096];
foreach (string file in filenames)
{
ZipEntry entry = new ZipEntry(Path.GetDirectoryName(file));
//entry.DateTime = DateTime.Now;
s.PutNextEntry(entry);
using (FileStream fs = File.OpenRead(file))
{
int sourcebytes;
do
{
sourcebytes = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, sourcebytes);
}
while (sourcebytes > 0);
}
}
s.Finish();
s.Close();
return;
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Timers;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
namespace trail2zip
{
public partial class trail2zip : ServiceBase
{
Timer timer;
string path1 = #"E:\zipped files\New Text Document.txt";
string path2 = #"E:\output\filezipname.zip";
string path3 = #"E:\zipped files\R_23122015.txt";
int timerInterval = 60000;
public trail2zip()
{
InitializeComponent();
timer = new Timer();
timer.Elapsed+=new ElapsedEventHandler(this.timer_Elapsed);
timer.Interval = timerInterval;
timer.Enabled = true;
}
protected override void OnStart(string[] args)
{
timer.Start();
}
protected override void OnStop()
{
timer.Stop();
timer.SynchronizingObject = null;
timer.Elapsed -= new ElapsedEventHandler(this.timer_Elapsed);
timer.Dispose();
timer = null;
}
public void timer_Elapsed(object sender, ElapsedEventArgs e)
{
ZipFile z = ZipFile.Create(path2); //(filezipname);
z.BeginUpdate();
z.Add(path1);
z.Add(path3);
z.CommitUpdate();
z.Close();
}
}
}