Reflection gives different results

J

John Rivers

Using Fusion Log Viewer I have found a difference that may be the
cause

using Assembly.LoadFile() or Assembly.LoadFrom() gives "LOG: Assembly
is loaded in LoadFrom load context."
using a File Reference gives "LOG: Assembly is loaded in default load
context."

http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx

Now I am trying to figure out how to use Assembly.Load() to load a
file
 
J

John Rivers

I have found a workaround - but it is overly complex and I am not
happy with it

The problem is related to the Assembly Load Context - for this to work
the ConnectionDlg.dll *must* load in the DefaultContext

My understanding of dot net code access security is very limited - I
don't think it is possible to alter the AppBase or PrivateBinPath of a
running assembly

So the workaround creates an AppDomain that trusts my EXE completely
with an AppBase and PrivateBinPath set to the folder containing
ConnectionDlg.dll

and then uses CreateInstanceAndUnwrap() to create an instance of
Personalization (luckily this works)
and then just use InvokeMember() as usual

Watching this in Fusion Log Viewer shows "LOG: Assembly is loaded in
default load context."

I am sure there is a better solution that simply involves using
Assembly.Load() to load the dll into the default context
I will research that now

I haven't posted the code because it is long winded and ugly - if
anybody wants to see it I will post it
 
J

John Rivers

Seems I am talking to myself now
But it might be useful to someone else, so I will carry on ...

There is a fairly simple workaround for this problem:

Copy the DLL from the default location to any location under the
AppBase of the currently executing assembly!

The problem now is resolving references - by copying them also into a
trusted location on the filesystem
 
J

John Rivers

this seems to work OK
but I think it is easier to BinaryFormatter.Deserialize the mru.dat
file and scan it myself ... that is all ConnectionDlg.dll does anyway

string[] GetMRU_CopyDLL() {

const string regPathBinnFolder = @"SOFTWARE\Microsoft\Microsoft SQL
Server\90\Tools\ClientSetup";

const string assName = "ConnectionDlg";
const string dllName = assName + ".dll";

const string typeNamePersonalization =
"Microsoft.SqlServer.Management.UI.ConnectionDlg.Personalization";
const string typeNameSqlServerType =
"Microsoft.SqlServer.Management.UI.ConnectionDlg.SqlServerType";

try {

string folderBinn;

// open
using (RegistryKey regKeyBinnFolder =
Registry.LocalMachine.OpenSubKey(regPathBinnFolder)) {

//
if (regKeyBinnFolder == null) return null; // nothing to do

// create path to dll from registry key etc.
folderBinn = (string)regKeyBinnFolder.GetValue("Path");

}//using

// calculate paths
string folderConnDlg = Path.Combine(folderBinn, @"VSShell\Common7\IDE
\");
string pathConnDlg = Path.Combine(folderConnDlg, dllName);

// check dll exists
if (!File.Exists(pathConnDlg)) return null; // nothing to do

// create trusted path for dll
string trustedPathConnDlg = Path.Combine
(AppDomain.CurrentDomain.BaseDirectory, dllName);

// todo: worry about locks on the file from ssms etc.
File.Copy(pathConnDlg, trustedPathConnDlg, true);

//
Assembly assCurrent = Assembly.GetExecutingAssembly();
Assembly assConnDlg = Assembly.Load(assName, assCurrent.Evidence);

//
Type typePersonalization = assConnDlg.GetType
(typeNamePersonalization);

//
//Guid guidServerType = new Guid(@"8c91a03d-f9b4-46c0-a305-
b5dcc79ff907");
Guid guidServerType = (Guid)assConnDlg.GetType
(typeNameSqlServerType).GetField("ServerType").GetValue(null);

//
//BindingFlags bindFlags = BindingFlags.Public | BindingFlags.Static
| BindingFlags.InvokeMethod;
BindingFlags bindFlags = BindingFlags.InvokeMethod;
int count = (int)typePersonalization.InvokeMember
("GetCountByServerType", bindFlags, null, null, new object[]
{ guidServerType });

//
string[] engines = new string[count];
typePersonalization.InvokeMember("GetStringsByServerType",
bindFlags, null, null, new object[] { guidServerType, engines,
count });

//
return engines;

} catch (Exception exc) {
// oh well
return null;
}//try

}//method
 

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