[英]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.