Custom Configuration - dll

J

Jeff Hegedus

I have a dll that requires some configuration data. I put the configuration
data in a custom configuration section in a config file that is loaded in
the installation folder of the dll. If I install the dll to the same
directory as the exe which uses it, everything works as expected but if I
load the dll in any other directory, I get the following error...

2007-02-04 16:36:51,171 [1] DEBUG CentrifugeBHO.CentrifugeBHO [(null)] -
dllPath =
C:\Projects\VSS\Centrifuge\InformationCentrifuge\CentrifugeBHO\bin\Debug\CentrifugeBHO.dll
2007-02-04 16:36:51,202 [1] DEBUG CentrifugeBHO.CentrifugeBHO [(null)] -
Assembly.GetExecutingAssembly().FullName = CentrifugeBHO, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=558ea11974e40b85
2007-02-04 16:36:51,202 [1] DEBUG CentrifugeBHO.CentrifugeBHO [(null)] -
Exception1
2007-02-04 16:36:51,202 [1] DEBUG CentrifugeBHO.CentrifugeBHO [(null)] - An
error occurred creating the configuration section handler for dllConfig:
Could not load file or assembly 'CentrifugeBHO, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=558ea11974e40b85' or one of its
dependencies. The system cannot find the file specified.
(C:\Projects\VSS\Centrifuge\InformationCentrifuge\CentrifugeBHO\bin\Debug\CentrifugeBHO.dll.config
line 6)
2007-02-04 16:36:51,218 [1] DEBUG CentrifugeBHO.CentrifugeBHO [(null)] -
at
System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String
configKey, Boolean& isRootDeclaredHere)
at
System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String
configKey, Boolean getLkg, Boolean checkPermission, Boolean
getRuntimeObject, Boolean requestIsHere, Object& result, Object&
resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String
configKey, Boolean getLkg, Boolean checkPermission)
at System.Configuration.ConfigurationSectionCollection.Get(String name)
at System.Configuration.ConfigurationSectionCollection.get_Item(String
name)
at CentrifugeBHO.CentrifugeBHO.OnDocumentComplete(Object frame, Object&
urlObj) in
C:\Projects\VSS\Centrifuge\InformationCentrifuge\CentrifugeBHO\CentrifugeBHO.cs:line
268



Here is the config file...

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="dllConfig"
type="CentrifugeBHO.CentrifugeConfigurationSection, CentrifugeBHO,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=558ea11974e40b85"
allowLocation="true" allowDefinition="Everywhere"
allowExeDefinition="MachineToApplication" restartOnExternalChanges="true"
requirePermission="true" />
</configSections>
<dllConfig fileName="default.txt" maxIdleTime="01:30:30" permission="Read"
/>
</configuration>



The following line is where the error is occuring...

<section name="dllConfig"
type="CentrifugeBHO.CentrifugeConfigurationSection, CentrifugeBHO,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=558ea11974e40b85"
allowLocation="true" allowDefinition="Everywhere"
allowExeDefinition="MachineToApplication" restartOnExternalChanges="true"
requirePermission="true" />



I have also tried using a full path as below instead of just an assembly
name with the same results...

<section name="dllConfig"
type="CentrifugeBHO.CentrifugeConfigurationSection,
file:///C:/Projects/VSS/Centrifuge/InformationCentrifuge/CentrifugeBHO/bin/Debug/CentrifugeBHO.dll,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=558ea11974e40b85"
allowLocation="true" allowDefinition="Everywhere"
allowExeDefinition="MachineToApplication" restartOnExternalChanges="true"
requirePermission="true" />



Here is the code that loads the configuration in the dll...

log.Debug("dllPath = " + dllPath);
System.Configuration.Configuration config = null;

// Get the application configuration file.
try
{
config =
System.Configuration
.ConfigurationManager
.OpenExeConfiguration(dllPath);
//.OpenExeConfiguration("C:\\Documents and
Settings\\jhegedus\\My
Documents\\projects\\C#\\InformationCentrifuge\\CentrifugeBHO\\bin\\Debug\\CentrifugeBHO.dll");
}
catch (Exception e)
{
log.Debug(e.Message);
log.Debug(e.StackTrace);
throw (e);
}

// If the section does not exist in the configuration
// file, create it and save it to the file.
String customSectionName = "dllConfig";

try
{
log.Debug("Assembly.GetExecutingAssembly().FullName = " +
Assembly.GetExecutingAssembly().FullName);
if (config.Sections[customSectionName] == null)
{
log.Debug("config.Sections[customSectionName] == null");
//uugh();
CentrifugeConfigurationSection custSection = new
CentrifugeConfigurationSection();
config.Sections.Add(customSectionName, custSection);
custSection =
(CentrifugeConfigurationSection)config.GetSection(customSectionName);
custSection.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
}
}
catch (Exception e)
{
log.Debug("Exception1");
log.Debug(e.Message);
log.Debug(e.StackTrace);
throw (e);
}



Do you have any suggestions to resolve the problem?

Thanks in advance,



Jeff
 
S

Steven Cheng[MSFT]

Hello Jeff,

From your description, you're getting "could not find file or assembly ..."
error when try launch an .net application which read some custom
configuration sectino data from app.config file, correct?

As the error message indicate, the problem here is that the .net runtime
can not correctly find the assembly for your custom configuration section.
And based on my previous description, I think the cause here is that you
did not put the custom configuration section assembly in the .NET runtime's
expected searching path. For .net framework application, its runtime
host(CLR runtime) has a regular rule of how to search for dependency
assemblies. Generally, when an .net application need to locate a certain
assembly it references, it will go through the following steps:

**if the referenced assembly is strong-named, lookup the GAC first

**if GAC not exists, look into Application configureation file(App.config)
to see whether there is codebase setting indicate a specfiic location of
the assembly(on file system or over internet)

**Perform local assembly probing under the application's root folder(you
can configure which sub folders to probing in app.config file).

Here is the MSDN refernce that detailedly describe this:

#How the Runtime Locates Assemblies
http://msdn2.microsoft.com/en-us/library/yx7xezcf.aspx

For your scenario, I think you can consider the following options to deploy
the assembly of your custom configuration section:

1. strong-named your assembly and put it into machine's GAC so that any
..net application running on that machine can locate it(if it has referenced
your assembly).

2. Use <codebase> setting to specify a particular location(such as file
system path or http web url) for your assembly, you can put the <codebase>
setting in the certain application(which want to reference that custom
assembly)'s app.config file. For syntax setting, you can refer to the
following document:

#Specifying an Assembly's Location
http://msdn2.microsoft.com/en-us/library/4191fzwb.aspx

#<codeBase> Element
http://msdn2.microsoft.com/en-us/library/efs781xb.aspx

BTW, you should not put file path in the "type" attribute of the <section
element(only assembly name is necessary), searching path is determined by
the .NET's CLR searching rules as described above.


3. Put the assembly in same directory with the .net application(exe) which
reference that certain assembly.

Hope this helps. If you have anything unclear or any further questions on
this, please feel free to let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================



This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeff Hegedus

Steven,

Thanks for the reply. I have been able to make option#3 work but it is not
my first choice as I am not sure where the exe might be that uses the
assembly. I have examined the article on how the runtime locates assemblies
and tried both installing in the GAC and using the <codeBase> element. I
had not had any luck as of yet which is why I posted to the group. I'll
continue trying now that I have confirmation that I am on the right track.
I'll post back to the group once I have resolved or if I continue to have
difficulties.

Thanks,



Jeff
 
S

Steven Cheng[MSFT]

Thanks for your reply Jeff,

As for the following things you mentioned:

=================
I have examined the article on how the runtime locates assemblies
and tried both installing in the GAC and using the <codeBase> element. I
had not had any luck as of yet which is why I posted to the group.
===============

If you put the assembly into GAC, then you no longer need to use <codebase>
or copy it to the same directory as the exe and any application on the
machine that reference it can locate it from GAC. However, you need to
first strong-name that assembly(only strong-named asssembly can be
installed into GAC). Here are some knowledge base articles demonstrate on
creating strong-name assembly and deply them in GAC:


#Creating and Using Strong-Named Assemblies
http://msdn2.microsoft.com/en-us/library/xwb8f617.aspx

#How to install an assembly in the Global Assembly Cache in Visual Basic
..NET or in Visual Basic 20
http://support.microsoft.com/kb/315682/en-us

#How to consume assemblies that are located in a folder that is different
from the application base folder in Visual Basic .NET or in Visual Basic
2005
http://support.microsoft.com/kb/897297/en-us


If you need any further help on this, please feel free to post here.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeff Hegedus

Steven,

I have tried all options and none seems to work with the exception of
installing the assembly in the same folder as the exe which is not my
preferred option. The exe in this case is InternetExplorer and the dll is a
browser helper object. The dll has a configuration file that has a custom
configuration section in it. The dll itself is found correctly for any of
the three scenarios, but the only scenario in which the custom config
section is successfully loaded is when the dll is is installed in the same
folder as the exe.

The exe is not a .NET assembly and so it does not have a config file I can
use to set up assembly loading. It is calling my dll through COM Interop.
It does not appear that the information in the config file I load with the
dll is used by the .NET loading process. I don't understand why it doesn't
work when the dll is loaded into the GAC though.

I have a few more ideas I want to try and will let you know if they are
successful. If you have any other ideas that might help, I would appreciate
them.

Thanks,



Jeff
 
S

Steven Cheng[MSFT]

Thanks for your reply Jeff,

As you mentioned that the exe is IE and the dll is a BHO assembly, this is
very important since IE is not a managed application. Also, as for the
configuration file, are you putting it in the same directory with
IE(iexplore.exe ) and rename it as iexplore.exe.config? This is necessary
because .net assembly doesn't have runtime config file, only exe can have a
config file to manage the .net runtime settings.

Also, i'm bit surprised that installing assembly into GAC doesn't work.

for managed BHO dev and deploy, you can refer to this article:

#Building Browser Helper Objects using Managed Code
http://simonguest.com/blogs/smguest/archive/2006/11/19/Building-Browser-Help
er-Objects-using-Managed-Code.aspx

In addition, I suggest you try using the fuslogvw.exe utility to trace the
assembly binding failure, this is a very useful tool on troubleshooting
.net CLR assembly loading issue:

#Assembly Binding Log Viewer (Fuslogvw.exe)
http://msdn2.microsoft.com/en-us/library/e74a18c4(VS.80).aspx

Please feel free to let me know your result.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

Steven Cheng[MSFT]

Hello Jeff,

How are you doing on this issue, have you got any further progress? If
there is anything else we can help, please feel free to followup there.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top