[英]Accessing information in the AssemblyInfo.cs using Reflection in a Web Site
我创建了一个DLL,它将从AssemblyInfo.cs收集信息。 在类构造函数中,我使用Reflection来获取正在运行的最顶层的应用程序。
public class AppInfo()
{
public AppInfo()
{
System.Reflection.Assembly assembly =
System.Reflection.Assembly.GetEntryAssembly();
if (assembly == null)
assembly = System.Reflection.Assembly.GetCallingAssembly();
//code to gather needed information
}
}
这是如何使用的,如果我从给定应用程序MyApp中的任何DLL调用它,可以说该名称将始终为“MyApp”。 检索该信息不是问题,它在Windows服务和Windows应用程序中运行良好。 我的问题是: 如何获得最顶级网站的大会?
我找到了一些文章,我可以通过将网站的AssemblyInfo.cs移出App_Code文件夹并进入网站的根目录来获取Global.asax.cs中的信息。 然后通过将compilerOption添加到AssemblyInfo.cs的物理路径
<compiler
language="c#;cs;csharp"
extension=".cs"
compilerOptions="C:\Sandbox\MyWebSite\AssemblyInfo.cs"
type="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
使用它我能够通过System.Reflection.Assembly.GetExecutingAssembly()
在AssemblyInfo.cs中检索网站的信息。 现在我可以重载我的AppInfo
类的构造函数来接受Assembly
并以这种方式检索信息,但是如果MyWebSite
使用的另一个DLL创建一个new AppInfo()
我将获得该DLL的程序集信息而不是父网站。
我知道如果我使用的是Web应用程序而不是Web站点,我就不会遇到这个问题,但由于我不会进入的原因,我无法使用Web应用程序。 关于如何从我正在运行的网站的AssemblyInfo.cs中读取信息的任何建议,无论我在哪个DLL中?
编辑:我需要这个适用于网站,Windows应用程序和Windows服务
如果我理解你正确,问题是Assembly.GetEntryAssembly()
在一个网站并返回null Assembly.GetCallingAssembly()
将返回错误的事情,因为你已经有了致使不是直接调用该网站的调用链。 如果是这种情况,您可以使用堆栈跟踪找到“Entry Assembly”并向后移动调用帧。 堆栈将充满来自System.Web等的引用,因为调用将来自IIS内部的深处,但您应该能够通过抓住可以肯定识别的最低帧来挑选您感兴趣的程序集。属于你。 请注意,这是非常hacky,但我认为它会得到你想要的...
var trace = new StackTrace();
Assembly entryAssembly = null;
foreach (var frame in trace.GetFrames())
{
var assembly = frame.GetMethod().DeclaringType.Assembly;
//check if the assembly is one you own & therefore could be your logical
//"entry assembly". You could do this by checking the prefix of the
//Assembly Name if you use some standardised naming convention, or perhaps
//looking at the AssemblyCompanyAttribute, etc
if ("assembly is one of mine")
{
entryAssembly = assembly;
}
}
希望其他人能够提出一种不那么讨厌的方式......但是如果你真的被困住了,这可能会有所帮助。
AppDomains是按网站创建的,然后bin * .dll文件将加载到该应用程序的AppDomain中。 该网站没有“大师大会”,至少没有任何特殊含义。
这是一个过程。 System.Web.Hosting.ProcessHost这产生System.Web.ApplicationHost通过的组合System.Web.Hosting.ApplicationManger和System.Web.Hosting.Environment然后为应用程序创建一个System.AppDomain。
AppDomain非常安全,所以除非你知道如何进入AppDomain,否则你运气不好。
如果您可以更新您的问题,有人可能会提供更多帮助。
如果没有正确设置安全性,您可以这样做“
String binDir = Server.MapPath("/bin/");
Response.Write(String.Format("Bin dir:{0}<br/><br/>",binDir));
foreach (string file in Directory.GetFiles(binDir, "*.dll"))
{
Response.Write(String.Format("File:{0}<br/>", file));
try
{
Assembly assembly = Assembly.LoadFile(file);
object[] attrinutes = assembly.GetCustomAttributes(true);
foreach (var o in attrinutes)
{
//AssemblyCompanyAttribute is set in the AssemblyInfo.cs
if (o is AssemblyCompanyAttribute)
{
Response.Write(String.Format("Company Attribute: Company = {0}<br/>", ((AssemblyCompanyAttribute)o).Company));
continue;
}
Response.Write(String.Format("Attribute: {0}<br/>", o));
}
}
catch(Exception ex)
{
Response.Write(String.Format("Exception Reading File: {0} Exception: {1}",file,ex));
}
}
您在此假设主站点未编译(具有App_Code目录)并且与您的子站点位于同一应用程序池中。 您是否需要访问权限? 主站点是共享主机站点还是什么?
越轨是对的。 但是,如果可以,您应该使用Assembly.Load而不是Assembly.LoadFile。
这是一个很好的参考:
http://gisresearch.blogspot.com/2007/09/assembly-load-loadfrom-loadfile.html
使用Alconja的建议我正在检查assembly.GlobalAssemblyCache,直到我发现第一个在那里。 不存在的最后一个是我认为入口组件的第一个我自己的dll。
如果只知道程序集名称和类型名称,下面的类有助于获取Type对象。
public static class AssemblyHandler {
private static Dictionary<String, Assembly> Assemblies;
public static Assembly GetAssembly(String Name) {
if (Assemblies == null) {
Assemblies = new Dictionary<string, Assembly>();
var mainAsm = Assembly.GetEntryAssembly();
if (mainAsm == null) {
var trace = new StackTrace();
foreach (var frame in trace.GetFrames()) {
var assembly = frame.GetMethod().DeclaringType.Assembly;
if (assembly.GlobalAssemblyCache) {
break;
}
mainAsm = assembly;
}
}
Assemblies.Add(mainAsm.FullName, mainAsm);
ScanReferencedAssemblies(mainAsm);
}
if (!Assemblies.ContainsKey(Name)) {
return null;
}
return Assemblies[Name];
}
private static void ScanReferencedAssemblies(Assembly Asm) {
foreach (var refAsmName in Asm.GetReferencedAssemblies()) {
Assembly a = Assembly.Load(refAsmName);
if (a.GlobalAssemblyCache) {
continue;
}
if (!Assemblies.ContainsKey(a.FullName)) {
Assemblies.Add(a.FullName, a);
ScanReferencedAssemblies(a);
}
}
}
public static Type GetType(string AssemblyName, string TypeName) {
return GetAssembly(AssemblyName).GetType(TypeName);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.