views:

40

answers:

3

Hello all

I have created a dll that will be used by multiple applications, and have created an installer package that installs it to the program files, as well as adds it to the Global Assembly Cache.

The dll itself uses log4net, and requires a xml file for the logging definitions.

Therefore when the installer is run, the following files get copied to the install directory within program files: The main dll that I developed - The Log4Net.dll - the Log4Net.xml file

I am now experiencing a problem. I have created a test console application for experimentation. I have added my dll as a reference, and set the 'local copy' flag to false.

When I compile the test console exe however, I noticed that it has copied the log4net.dll and log4net.xml files to the bin directory. And when running the test console, it appears that it will only work if the log4net.dll is in the same directory as the exe. This is dispite the fact that the test console application does not use log4net, only the dll that was added as a reference does.

Is there some way to have it so that the log4net.dll & xml files used will be the ones that were installed to the program files, rather than any application needed to copy over local copies? The applications that will be using my dll will not be using log4net, only the dll that they are referencing uses it.

Many thanks

+1  A: 
  1. Don't install into the Global Assembly Cache! Even if your library dll is used by multiple applications each should have it's own local copy. Otherwise you get into a whole world of pain for saving a few KB of disk space.
  2. Always copy the required dlls locally. If you are really sure that the application won't need it you can simply delete the unnessesary dlls later or don't include them in the installer. But if your application will call ANY reference there it will crash at runtime. So best option is to leave them there (after all they WERE referenced for a reason).
  3. No, it's not possible (at least not without much efford) to have .Net load dlls from arbitrary locations on the disk. And it should be this way (look up DLL-hell if you want to know why).
Foxfire
Unfortunately having to rely on local copies of any dlls is not an option - This is due to the requirements of the project, as the client would like stand alone exe's that they can run. That is why I have added my dll to the GAC.
Adam
That's lipstick on a pig. It is *not* a stand alone exe, it needs an assembly in the GAC and an xml file somewhere that configures it. The only point of having a "stand alone exe" is not requiring an installer. That's a pig that won't fly.
Hans Passant
It needs to be stand-alone to the point of being able to be run from any directory on the host machine. The client wants a clean directory full of exe's they can run, not a directory full of exe's and supporting DLL's/xml files.I've actually almost got it working, by simply adding the log4net.dll to the GAC, except now I've got a problem where it's not picking up the xml file. However, it's a step forward.I agree with your thoughts that it may not be the best solution, however unfortunaely it is no my design, and I am limited to the framework that our customer wants. Many thanks
Adam
IMHO creating buggy applications because the customer requests is is not particulary wise. In my experience it usually pays off to actually hint to the customer that relying on .exe files with no additional files in a "directory" is not a particulary good requirement (I could somehow understand it if it wouldn't need an installer, but it does). You could use a linker, but that doesn't solve your problem with the xml file.
Foxfire
A: 

I suspect your problem is the configuration. You must use fully qualified names if you want it to work from the GAC. As per the documentation at http://logging.apache.org/log4net/release/faq.html:

"When loading an assembly from the GAC the fully qualified assembly name, including the version, culture and public key must be specified. This is in the standard syntax supported by System.Type.GetType. See the next FAQ on how to get the version and public key for an assembly."

Tom Cabanski
Thank you for your update, however I am confused at how I would need to change my appender. Here is my appender tag: <appender name="ProcessLogFile" type="log4net.Appender.RollingFileAppender" >I then refernce this with an appender-ref. i.e: <appender-ref ref="ProcessLogFile"/>At no point do I actually use the name of the class that is in the GAC.
Adam
I just pulled what was in the docs. It says that if you put log4net in the GAC, you have to use the full name in the config. I do know that if you create object instances via reflection, you cannot create instances out of the GAC unless your type name includes the version and public key.
Tom Cabanski
A: 

I managed to resolve this by adding Log4net.dll to the GAC as well. It will now run without needing a local copy the dll.

It does however require a local copy of the XML file, to correctly log.

Adam