home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples.exe / Reflector / VC / reflector.cpp < prev   
Encoding:
C/C++ Source or Header  |  2000-06-23  |  7.9 KB  |  309 lines

  1. /*+==========================================================================
  2.   File:      reflector.cpp
  3.  
  4.   Summary:   The purpose of this demo is to introduce NGWS reflection. 
  5.              Reflection is a feature in NGWS that allow object inspection 
  6.              and dynamic invocation. The reflector program uses the NGWS 
  7.              reflection to inspect the methods and properties of the class 
  8.              named on the command line at runtime. You can also invoke the 
  9.              classes methods at runtime by using the command line switches.
  10.  
  11.   Classes:   Reflector
  12.  
  13.   Functions: Run, DumpClass, DumpMethods, Usage, main
  14.  
  15. ----------------------------------------------------------------------------
  16.   This file is part of the Microsoft NGWS Samples.
  17.  
  18.   Copyright (C) 1998-2000 Microsoft Corporation.  All rights reserved.
  19. ==========================================================================+*/
  20. #using <mscorlib.dll>
  21.  
  22. using namespace System;
  23. using namespace System::Reflection;
  24. using namespace System::Text;
  25.  
  26. #define NULL 0
  27.  
  28. [sysimport(dll="msvcrt", charset="ansi")]
  29. extern "C" char* _cdecl strcpy(StringBuilder *dest, char *src);
  30.  
  31. [sysimport(dll="msvcrt", charset="ansi")]
  32. extern "C" int _cdecl strlen(char *str);
  33.  
  34. [sysimport(dll="msvcrt", charset="ansi")]
  35. extern "C" char _cdecl toupper(char c);
  36.  
  37. [sysimport(dll="msvcrt", charset="ansi")]
  38. extern "C" int _cdecl printf(String *fmt, ...);
  39.  
  40. __gc class Reflector
  41. {
  42. public:
  43.     static String *strLoc=L"000oo";
  44.  
  45.     bool methods;
  46.     bool verbose;
  47.     bool implOnly;
  48.     bool invoke;
  49.     String *className;
  50.     String *methName;
  51.     String *callArgs;
  52.  
  53. /*****************************************************************************
  54.  Constructor : Reflector
  55.  
  56.  Abstract:     Constructs an instance of Reflector.
  57.             
  58.  Input Parameters: None
  59.  
  60.  Returns: None
  61. ******************************************************************************/
  62.     Reflector() : methods(false), verbose(false),
  63.                   implOnly(false), invoke(false),
  64.                   className(NULL), methName(NULL),
  65.                   callArgs(NULL)
  66.     {
  67.     }
  68.  
  69. /*****************************************************************************
  70.  Function :    Run
  71.  
  72.  Abstract:     Dumps the class name and its methods stored in "className".
  73.             
  74.  Input Parameters: None
  75.  
  76.  Returns: int (1==error, 0==OK)
  77. ******************************************************************************/
  78.     int Run()
  79.     {
  80.         if (className == NULL)
  81.             return 1;
  82.  
  83.         try {
  84.             DumpClass();
  85.         }
  86.         catch (Exception *e)
  87.         {
  88.             printf(L"Exception: (%s)\n",strLoc);
  89.             printf(L"%s\n",e->StackTrace);
  90.             return 1;
  91.         }
  92.         return 0;
  93.     }
  94.  
  95. /*****************************************************************************
  96.  Function :    DumpClass
  97.  
  98.  Abstract:     Dumps the class "className" and its methods.
  99.             
  100.  Input Parameters: None
  101.  
  102.  Returns: Void
  103. ******************************************************************************/
  104.     void DumpClass()
  105.     {
  106.         String *clsName = String::Concat(className, ",");
  107.         clsName = String::Concat(clsName, className , ".dll");
  108.  
  109.         Type *t = Type::GetType(clsName);
  110.         if (t == NULL) {
  111.             printf(L"ERROR: Class \"%s\" not found\n", className);
  112.             return;
  113.         }
  114.         printf(L"Class: %s\n",t->FullName);
  115.         if (methods)
  116.             DumpMethods(t);
  117.     }
  118.  
  119. /*****************************************************************************
  120.  Function :    DumpMethods
  121.  
  122.  Abstract:     Dumps the class "className" and its methods.  If the bool 
  123.                invoke is true, then the method name "methName" is invoked
  124.                with the arguments "callArgs".
  125.             
  126.  Input Parameters: c (Microsoft::Runtime::Class in which to dump methods)
  127.  
  128.  Returns: Void
  129. ******************************************************************************/
  130.     void DumpMethods(Type *t)
  131.     {
  132.         int in4a = -2;
  133.         strLoc=L"DM_23n";
  134.         MemberInfo *memi2 __gc[] = NULL;
  135.         
  136.         if (methName == NULL)
  137.         {
  138.             // t->GetMethods() returns MethodInfo[]
  139.             memi2 = t->GetMethods();
  140.         }
  141.         else
  142.         {
  143.             memi2 = t->FindMembers(MemberTypes::Method , BindingFlags::NonPublic, 
  144.                     Type::FilterName, methName); // returns MemberInfo[]
  145.         }
  146.     
  147.         printf(L"Methods (%s)\n",Convert::ToString(memi2->Length));
  148.  
  149.         strLoc=L"DM_66n";
  150.  
  151.         if (verbose)
  152.             for (int i=0;i<memi2->Length;i++)
  153.                 printf(L"\t%s\n",(memi2[i])->ToString());
  154.  
  155.         strLoc=L"DM_57x";
  156.  
  157.         if (invoke && memi2->Length == 1) {
  158.  
  159.             Object *o = Activator::CreateInstance(t);
  160.             printf(L"Invoking method \"%s\" on class \"%s\"\n", 
  161.                     memi2[0]->Name, t->FullName);
  162.  
  163.             Object *varRet = NULL;
  164.             Object *var2 __gc[] = (Object*)NULL;
  165.             
  166.             if (callArgs != NULL) {
  167.                 // Construct parameter list.
  168.                 wchar_t split __gc[] = new wchar_t __gc[1];
  169.                 split[0] = L' ';
  170.                 String *str __gc[] = callArgs->Split(split);
  171.                 var2 = new  Object* __gc[str->Length];
  172.  
  173.                 String *a = L"";
  174.                 if (str->Length != 1)
  175.                     a = L"s";
  176.                 printf(L"With %ld argument%s:\n",str->Length,a);
  177.  
  178.                 for (int ii = 0; ii < str->Length; ii++) {
  179.                     printf(L"\tArgument %ld: \"%s\"\n",(ii+1),str[ii]);
  180.  
  181.                     var2[ii] = (dynamic_cast<Object *> (Convert::ToInt32(str[ii])));
  182.                 }                    
  183.             } else {
  184.                 printf(L"With no arguments\n");
  185.             }
  186.                 
  187.             strLoc=L"DM_08u";
  188.  
  189.             try {
  190.                 varRet = (static_cast<MethodInfo*> (memi2[0]))->Invoke(o,var2);
  191.             }
  192.             catch (Exception *e) {
  193.                 printf(L"Invoke Exception: (%s) %s\n", strLoc, e->ToString());
  194.             }
  195.  
  196.             strLoc=L"DM_48k";
  197.             Type *vt = varRet->GetType();
  198.             printf(L"Invocation Results: (%s) ", vt->FullName);
  199.  
  200.             strLoc=L"DM_92c";
  201.             printf(L"%s\n",varRet->ToString());
  202.  
  203.             strLoc=L"DM_61a";
  204.         }
  205.     }
  206.  
  207.  
  208. };
  209.  
  210. /*****************************************************************************
  211.  Function :    Usage
  212.  
  213.  Abstract:     Prints usage for reflector application.
  214.             
  215.  Input Parameters: None
  216.  
  217.  Returns: Void
  218. ******************************************************************************/
  219. void Usage()
  220. {
  221.     printf(L"Usage: Reflector [options] class\n\n");
  222.     printf(L"Options:\n");
  223.     printf(L"   -V\tVerbose\n");
  224.     printf(L"   -M<opt>\tMethods <=name>\n");
  225.     printf(L"   -I<opt>\tInvoke <=\"args\">\n");
  226.     printf(L"   -?\tHelp\n");
  227.  
  228. }
  229.  
  230.  
  231. /*****************************************************************************
  232.  Function :    main
  233.  
  234.  Abstract:     Entry point to the application.  Parses command line options
  235.                and instantiates the Reflector class and calls Run().
  236.             
  237.  Input Parameters: argc (number of arguments, including the program name)
  238.                    argv (array of ansi strings containing the arguments)
  239.  
  240.  Returns: Void
  241. ******************************************************************************/
  242. int main(int argc, char **args) 
  243. {
  244.     Reflector *r = new Reflector();
  245.     bool do_usage = false;
  246.     
  247.     try
  248.     {
  249.         if (argc < 2) {
  250.             Usage();
  251.             return 1;
  252.         }
  253.  
  254.         for (int i=1;i<argc;i++) {
  255.             int len = strlen(args[i]);
  256.             if ((args[i][0] == L'/') || (args[i][0] == L'-')) {
  257.                 switch (toupper(args[i][1])) {
  258.                 case L'?':
  259.                     do_usage = true;
  260.                     break;
  261.                 case L'M':
  262.                     r->methods = true;
  263.                     if (len > 2) {
  264.                         len -= 2;
  265.                         StringBuilder *sb = new StringBuilder(256);
  266.                         strcpy(sb,args[i]+2);
  267.                         r->methName = sb->ToString();
  268.                     }
  269.                     break;
  270.                 case L'I':
  271.                     r->invoke = true;
  272.                     if (len > 2) {
  273.                         len -= 2;
  274.                         StringBuilder *sb = new StringBuilder(256);
  275.                         strcpy(sb,args[i]+2);
  276.                         r->callArgs = sb->ToString();
  277.                     }
  278.                     break;
  279.                 case L'V':
  280.                     r->verbose = true;
  281.                     break;
  282.                 default:
  283.                     printf(L"Invalid Option\n\n");
  284.                     do_usage = true;
  285.                 }
  286.             }
  287.             else {
  288.                 StringBuilder *sb = new StringBuilder(256);
  289.                 strcpy(sb,args[i]);
  290.                 r->className = sb->ToString();
  291.             }
  292.             if (do_usage)
  293.                 break;
  294.         }
  295.         if (do_usage || r->className == NULL) {
  296.             Usage();
  297.             return 1;
  298.         }
  299.         return r->Run();
  300.     }
  301.     catch (Exception *exc_main)
  302.     {
  303.         printf(L"Error Err_012ab, exc caught in main, strLoc==%s, "
  304.                 L"exc_main==%s\n",r->strLoc,exc_main->ToString());
  305.     }
  306.     return 1;
  307. }
  308.  
  309.