Hi Folks,
I got an Auto-Updating Application that is supposed to download all the
assemblies needed from a deployment machine when started.
Here ist the Code for the Launcher that has to be deployed to the Machine
actually running the Code. All other Stuff should be downloaded upon
execution time.
using System;
using System.Management;
using System.Management.Instrumentation;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;
using System.IO;
using System.Security;
using System.Security.Policy;
using System.Security.Permissions;
using System.Collections;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using System.Net;
using System.Diagnostics;
using System.Threading;
namespace Launcher
{
/// <summary>
/// Summary description for Launcher.
/// </summary>
public class Launcher
{
public static string ConfigFile = "ServerConfig.xml";
public static string AssemblyFile = "SharedAssembly.dll";
public static string DeploymentServer = "http://servername/Deployment/";
public static string CodeGroup = "3DEM";
public static Assembly AssemblyResolveEventHandler(System.Object sender,
System.ResolveEventArgs e)
{
AppDomain domain = (AppDomain) sender;
// e.Name gives the assembly display name that was requested
int commaPos = e.Name.IndexOf(",", 0, e.Name.Length);
String name = e.Name;
if (commaPos > 0) name = e.Name.Substring(0, commaPos);
if (name.EndsWith(".resources")) name = e.Name.Substring(0, name.Length -
10);
Assembly foundAss = null;
WebPermission perm = new WebPermission(NetworkAccess.Connect,
DeploymentServer + name + ".dll");
perm.Assert();
String fileName = DeploymentServer + name + ".dll";
foundAss = Assembly.LoadFrom(fileName);
Console.WriteLine("AliGUI loaded Assembly: " + fileName);
CodeAccessPermission.RevertAssert();
return foundAss;
}
public Launcher()
{
//
// TODO: Add constructor logic here
//
}
[STAThread]
static void Main()
{
try
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new
ResolveEventHandler(AssemblyResolveEventHandler);
IEnumerator levels = System.Security.SecurityManager.PolicyHierarchy();
while (levels.MoveNext())
{
PolicyLevel level = (PolicyLevel)levels.Current;
CodeGroup group = level.RootCodeGroup;
if (level.Label.ToString( ) == "Machine")
{
if (group.MembershipCondition.ToString( ) == "All code")
{
System.Security.PermissionSet permSetFulltrust =
level.GetNamedPermissionSet("FullTrust");
System.Security.Policy.UrlMembershipCondition
objUrlMembershipCondition = new UrlMembershipCondition(DeploymentServer+"*");
group.AddChild(new
System.Security.Policy.UnionCodeGroup(objUrlMember shipCondition, new
System.Security.Policy.PolicyStatement(permSetFull trust)));
System.Security.Policy.UnionCodeGroup UnionCodeGroupObject =
new System.Security.Policy.UnionCodeGroup (objUrlMembershipCondition
, new System.Security.Policy.PolicyStatement (permSetFulltrust));
UnionCodeGroupObject.Name = CodeGroup;
group.AddChild(UnionCodeGroupObject);
System.Security.SecurityManager.SavePolicy( );
}
}
}
string codeBase = "http://servername/Deployment/";
Assembly uiAssembly = Assembly.LoadFrom(codeBase +
"AliGUI.exe");
Type type = uiAssembly.GetType("empGui.Form_Ali_Setup", true, false);
Console.WriteLine("Assembly Name: " +
type.AssemblyQualifiedName.ToString());
Console.WriteLine("CodeBase: " + type.Assembly.CodeBase);
System.Reflection.AssemblyName[] deps =
type.Assembly.GetReferencedAssemblies();
Console.WriteLine("Dependencies:");
foreach(System.Reflection.AssemblyName dep in deps)
{
Console.WriteLine(dep.ToString());
//Console.WriteLine(dep.CodeBase.ToString());
}
Application.Run((Form)Activator.CreateInstance(typ e));
/*Console.WriteLine("Press any Key to exit");
Console.ReadLine();*/
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
}
}
}
This simply works for Windows XP machines where Visual Studio is installed.
In this case, the output looks like this:
Assembly Name: empGui.Form_Ali_Setup, AliGUI, Version=1.0.0.6,
Culture=neutral,
PublicKeyToken=null
CodeBase: http://servername/Deployment/AliGUI.exe
Dependencies:
System.Web.Services, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7
f11d50a3a
System.Windows.Forms, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b77a5c
561934e089
mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Drawing, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d5
0a3a
empDll, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null
ClientAssembly, Version=1.1.0.6, Culture=neutral, PublicKeyToken=null
System.Xml, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
SharedAssembly, Version=1.1.0.6, Culture=neutral, PublicKeyToken=null
AliGUI loaded Assembly: http://servername/Deployment/SharedAssembly.dll
AliGUI loaded Assembly: http://servername/Deployment/SharedAssembly.dll
AliGUI loaded Assembly: http://servername/Deployment/empDll.dll
AliGUI loaded Assembly: http://servername/Deployment/SharedAssembly.dll
As you can see here, an AssemblyResolve Event is fired and the Handler
redirects to the Deployment URL, like it should be.
On machines where Visual Studio ist not installed, I get the following output:
Assembly Name: empGui.Form_Ali_Setup, AliGUI, Version=1.0.0.6,
Culture=neutral,
PublicKeyToken=null
CodeBase: http://servername/Deployment/AliGUI.exe
Dependencies:
System.Web.Services, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7
f11d50a3a
System.Windows.Forms, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b77a5c
561934e089
mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Drawing, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d5
0a3a
empDll, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null
ClientAssembly, Version=1.1.0.6, Culture=neutral, PublicKeyToken=null
System.Xml, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
SharedAssembly, Version=1.1.0.6, Culture=neutral, PublicKeyToken=null
Now at this Point I get a "File not Found" exception. The assembly "empDll"
or one of it`s components can not be found.
The AssemblyResolve Event is never fired.
When I copy the assembly "empDll" locally into the directory where the
launcher is, everything works fine again but in this case the
Auto-Update-Feature does not work of course and everything is useless.
In this case, the output is the following:
Assembly Name: empGui.Form_Ali_Setup, AliGUI, Version=1.0.0.6,
Culture=neutral,
PublicKeyToken=null
CodeBase: http://servername/Deployment/AliGUI.exe
Dependencies:
System.Web.Services, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7
f11d50a3a
System.Windows.Forms, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b77a5c
561934e089
mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Drawing, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d5
0a3a
empDll, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null
ClientAssembly, Version=1.1.0.6, Culture=neutral, PublicKeyToken=null
System.Xml, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
SharedAssembly, Version=1.1.0.6, Culture=neutral, PublicKeyToken=null
AliGUI loaded Assembly: http://servername/Deployment/SharedAssembly.dll
AliGUI loaded Assembly: http://servername/Deployment/SharedAssembly.dll
AliGUI loaded Assembly: http://servername/Deployment/SharedAssembly.dll
AliGUI loaded Assembly: http://servername/Deployment/SharedAssembly.dll
As you can see, the Assembly "empDll" is loaded locally but the dependencies
are downloaded from the deployment machine.
As I already mentioned, the only differnce between the machines where Auto
Updating works and the AssemblyResolve Event is fired and handeled and the
machines where the file not found exception occurs is that on the working
machines
Visual Studio .Net is installed and on the Machines with file not found
exception there is just .Net Framework 1.1 from Windows update.
The special thing about "empDll" is that it is a managed c++ dll that is
linked against native libs.
Is there any difference between the .NET Framework from Windows Update and
from Visual Studio or does anybody have any other idea what may be the
difference between the machines here or how to force the AssemblyResolve
Event to be fired?
Thanks in Advance for your efforts
Best Regards
Chucker