如何在Template Codes 中能够加载所在的Project的Assembly,获取所有Type

1.首先要获取Project对象

2.分析得到Project对象生成的bin路径,也就是$(TargetPath)

3.Assembly.LoadFromFile( binpath )

4.asm.GetTypes(),这里要注意处理Reference Project


代码如下:

1.GetProject()

  Project GetProject()
    {
        var hostServiceProvider = (IServiceProvider)this.Host;
        var dte = (DTE)hostServiceProvider.GetService(typeof(DTE));      
        var item = dte.Solution.FindProjectItem(this.Host.TemplateFile);
        if (item != null && item.ContainingProject != null)
        {
             return item.ContainingProject;
        }
        return null;
    }

2.GetAssemblyPath,GetAssemblyDir(获取bin目录)

 string GetAssemblyPath(EnvDTE.Project vsProject)
        {
            string fullPath = vsProject.Properties.Item("FullPath").Value.ToString();
            string outputPath = vsProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
            string outputDir = Path.Combine(fullPath, outputPath);
            string outputFileName = vsProject.Properties.Item("OutputFileName").Value.ToString();      
            string assemblyPath = Path.Combine(outputDir, outputFileName);
            return assemblyPath;
        }
     string GetAssemblyDir(EnvDTE.Project vsProject)
        {
            string fullPath = vsProject.Properties.Item("FullPath").Value.ToString();
            string outputPath = vsProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
            string outputDir = Path.Combine(fullPath, outputPath);     
            return outputDir;
        }

3.获取asm中所有interface

 Type[] GetInterfaces()
      {
        var p = GetProject();
        string str = GetAssemblyPath(p);    
        var asm = Assembly.LoadFile(str);
        Type[] tps = new Type[]{};
        try
        {                   
            tps = asm.GetTypes();
        }
        catch (ReflectionTypeLoadException ex)
        {
            foreach (Exception loaderException in ex.LoaderExceptions)
            {
                WriteLine(loaderException.ToString());
            }   
        }         
        return tps.ToOtherTypeArrayEx(i=>i.IsInterface,i=>i);
      }


最后要注意Reference :

<#
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
#>
<#+
      System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
         {           
            var strDllDir = GetAssemblyDir(GetProject());
            var strs = args.Name.Split(',');
            var strNeedResolveDllPath = strDllDir + strs[0] + ".dll";
         
            if (System.IO.File.Exists(strNeedResolveDllPath))
                return Assembly.LoadFile(strNeedResolveDllPath);            
            return null;
         }
    #>


一些参考:

http://msdn.microsoft.com/en-us/library/envdte.dte.aspx

http://msdn.microsoft.com/en-us/library/vstudio/gg604090(v=vs.100).aspx

http://stackoverflow.com/questions/3548026/get-referenced-projects-path-in-t4-template

http://stackoverflow.com/questions/12952110/accessing-projects-via-dte-in-c-sharp-t4-template

http://stackoverflow.com/questions/5486593/getting-the-macro-value-of-projects-targetpath-via-dte

http://social.msdn.microsoft.com/Forums/vstudio/en-US/03d9d23f-e633-4a27-9b77-9029735cfa8d/how-to-get-the-right-output-path-from-envdteproject-by-code-if-show-advanced-build?forum=vsx



转载于:https://www.cnblogs.com/norsd/p/6359362.html

在Android,可以使用Java的反射机制获取某个应用程序加载的所有类。以下是一个示例代码: ```java import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Build; import android.util.Log; import java.lang.reflect.Field; import java.util.HashSet; import java.util.Set; public class LoadedClasses { public static Set<String> getAllLoadedClasses(Context context, String packageName) { Set<String> classNames = new HashSet<>(); try { ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(packageName, 0); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { ClassLoader classLoader = context.getClassLoader(); Field pathListField = classLoader.getClass().getDeclaredField("pathList"); pathListField.setAccessible(true); Object dexPathList = pathListField.get(classLoader); Field dexElementsField = dexPathList.getClass().getDeclaredField("dexElements"); dexElementsField.setAccessible(true); Object[] dexElements = (Object[]) dexElementsField.get(dexPathList); for (Object dexElement : dexElements) { Field dexFileField = dexElement.getClass().getDeclaredField("dexFile"); dexFileField.setAccessible(true); Object dexFile = dexFileField.get(dexElement); Method entriesMethod = dexFile.getClass().getDeclaredMethod("entries"); Object entriesObject = entriesMethod.invoke(dexFile); if (entriesObject instanceof Enumeration) { Enumeration<String> entries = (Enumeration<String>) entriesObject; while (entries.hasMoreElements()) { String entry = entries.nextElement(); classNames.add(entry.replace("/", ".")); } } } } else { String apkPath = appInfo.sourceDir; ClassLoader classLoader = LoadedClasses.class.getClassLoader(); Field pathListField = classLoader.getClass().getSuperclass().getDeclaredField("pathList"); pathListField.setAccessible(true); Object dexPathList = pathListField.get(classLoader); Field dexElementsField = dexPathList.getClass().getDeclaredField("dexElements"); dexElementsField.setAccessible(true); Object[] dexElements = (Object[]) dexElementsField.get(dexPathList); for (Object dexElement : dexElements) { Field dexFileField = dexElement.getClass().getDeclaredField("dexFile"); dexFileField.setAccessible(true); Object dexFile = dexFileField.get(dexElement); Method getNameMethod = dexFile.getClass().getDeclaredMethod("getName"); String dexFileName = (String) getNameMethod.invoke(dexFile); if (!apkPath.equals(dexFileName)) { continue; } Method entriesMethod = dexFile.getClass().getDeclaredMethod("entries"); Object entriesObject = entriesMethod.invoke(dexFile); if (entriesObject instanceof Enumeration) { Enumeration<String> entries = (Enumeration<String>) entriesObject; while (entries.hasMoreElements()) { String entry = entries.nextElement(); classNames.add(entry.replace("/", ".")); } } } } } catch (Throwable e) { Log.e("LoadedClasses", "Failed to get all loaded classes", e); } return classNames; } } ``` 这个类定义了一个静态方法`getAllLoadedClasses()`,它接收一个`Context`对象和一个应用程序包名作为参数,返回这个应用程序加载的所有类的类名的集合。这个方法通过反射机制获取应用程序的APK文件路径,然后使用DexClassLoader加载APK的所有类,并遍历所有类获取其类名。需要注意的是,这个方法只能获取已经被加载的类,如果有动态加载的类可能无法被获取到。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值