views:

214

answers:

4

In a .Net web service is it possible to determine if the assembly was loaded inside a web service? If it is, how would such a check be made? And from such a check can the original location of the assembly be determined?

It's a long story involving assemblies being shared between multiple entry points of our application on a server some of which are exposed through web services and others are exposed through more traditional TCP sockets hosted inside of normal Windows services. There may also be other Windows services running using the same shared assemblies. The configuration needs of each are slightly different and calls like System.Windows.Forms.Application.ExecutablePath yield different results depending on what is "hosting" the assembly. I need to be able reliably calculate the assembly's location to calculate the location of the configuration file.

Web.config / app.config are not options in this scenario.

It would be possible to put an entry into the registry that could be used to determine where the application(s) and all assemblies are located. But this wouldn't be as desirable as having the application(s) calculate locations themselves.

EDIT:

Let's that foo.dll can be called from both MyApp.asmx (the web service) and MyService.exe (the Windows service). Is there anyway to determine if MyApp.asmx was the application that loaded foo.dll from the code-behind (MyApp.dll)?

+1  A: 

This will get all the assemblies loaded into the current execution context:

Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
Rex M
This will get the complete list of assemblies, but doesn't address the primary question: How to determine if the assembly is running from inside a web service.
Mike Chess
When you say "from inside a web service", do you mean the check occurs from the code executing in your web service, or you are external to the web service and want to ask said service if it has loaded a given assembly?
Rex M
From code executing in the web service. It may be an additional assembly that the web service has loaded.
Mike Chess
Then unless I am completely misunderstanding, this will tell you waht you need. This will return all assemblies that have ever been loaded into the appdomain under which the web service is running.
Rex M
The web service and the windows service are different appdomains.
Rex M
A: 

You could make a call to:

Assembly.GetExecutingAssembly().CodeBase

In your code, this would tell you where the currently executing assembly lives.

Millhouse
Yes, but it won't tell me how to determine if the assembly is executing from inside a web service ... which is what I really want to know.
Mike Chess
A: 

If you own the code, it would be better to add an Initialization method or property of some kind that could be used by calling code to tell the assembly where it's running. In fact, you might add a static property that is the location of the config file.

This would help you in other scenarios as well, such as during testing, where you might want to explicitly specify which configuration file should be used, rather than embedding the logic to guess which configuration file to use.

John Saunders
A static property could work. However, there is no guarantee that the application would be placed in the same location at each customer.
Mike Chess
A: 

In researching another aspect of the web service, I stumbled upon this:

string path = Context.Request.ServerVariables["APPL_PHYSICAL_PATH"];

This will return something like "C:\inetpub\wwwroot\MyWebApp\" indicating whether the application is installed. The specific path depends on where the application is installed.

As mentioned in the question, this won't directly help foo.dll figure out whether or not it was called from a web service as foo.dll wouldn't normally have access to Context.Request. With a few changes to foo.dll it would allow the web service to tell foo.dll what the application root was.

Mike Chess