NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Loading app.config stuff from .net assembly

Solved!
Go to solution

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

--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 1 of 18
(7,715 Views)

Hi

 

this attachement should show the issue

 

Juergen 

--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 2 of 18
(7,707 Views)

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

0 Kudos
Message 3 of 18
(7,683 Views)

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 🙂 

 

 

--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 4 of 18
(7,675 Views)

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

Message 5 of 18
(7,668 Views)

Hi Doug

 

Thanks for your reply!

 

I will try solution 1

 

But now my .config file is really missing in GAC !

Is there a way to install it with gacutil. I found no way ??

 

Juergen

 

 

 

--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 6 of 18
(7,660 Views)

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.

0 Kudos
Message 7 of 18
(7,648 Views)

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

 

 

 

 

 

 

--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 8 of 18
(7,638 Views)

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

0 Kudos
Message 9 of 18
(7,611 Views)

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

Message Edited by j_dodek on 01-18-2010 05:27 PM
--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 10 of 18
(7,607 Views)