Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell Calling .NET Assembly that uses App.config

Tags:

I have a Powershell script that is loading a .NET assembly (.EXE in my case) and calling a public method that uses the app.config to pull an encrypted connection string.

The script dynamically copies the assembly's exe.config over to the Powershell ($pshome) folder as powershell.exe.config and is able to run from my development box just fine. The problem is that it doesn't run from a standard Windows Server 2003 installation.

I verified the exe.config is being copied over to the powershell directory correctly. I've run SysInternals Process Explorer and verified that the process was accessing the config files (no file not found messages). I remotely debugged the powershell.exe instance and can see that the assembly is loading fine but cannot access ConfigurationManager.AppSettings[...] values (returns null).

I'm out of ideas. I've read that I may be able to use a separate app domain but I see no examples of doing this with Powershell.

My code does something to the effect of:

$absolute_path = "c:\foo.exe"
$config_path = $absolute_path + ".config"
copy "$config_path" "$pshome\powershell.exe.config" -Force
[Reflection.Assembly]::LoadFrom($absolute_path)
$foo = new-object MyFooAssembly.FooClass
$foo.DoSomething()  

In Vista the code works, in Windows Server 2003 the code does not work.

like image 458
GabeA Avatar asked May 07 '09 16:05

GabeA


2 Answers

Try:

[System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $config_path)
like image 195
Chris Ballard Avatar answered Oct 26 '22 20:10

Chris Ballard


After researching further I found out the cause. At an earlier point in the script I was loading SMO:

$null = [reflection.assembly]::loadwithpartialname("microsoft.sqlserver.smo") 

I believe this some how mangles my configuration settings. The fix was to do as Chris mentions above to this call first:

[System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $null)
$null = [reflection.assembly]::loadwithpartialname("microsoft.sqlserver.smo") 

And then on my second call to another assembly do this:

$config_path = $assembly_exe + ".config"
[System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $config_path)
[Reflection.Assembly]::LoadFrom($assembly_exe)

Problem appears to be solved...

like image 37
GabeA Avatar answered Oct 26 '22 18:10

GabeA