home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / dotNETSDK / SETUP.EXE / netfxsd1.cab / FL_comreg_cs________.3643236F_FC70_11D3_A536_0090278A1BB8 < prev    next >
Encoding:
Text File  |  2002-04-20  |  19.3 KB  |  616 lines

  1. using System;
  2. using System.Collections;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Reflection;
  6. using System.Runtime.Remoting;
  7. using System.Runtime.CompilerServices;
  8. using System.Runtime.InteropServices;
  9. using System.Security.Policy;
  10. using System.Text;
  11.  
  12. using Microsoft.Win32;
  13.  
  14. namespace ComReg
  15. {
  16.  
  17.     public    class ComRegistrationClass : MarshalByRefObject
  18.     {
  19.         // Some privates
  20.         private const string strManagedCategoryGuid = "{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}";
  21.  
  22.         // Marshaler clsid
  23.         private const string strPrxyStubMarshalerGuid = "{34E6B1BA-CFD5-4ea3-B0C8-D16DF05C2C4B}";
  24.         private const string strDocStringPrefix = "";
  25.         private const string strManagedTypeThreadingModel = "Both";
  26.         private const string strComponentCategorySubKey = "Component Categories";
  27.         private const string strManagedCategoryDescription = ".NET Category";
  28.         private const string strMsCorEEFileName = "mscoree.dll";
  29.         private string strRuntimeVersion = RuntimeEnvironment.GetSystemVersion();
  30.  
  31.         public    class RegistryValue
  32.         {
  33.             public RegistryValue(string pkey, string pattr, string pvalue)
  34.             {
  35.                 key = pkey;
  36.                 attr = pattr;
  37.                 value=pvalue;
  38.             }
  39.  
  40.             public string key;
  41.             public string attr;
  42.             public object value;
  43.         }
  44.  
  45.         public object[] GetTypes(Assembly asm)
  46.         {
  47.             ArrayList regtypes = new ArrayList();
  48.  
  49.             // No assembly is an error
  50.             if (asm == null)
  51.                 throw new ArgumentNullException("assembly");
  52.  
  53.             // Fetch all of the types in each module that require registration.
  54.             foreach (Module m in asm.GetModules())
  55.             {
  56.                 foreach (Type t in m.GetTypes())
  57.                 {
  58.                     if ((t.IsPublic || t.IsNestedPublic) && (t.IsClass || t.IsInterface))
  59.                         regtypes.Add(t);
  60.                 }
  61.             }
  62.             return (object[])regtypes.ToArray();
  63.         }
  64.  
  65.         private bool GetIClassXXXInfo(Type t, out string name, out Guid guid)
  66.         {
  67.             name = "";
  68.             guid = new Guid();
  69.             object[] attrs = t.GetCustomAttributes(typeof(ClassInterfaceAttribute), true);
  70.             if (attrs.Length != 0 && ((ClassInterfaceAttribute)attrs[0]).Value == ClassInterfaceType.AutoDual)
  71.             {
  72.                 // Now add IClassXXX Information
  73.                 // I need to get the ITypeInfo and munge around like a mad thing because the CLR doesn't really believe that
  74.                 // an IClassXXX exists
  75.                 IntPtr pTI = Marshal.GetITypeInfoForType(t);
  76.                 if (pTI != (IntPtr)0)
  77.                 {
  78.                     UCOMITypeInfo ti = (UCOMITypeInfo)Marshal.GetObjectForIUnknown(pTI);
  79.                     IntPtr pATTR;
  80.                     ti.GetTypeAttr(out pATTR);
  81.                     TYPEATTR attr = (TYPEATTR)Marshal.PtrToStructure(pATTR, typeof(TYPEATTR));
  82.  
  83.                     if (attr.typekind == TYPEKIND.TKIND_COCLASS)
  84.                     {
  85.                         // Rest easy we got a coclass
  86.                         for(int i = 0; i < attr.cImplTypes; i++)
  87.                         {
  88.                             int href;
  89.                             int    flags;
  90.                             ti.GetImplTypeFlags(i, out flags);
  91.                             if ((flags & (int)IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0  &&
  92.                                 (flags & (int)IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) == 0)
  93.                             {
  94.                                 // This is the default interface
  95.                                 ti.GetRefTypeOfImplType(i, out href);
  96.                                 if (href != 0)
  97.                                 {
  98.                                     UCOMITypeInfo reftype;
  99.                                     ti.GetRefTypeInfo(href, out reftype);
  100.  
  101.                                     // Retrieve guid
  102.                                     IntPtr pREFATTR;
  103.                                     reftype.GetTypeAttr(out pREFATTR);
  104.                                     TYPEATTR refattr = (TYPEATTR)Marshal.PtrToStructure(pREFATTR, typeof(TYPEATTR));
  105.                                     guid = refattr.guid;
  106.                                     reftype.ReleaseTypeAttr(pREFATTR);
  107.  
  108.                                     // Retrieve name
  109.                                     string strDocString;
  110.                                     int dwHelpContext;
  111.                                     string strHelpFile;
  112.  
  113.                                     // Should be TYPEATTR.MEMBER_ID_NIL - but there was a typo in devland
  114.                                     reftype.GetDocumentation(TYPEATTR.MEMBER_ID_NIL, out name, out strDocString, out dwHelpContext, out strHelpFile);
  115.                                 }
  116.                             }
  117.                         }
  118.                     }
  119.                     ti.ReleaseTypeAttr(pATTR);
  120.                 }
  121.             }
  122.             return guid != Guid.Empty && name != "";
  123.         }
  124.  
  125.         private object[]    RegisterType(Type t, bool proxystubmarshaler, bool codebase, string remotehost, string runas)
  126.         {
  127.             object[] keys = GenerateRegKeysForType(t, proxystubmarshaler, codebase, remotehost, runas);
  128.             return keys;
  129.         }
  130.  
  131.         private void    WriteStream(FileStream fs, string text)
  132.         {
  133.             byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text);
  134.             fs.Write(bytes, 0, bytes.Length);
  135.         }
  136.  
  137.         private void    GenerateRegFile(ArrayList keys, string regfile)
  138.         {
  139.             if (regfile == null || regfile == "") regfile="default.reg";
  140.  
  141.             FileStream fs = File.Create(regfile);
  142.             WriteStream(fs, "REGEDIT4" + Environment.NewLine);
  143.             string lastkey = "";
  144.             string attr = "";
  145.             string value = "";
  146.             foreach(RegistryValue r in keys)
  147.             {
  148.                 if (r.key != lastkey)
  149.                 {
  150.                     lastkey = r.key;
  151.                     WriteStream(fs,  Environment.NewLine + "[" + lastkey + "]"  + Environment.NewLine);
  152.                 }
  153.  
  154.                 attr = (r.attr == null || r.attr == "") ? "@" : '"' + r.attr + '"';
  155.                 value = '"' + ((r.value == null || (string)r.value == "") ? "" : r.value.ToString()) + '"';
  156.                 WriteStream(fs, attr + "=" + value + Environment.NewLine);
  157.             }
  158.  
  159.             fs.Close();
  160.  
  161.             return;
  162.         }
  163.  
  164.         private bool LeftCompare(string s, string target, out string remainder)
  165.         {
  166.             if(s.Substring(0, target.Length) == target)
  167.             {
  168.                 remainder = s.Substring(target.Length, s.Length - target.Length);
  169.                 return true;
  170.             }
  171.             remainder = "";
  172.             return false;
  173.         }
  174.  
  175.         private RegistryKey CreateSubKey(string key)
  176.         {
  177.             string remainder = "";
  178.             RegistryKey branch = null;
  179.  
  180.             if (LeftCompare(key, "HKEY_CLASSES_ROOT\\", out remainder))
  181.             {
  182.                 branch = Registry.ClassesRoot;
  183.             }
  184. #if EXTRA_REG
  185.             // I don't need these others yet - maybe I never will
  186.             else if (LeftCompare(key, "HKEY_CURRENT_USER\\", out remainder))
  187.             {
  188.                 branch = Registry.CurrentUser;
  189.             }
  190.             else if (LeftCompare(key, "HKEY_LOCAL_MACHINE\\", out remainder))
  191.             {
  192.                 branch = Registry.LocalMachine;
  193.             }
  194.             else if (LeftCompare(key, "HKEY_USERS\\", out remainder))
  195.             {
  196.                 branch = Registry.Users;
  197.             }
  198.             else if (LeftCompare(key, "HKEY_CURRENT_CONFIG\\", out remainder))
  199.             {
  200.                 branch = Registry.CurrentConfig;
  201.             }
  202. #endif
  203.             if (branch == null)
  204.             {
  205.                 throw new Exception("Invalid Registry Root specified in: " + key);
  206.             }
  207.             return branch.CreateSubKey(remainder);
  208.         }
  209.  
  210.         private void    RegisterKeys(ArrayList keys)
  211.         {
  212.             RegistryKey key = Registry.ClassesRoot;
  213.             string lastkey = "";
  214.             string attr = "";
  215.             string value = "";
  216.             foreach(RegistryValue r in keys)
  217.             {
  218.                 if (r.key != lastkey)
  219.                 {
  220.                     if (lastkey != "") key.Close();
  221.                     lastkey = r.key;
  222.                     key = CreateSubKey(lastkey);
  223.                 }
  224.  
  225.                 attr = (r.attr == null) ? "" : r.attr;
  226.                 value = (r.value == null) ? "" : r.value.ToString();
  227.  
  228.                 // The Reg API on Some OS's requires the length to include the terminating \0 and on others not too.
  229.                 // The /0 doesn't seem to do much harm so I am adding it anyway
  230.                 value += "\0";
  231.                 key.SetValue(attr, value);
  232.             }
  233.  
  234.             key.Close();
  235.             return;
  236.         }
  237.  
  238.         public    static    bool IsWin2K()
  239.         {
  240.             OperatingSystem os = Environment.OSVersion;
  241.             if ( os.Platform == PlatformID.Win32NT && os.Version.Major == 5)
  242.                 return true;
  243.             else
  244.                 return false;
  245.         }
  246.  
  247.         private    static    bool IsWindows()
  248.         {
  249.             OperatingSystem os = Environment.OSVersion;
  250.             if ( os.Platform == PlatformID.Win32Windows)
  251.                 return true;
  252.             else
  253.                 return false;
  254.         }
  255.  
  256.  
  257.         private object[]    GenerateRegKeysForType(Type t, bool proxystubmarshaler, bool codebase, string remotehost, string runas)
  258.         {
  259.             ArrayList    keys = new ArrayList();
  260.  
  261.             // If the type is not public then no registration.
  262.             if ((t.IsPublic || t.IsNestedPublic) && !t.IsImport)
  263.             {
  264.                 string root = Registry.ClassesRoot.Name;
  265.                 string key = null;
  266.                 string strTypeName = t.FullName;
  267.                 string strAssemblyName = t.Assembly.GetName().FullName;
  268.  
  269.                 // Deal with classes
  270.                 if (t.IsClass)
  271.                 {
  272.                     if(!(t.IsAbstract || t.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null) == null))
  273.                     {
  274.                         // Creatable class - get Guid and ProgId
  275.                         string strClsId = "{" + Marshal.GenerateGuidForType(t).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
  276.                         object[] attrs = t.GetCustomAttributes(typeof(ProgIdAttribute), true);
  277.  
  278.                         // ====================================================================================
  279.                         // Generate progid
  280.                         // If there is no prog ID attribute then use the full name of the type as the prog id.
  281.                         // null progid = is equivalent to a blank progid.
  282.                         // ====================================================================================
  283.                         string strProgId = null;
  284.                         strProgId = (attrs.Length == 0) ?  strTypeName : ((ProgIdAttribute)attrs[0]).Value;
  285.  
  286.                         if (strProgId == null)
  287.                             strProgId = String.Empty;
  288.  
  289.                         // Now generate registry keys
  290.                         // Create the HKEY_CLASS_ROOT\<strProgId> key.
  291.                         if (strProgId != String.Empty)
  292.                         {
  293.                             key = root + "\\" + strProgId;
  294.                             keys.Add(new RegistryValue( key, "", strTypeName));
  295.                             keys.Add(new RegistryValue( key + "\\CLSID", "", strClsId));
  296.                         }
  297.  
  298.                         // Create the HKEY_CLASS_ROOT\CLSID\<CLSID> key.
  299.                         key = root + "\\CLSID\\" + strClsId;
  300.                         keys.Add(new RegistryValue( key, "", strTypeName));
  301.                         keys.Add(new RegistryValue( key, "AppID", strClsId));
  302.  
  303.                         // Create the HKEY_CLASS_ROOT\CLSID\<CLSID>\InprocServer32 key.
  304.                         key = root + "\\CLSID\\" + strClsId + "\\InprocServer32";
  305.                         keys.Add(new RegistryValue( key, "", strMsCorEEFileName));
  306.                         keys.Add(new RegistryValue( key, "ThreadingModel", "Both"));
  307.                         keys.Add(new RegistryValue( key, "Class", strTypeName));
  308.                         keys.Add(new RegistryValue( key, "Assembly", strAssemblyName));
  309.                         keys.Add(new RegistryValue( key, "RuntimeVersion", strRuntimeVersion));
  310.                         if(codebase)
  311.                             keys.Add(new RegistryValue( key, "Codebase", t.Assembly.CodeBase));
  312.  
  313.                         if (strProgId != String.Empty)
  314.                         {
  315.                             key = root + "\\CLSID\\" + strClsId + "\\ProgId";
  316.                             keys.Add(new RegistryValue( key, "", strProgId));
  317.                         }
  318.  
  319.  
  320.                         // Create the HKEY_CLASS_ROOT\AppID\.
  321.                         key = root + "\\AppID\\" + strClsId;
  322.                         keys.Add(new RegistryValue( key, "", strTypeName));
  323.                         keys.Add(new RegistryValue( key, "AppID", strClsId));
  324.  
  325.                         if(remotehost == "")
  326.                         {
  327.                             keys.Add(new RegistryValue( key, "DllSurrogate", ""));
  328.                         }
  329.                         else
  330.                         {
  331.                             keys.Add(new RegistryValue( key, "RemoteServer", remotehost));
  332.                         }
  333.  
  334.                         if(runas == "")
  335.                         {
  336.                             keys.Add(new RegistryValue( key, "RunAs", "Interactive User"));
  337.                         }
  338.                         else
  339.                         {
  340.                             keys.Add(new RegistryValue( key, "RunAs", runas));
  341.                         }
  342.  
  343.                         // Create the HKEY_CLASS_ROOT\CLSID\<CLSID>\Implemented Categories\<Managed Category Guid> key.
  344.                         string cat = root + "\\CLSID\\" + strClsId + "\\Implemented Categories\\" + strManagedCategoryGuid;
  345.                         keys.Add(new RegistryValue( cat, "", ""));
  346.  
  347.                         // Create the HKEY_CLASS_ROOT\Component Category key.
  348.                         string comp = root + "\\Component Category\\" + strManagedCategoryGuid;
  349.                         keys.Add(new RegistryValue( comp, "0", ""));
  350.  
  351.                         if (proxystubmarshaler)
  352.                         {
  353.                             string name;
  354.                             Guid   guid;
  355.                             if (GetIClassXXXInfo(t, out name, out guid))
  356.                             {
  357.                                 string itf = root + "\\Interface\\{" + guid.ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
  358.                                 keys.Add(new RegistryValue( itf, "", name));
  359.                                 keys.Add(new RegistryValue( itf, "Assembly", strAssemblyName));
  360.                                 keys.Add(new RegistryValue( itf, "TypeName", strTypeName));
  361.                                 keys.Add(new RegistryValue( itf + "\\ProxyStubClsId", "", strPrxyStubMarshalerGuid));
  362.                                 keys.Add(new RegistryValue( itf + "\\ProxyStubClsId32", "", strPrxyStubMarshalerGuid));
  363.                                 if(codebase)
  364.                                     keys.Add(new RegistryValue( itf, "Codebase", t.Assembly.CodeBase));
  365.  
  366.                                 // We may want to add some unregistration guff here.
  367.                             }
  368.                         }
  369.                     }
  370.                 }
  371.                 else if(t.IsInterface)
  372.                 {
  373.                     if (proxystubmarshaler)
  374.                     {
  375.                         string itf = root + "\\Interface\\{" + Marshal.GenerateGuidForType(t).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
  376.                         keys.Add(new RegistryValue( itf, "", t.Name));
  377.                         keys.Add(new RegistryValue( itf, "Assembly", strAssemblyName));
  378.                         keys.Add(new RegistryValue( itf, "TypeName", strTypeName));
  379.                         keys.Add(new RegistryValue( itf + "\\ProxyStubClsId", "", strPrxyStubMarshalerGuid));
  380.                         keys.Add(new RegistryValue( itf + "\\ProxyStubClsId32", "", strPrxyStubMarshalerGuid));
  381.                         if(codebase)
  382.                             keys.Add(new RegistryValue( itf, "Codebase", t.Assembly.CodeBase));
  383.                     }
  384.                 }
  385.             }
  386.             return (object[])keys.ToArray();
  387.         }
  388.  
  389.         public void RegisterAssembly(Assembly asm, string regfile, bool proxystubmarshaler, bool codebase, string remotehost, string runas)
  390.         {
  391.  
  392.             ArrayList keys = new ArrayList();
  393.             foreach(Type t in GetTypes(asm))
  394.             {
  395.                 if (Marshal.IsTypeVisibleFromCom(t))
  396.                 {
  397.                     foreach(object o in RegisterType(t, proxystubmarshaler, codebase, remotehost, runas))
  398.                     {
  399.                         keys.Add(o);
  400.                     }
  401.                 }
  402.             }
  403.             if(regfile != null)
  404.                 GenerateRegFile(keys, regfile);
  405.             else
  406.                 RegisterKeys(keys);
  407.         }
  408.  
  409.         public void RegisterAssembly(string assemblyfile, string regfile, bool proxystubmarshaler, bool codebase, string remotehost, string runas)
  410.         {
  411.             RegisterAssembly(Assembly.LoadFrom(assemblyfile), regfile, proxystubmarshaler, codebase, remotehost, runas);
  412.         }
  413.     }
  414.  
  415.  
  416.     class ComRegister : ProgramBase
  417.     {
  418.         const    string    exe = ".exe";
  419.         const    string    dll = ".dll";
  420.  
  421.         static ComRegister()
  422.         {
  423.             name    = "ComReg";
  424.             description = "Assembly Registration utility";
  425.             syntax    = name + "[Options] Assembly file [Options]";
  426.             where    = "Assembly file\t\tFile containing the assembly to register";
  427.             options = new Option[]    {
  428.                       new Option ("/codebase","/c",                "\tSpecify that this assembly may be shared without the use of the gac.", false),
  429.                       new Option ("/gac","/g",                "\t\tAdd (Remove when used in with /unregister) the assembly to the GAC.", false),
  430.                       new Option ("/proxystubmarshaler","/p","Marshal using the proxystub marshaler.", false),
  431.                       new Option ("/regfile","/regf",        "\tEmit a regfile.", true),
  432.                       new Option ("/remotehost:server","/rem:server","\n\t\t\t\tSpecify the remote server which will host types in this Assembly.", true),
  433.                       new Option ("/runas:user","/run:server","Specify the user name to run this app when used out of process.", true),
  434.                       new Option ("/unregister", "/u",        "\tUnregister the assembly.", false)
  435.                     };
  436.         }
  437.  
  438.         static public    void RegisterAssembly(string assemblyfile, string regfile, bool proxystubmarshaler, bool codebase, string remotehost, string runas)
  439.         {
  440.             string adname = "ComReg: " + Guid.NewGuid().ToString();
  441.             string filepath = Path.GetDirectoryName(Path.GetFullPath(assemblyfile));
  442.             string filename = Path.GetFullPath(assemblyfile);
  443.  
  444.             Evidence si = null;
  445.             AppDomain ad = AppDomain.CreateDomain(adname, si);
  446.             if (ad == null)
  447.                 throw new ApplicationException("Unable to create AppDomain for assembly cache install ");
  448.             ComRegistrationClass r = (ComRegistrationClass)ad.CreateInstanceAndUnwrap(Assembly.GetAssembly(typeof(ComReg.ComRegistrationClass)).FullName, typeof(ComReg.ComRegistrationClass).FullName);
  449.             r.RegisterAssembly(filename, regfile, proxystubmarshaler, codebase, remotehost, runas);
  450.             AppDomain.Unload(ad);
  451.         }
  452.  
  453.  
  454.         static int    Main(string[] args)
  455.         {
  456.             int        exitcode = 0;
  457.             String    assemblyfile = null;
  458.             bool    psmarshaler = false;
  459.             string    regfile = null;
  460.             bool    gac = false;
  461.             bool    unregister = false;
  462.             bool    codebase = false;
  463.             string    remotehost = "";
  464.             string    runas = "";
  465.  
  466.             try
  467.             {
  468.                 Setting[] switches = GetSwitches(args);
  469.  
  470.                 foreach(Setting sw in switches)
  471.                 {
  472.                     if (sw.option == null)
  473.                     {
  474.                         if (assemblyfile != null)
  475.                         {
  476.                             // We already have an assembly
  477.                             PrintLogo();
  478.                             WriteErrorMsg("Only one assembly can be registered at a time.");
  479.                             exitcode = 1;
  480.                             goto done;
  481.                         }
  482.                         else
  483.                         {
  484.                             // We are cool with this
  485.                             assemblyfile = sw.value;
  486.                         }
  487.                     }
  488.                     else
  489.                     {
  490.                         if (CompareString(sw.option.value, "/proxystubmarshaler")==0)
  491.                         {
  492.                             psmarshaler=true;
  493.                         }
  494.                         else if (CompareString(sw.option.value, "/regfile:")==0)
  495.                         {
  496.                             if (regfile != null)
  497.                             {
  498.                                 PrintLogo();
  499.                                 WriteErrorMsg("Only one regfile can be specified at a time.");
  500.                                 exitcode = 1;
  501.                                 goto done;
  502.                             }
  503.                             else
  504.                                 regfile = sw.value;
  505.                         }
  506.                         else if (CompareString(sw.option.value, "/gac")==0)
  507.                         {
  508.                             gac = true;
  509.                         }
  510.                         else if (CompareString(sw.option.value, "/unregister")==0)
  511.                         {
  512.                             unregister = true;
  513.                         }
  514.                         else if (CompareString(sw.option.value, "/codebase")==0)
  515.                         {
  516.                             if(unregister)
  517.                             {
  518.                                 //Codebase and unregister are mutually exclusive
  519.                                 PrintLogo();
  520.                                 WriteErrorMsg("Codebase can not be specified with unregister.");
  521.                                 exitcode = 1;
  522.                                 goto done;
  523.                             }
  524.                             if(gac)
  525.                             {
  526.                                 //Codebase and gac are mutually exclusive
  527.                                 PrintLogo();
  528.                                 WriteErrorMsg("Codebase can not be specified with gac.");
  529.                                 exitcode = 1;
  530.                                 goto done;
  531.                             }
  532.                             codebase = true;
  533.                         }
  534.                         else if (CompareString(sw.option.value, "/remotehost:")==0)
  535.                         {
  536.                             remotehost = sw.value;
  537.                         }
  538.                         else if (CompareString(sw.option.value, "/runas:")==0)
  539.                         {
  540.                             runas = sw.value;
  541.                         }
  542.                         else if (CompareString(sw.option.value, "/?")==0)
  543.                         {
  544.                             PrintLogo();
  545.                             PrintUsage();
  546.                             exitcode = 0;
  547.                             goto done;
  548.                         }
  549.                     }
  550.                 }
  551.  
  552.                 PrintLogo();
  553.                 if (assemblyfile == null)
  554.                 {
  555.                     WriteErrorMsg("No Assembly file specified");
  556.                     exitcode = 1;
  557.                     goto done;
  558.                 }
  559.                 else
  560.                 {
  561.                     // Deal with adding to or removing from the gac ... as required
  562.                     if (gac)
  563.                     {
  564.                         if(unregister)
  565.                         {
  566.                             Console.WriteLine("Warning uninstall currently only removes the file from the GAC");
  567.  
  568.                             string fullname = FusionInstall.FullAssemblyName(assemblyfile);
  569.                             if (FusionInstall.RemoveAssemblyFromCache(fullname) != 0)
  570.                             {
  571.                                 WriteErrorMsg("Failed to remove the assembly: " + assemblyfile + "[" + fullname + "] from the GAC");
  572.                                 exitcode = 1;
  573.                             }
  574.                         }
  575.                         else
  576.                         {
  577.                             if(!File.Exists(assemblyfile))
  578.                             {
  579.                                 WriteErrorMsg("Unable to locate assembly: " + assemblyfile);
  580.                                 exitcode = 1;
  581.                             }
  582.                             else if(FusionInstall.AddAssemblyToCache(assemblyfile) != 0)
  583.                             {
  584.                                 WriteErrorMsg("Failed to add the assembly: " + assemblyfile + " to the GAC");
  585.                                 exitcode = 1;
  586.                             }
  587.                         }
  588.                     }
  589.  
  590.                     // If no errors installing
  591.                     if (exitcode == 0)
  592.                     {
  593.  
  594.                         if(unregister)
  595.                         {
  596.                             Console.WriteLine("Assembly: " + assemblyfile + " unregistered" + ((gac) ? " and removed from the GAC." : "."));
  597.                         }
  598.                         else
  599.                         {
  600.                             RegisterAssembly(assemblyfile, regfile, psmarshaler, codebase, remotehost, runas);
  601.                             Console.WriteLine("Assembly: " + assemblyfile + " registered" + ((gac) ? " and added to the GAC." : "."));
  602.                         }
  603.                     }
  604.                 }
  605.             }
  606.             catch(Exception e)
  607.             {
  608.                 WriteErrorMsg(e.Message);
  609.                 return 1;
  610.             }
  611.         done:
  612.             return exitcode;
  613.         }
  614.     }
  615. }
  616.