01-13-2010 09:27 AM
Hi
I try to run a net assembly in TS wich uses configuration data.
I am not able to link to my named section with System.Configuration.Sections["ABC"]
it will crash with an Exception. That my assembly-file is not found!
but this file is peresent !!
Loading the config is done by
Configuration config = ConfigurationManager.OpenExeConfiguration(spath);
Also System.Reflection.Assembly.GetEntryAssembly();
will return null
If i use it whitout Teststand it is woking fine !
Any thoughts ?
Juergen
Solved! Go to Solution.
01-13-2010 10:40 AM
01-14-2010 11:36 AM
TestStand runs .NET steps in a separate appdomain, that is why you get NULL for System.Reflection.Assembly.GetEntryAssembly();. I suggest you get the path for your exe using the following API instead:
System.Windows.Forms.Application.ExecutablePath
This does require you to add a reference to System.Windows.Forms, but you are likely using that assembly already.
Hope this helps,
-Doug
01-14-2010 02:47 PM
Hi Doug,
To get the path to the assembley i have used
Assembly assy = typeof(MySection).Assembly;
instead. So my path is pesent. i also check if config file is present
But
Configuration config = ConfigurationManager.OpenExeConfiguration(m_strPathAssembly);
is running into an execption that says my .config could not be opend.
I tried OpenMappedExeConfiguration, Too. This is working.
but when calling config.GetSection("xxx") i am running into the same exception.
Any thoughts
Juergen
See attached VS8 example (i am at home 🙂
01-14-2010 06:20 PM
It looks like you are running into an issue that is a variation of the one from this forum post:
http://forums.ni.com/ni/board/message?message.uid=1008210#U1008210
Basically, because your assembly, when run from teststand, is loaded using the LoadFrom context, the Configuration code (I'm guessing it does some sort of deserialization) needs to access your assembly's types in the Load context so it tries to load it in that context, but can't because your assembly is not in the GAC or application base path so it can't find it. You can use similar workarounds (or maybe even the same workarounds) as in the forum thread linked to above.
Namely, one of the following:
1) put your assembly in the GAC
or
2) register an AssemblyResolve event handler on the teststand execution appdomain that redirects references to your assembly to the one already in memory.
If you go with 2) I think you might have one additional issue to deal with that the user from the other forum post did not. It seems that if the version of the assembly referenced in the saved info in the config file is not the same as the one you have loaded, you also need to redirect references to that older version to your assembly as well (If you never change the version of the assembly this won't be an issue though). Here's an example AssemblyResolve handler that worked in my test case:
static System.Reflection.Assembly AssemblyResolveEventHandler(System.Object sender, System.ResolveEventArgs args)
{
if (args.Name.StartsWith("MyAssemblyName"))
return System.Reflection.Assembly.GetExecutingAssembly();
else
return null;
}
You need to register this event handler once as follows before executing your other code:
static bool assemblyResolveRegistered = false;
if (!assemblyResolveRegistered)
{
AppDomain.CurrentDomain.AssemblyResolve += new System.ResolveEventHandler(AssemblyResolveEventHandler);
assemblyResolveRegistered = true
}
Also take a look at and/or try the workaround code in the above forum post too as that one is a bit more general purpose and more robust (i.e. multi-threadsafe) in the way it registers the AssemblyResolve event handlers. Either way, hope this helps,
-Doug
01-15-2010 01:36 AM
01-15-2010 09:55 AM
I googled about the .config file with a GAC assembly and found this:
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/2710647c-6414-42c4-90b7-fd7603f55ae0
From a post in that link:
"You are right in that you cannot add text files to the GAC. However I did some more research and found that I can use the ConfigurationManager.OpenMappedExeConfiguration method to provide the full path name of the config file. "
So it sounds like you can store the config file elsewhere and use it with an assembly in the GAC, or you can go with solution 2) above and use the AssemblyResolve event handler instead of putting the assembly in the GAC.
01-15-2010 03:31 PM
Hi Doug,
Thanks for your reply.
You are right OpenMappedExeConfiguration could be a solution. I have also pointed out in upper message.
BTW i tried it once more with using the GAC and C:\default.config. If you try to run it via TS --> LoadFrom()
you are running into an exception.
I have used for research msdn.com and a really great thread on
http://www.codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx
With no idea
Juergen
01-18-2010 09:46 AM
TestStand does not load assemblies from the GAC using LoadFrom, that only applies to assemblies that you specify by path (you are specifying the one in the GAC by strongname right?). If you still don't have a solution, I recommend not using the GAC and instead using the AssemblyResolve event as I was able to workaround the problem in your attached code that way. I am not at all familiar with the Configuration API though so perhaps that's not the correct way to do things.
-Doug
01-18-2010 10:26 AM - edited 01-18-2010 10:27 AM
Hi Doug,
Normally I do not load from the GAC, This was just a test issue to demonstrate that it is not running by using GAC, too.
My first choise is to load the assembley by Path.
OpenMappedExeConfiguration will run, but after this next call to GetSection will fail this mentioned
file access. I have solved my issue by using a bruce force wrapper.
I am loading my stuff as XmlDocument a do some XPath parsing to get the attributes values.
But i am courious on your solution, because i am not using the great feature of GetSection.
Juergen