Cannot use any DLL in Windows Service!
-
I'm experimenting with windows services, and I'm facing a strange issue. Consider the following code for a really simple, barebone windows service:
public class TimeLoggerService : ServiceBase
{
public TimeLoggerService()
{
InitializeComponent();\_timer = new Timer(10000); \_timer.Elapsed += new ElapsedEventHandler(\_timer\_Elapsed); } protected override void OnStart(string\[\] args) { \_timer.Start(); } protected override void OnStop() { \_timer.Stop(); } protected void \_timer\_Elapsed(object sender, ElapsedEventArgs e) { // Do stuff here }
}
I compile & install using installutil.exe, and everything works fine. The problem is: when I add a reference to any DLL in my code, the service stops working and I have a FileNotFoundException which tells me that it was impossible to load the DLL. Now: 1 - The service has a LocalSystem account 2 - The DLL is contained in the same folder as the service exe file (the bin/debug folder of my VS2008 project) 3 - This happens with any DLL: I've even written a "dummy" dll with a single method
GetNumber()
which returns an integer for testing purposes, and by simply adding a call toGetNumber()
I have the aforementioned problem Do you have any suggestions about this issue? Regards, Andrea -
I'm experimenting with windows services, and I'm facing a strange issue. Consider the following code for a really simple, barebone windows service:
public class TimeLoggerService : ServiceBase
{
public TimeLoggerService()
{
InitializeComponent();\_timer = new Timer(10000); \_timer.Elapsed += new ElapsedEventHandler(\_timer\_Elapsed); } protected override void OnStart(string\[\] args) { \_timer.Start(); } protected override void OnStop() { \_timer.Stop(); } protected void \_timer\_Elapsed(object sender, ElapsedEventArgs e) { // Do stuff here }
}
I compile & install using installutil.exe, and everything works fine. The problem is: when I add a reference to any DLL in my code, the service stops working and I have a FileNotFoundException which tells me that it was impossible to load the DLL. Now: 1 - The service has a LocalSystem account 2 - The DLL is contained in the same folder as the service exe file (the bin/debug folder of my VS2008 project) 3 - This happens with any DLL: I've even written a "dummy" dll with a single method
GetNumber()
which returns an integer for testing purposes, and by simply adding a call toGetNumber()
I have the aforementioned problem Do you have any suggestions about this issue? Regards, Andreawhat do you mean about dll? is windows library or .net assembly? if it windows library, then you must copy it to %system% folder because service working directory is not in your application folder, otherwise just add as reference to your service application. hope it helps
dhaim ing ngarso sung tulodho, ing madyo mangun karso, tut wuri handayani. "Ki Hajar Dewantoro" in the front line gave a lead, in the middle line build goodwill, in the behind give power support
-
what do you mean about dll? is windows library or .net assembly? if it windows library, then you must copy it to %system% folder because service working directory is not in your application folder, otherwise just add as reference to your service application. hope it helps
dhaim ing ngarso sung tulodho, ing madyo mangun karso, tut wuri handayani. "Ki Hajar Dewantoro" in the front line gave a lead, in the middle line build goodwill, in the behind give power support
Hi, it's actually a .NET assembly so there should not be any problem. It only implements the following code:
namespace TimeLogger
{
public class RandomClass
{
public static int GetRandomNumber()
{
Random rand = new Random();return rand.Next(); } }
}
And compiles it as a managed DLL (TestDll.dll). I add a reference to TestDll.dll in my simple service, I add a line which goes:
int test = RandomClass.GetRandomNumber()
and the service stops working as discussed in my previous message. What am I missing? Thanks, Andrea -
Hi, it's actually a .NET assembly so there should not be any problem. It only implements the following code:
namespace TimeLogger
{
public class RandomClass
{
public static int GetRandomNumber()
{
Random rand = new Random();return rand.Next(); } }
}
And compiles it as a managed DLL (TestDll.dll). I add a reference to TestDll.dll in my simple service, I add a line which goes:
int test = RandomClass.GetRandomNumber()
and the service stops working as discussed in my previous message. What am I missing? Thanks, Andreathis very strange. so far, i only have 2 solved problems in service base application: 1. if in start phase, the service take long periods to start, usually there are processes that take time to load. in this case i create a time that run once to trigger that process on timer ticks. 2. if in start phase then stop, there are no process to be done or an error occurred. your code do not provide any errors. so maybe other member can show you how to solve your problem.
dhaim ing ngarso sung tulodho, ing madyo mangun karso, tut wuri handayani. "Ki Hajar Dewantoro" in the front line gave a lead, in the middle line build goodwill, in the behind give power support
-
this very strange. so far, i only have 2 solved problems in service base application: 1. if in start phase, the service take long periods to start, usually there are processes that take time to load. in this case i create a time that run once to trigger that process on timer ticks. 2. if in start phase then stop, there are no process to be done or an error occurred. your code do not provide any errors. so maybe other member can show you how to solve your problem.
dhaim ing ngarso sung tulodho, ing madyo mangun karso, tut wuri handayani. "Ki Hajar Dewantoro" in the front line gave a lead, in the middle line build goodwill, in the behind give power support
Hi Dhaim, I think I've found it! It is simply an installation issue. In order to install the service, I have configured an external tool in VS2008 with the following parameters: Title: Install Service Command: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe Arguments: $(TargetPath) Init.directory: $(TargetDir) The uninstall service is the same but adds /u. Now, launching this command actually installs the service (I have the familiar installutil log and I can start/stop the service as usual), but the service only works correctly if it does not include any dependency! As soon as I add an assembly, installing like this leads to the issue I noticed, for reasons that I'm not able to explain. If I simply open a VS prompt and install the service "manually" from the command line, everything is fine and the service works as expected. Thanks for your interest in my issue! Regards, Andrea
-
Hi Dhaim, I think I've found it! It is simply an installation issue. In order to install the service, I have configured an external tool in VS2008 with the following parameters: Title: Install Service Command: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe Arguments: $(TargetPath) Init.directory: $(TargetDir) The uninstall service is the same but adds /u. Now, launching this command actually installs the service (I have the familiar installutil log and I can start/stop the service as usual), but the service only works correctly if it does not include any dependency! As soon as I add an assembly, installing like this leads to the issue I noticed, for reasons that I'm not able to explain. If I simply open a VS prompt and install the service "manually" from the command line, everything is fine and the service works as expected. Thanks for your interest in my issue! Regards, Andrea
Update to the previous message: by carefully inspecting the installation logs, I noticed that by using $(TargetPath), VS was picking a copy of my service exe from the "obj/Debug" folder, and not from the "bin/Debug" folder, which contains the results of the compilation and all the assemblies that I'm referencing! I could not spot this earlier because I have a long path to the service exe directory, and I did not notice the fact that it contained "obj" instead of "bin"... For the moment, I have modified the external tool arguments as: $(BinDir)$(TargetName)$(TargetExt) which seems to work, even if I suspect there should be a more direct way to accomplish the same task. Regards, Andrea
-
Update to the previous message: by carefully inspecting the installation logs, I noticed that by using $(TargetPath), VS was picking a copy of my service exe from the "obj/Debug" folder, and not from the "bin/Debug" folder, which contains the results of the compilation and all the assemblies that I'm referencing! I could not spot this earlier because I have a long path to the service exe directory, and I did not notice the fact that it contained "obj" instead of "bin"... For the moment, I have modified the external tool arguments as: $(BinDir)$(TargetName)$(TargetExt) which seems to work, even if I suspect there should be a more direct way to accomplish the same task. Regards, Andrea
-
Final update: this is actually a known VS bug. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=271421[^] I've discovered this by accident, skimming throug a ton of google results about $(TargetPath) usage.
thanks FYI that's really useful information for me. Happy coding.
dhaim ing ngarso sung tulodho, ing madyo mangun karso, tut wuri handayani. "Ki Hajar Dewantoro" in the front line gave a lead, in the middle line build goodwill, in the behind give power support