2012-02-29 4 views
0

У меня проблема с активным компонентом x, который я написал на C#. Несмотря Я зарегистрировал DLL с Regasm я в настоящее время не в состоянии создать активный объект х ...Не удается создать объект из активного компонента x

Вот мой код из класса:

using System; 
using System.Collections; 
using System.Globalization; 
using System.IO; 
using System.Reflection; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 
using System.Security.Policy; 
using System.Security; 
using Ch.XXX.System6.Modules.Logger; 

namespace Gadget.Interop 
{ 
    /// <summary> 
    /// GadgetAdapter is the starting point for loading and unloading .NET assemblies 
    /// from javascript or any COM-based environment. 
    /// </summary> 
    [ComVisible(true)] 
    [ClassInterface(ClassInterfaceType.None)] 
    [Guid("21A72577-3D2D-4664-93F7-1BE02AE68240")] 
    [ProgId("GadgetInterop.GadgetAdapter")] 
    [ComDefaultInterface(typeof(IGadgetInterop))] 
    public class GadgetAdapter : IGadgetInterop, IDisposable, IObjectSafety 
    { 
     [DllImport("kernel32.dll")] 
     static extern IntPtr GetModuleHandle(string module); 
     [DllImport("kernel32.dll")] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     static extern bool FreeLibrary(IntPtr handle); 
     [DllImport("kernel32.dll")] 
     public extern static bool GetModuleHandleExA(int dwFlags, string ModuleName, ref IntPtr phModule); 
     [DllImport("kernel32.dll")] 
     static extern IntPtr LoadLibrary(string lpFileName); 

     /// <summary> 
     /// Gadget.Interop.dll Name for FreeLibrary Function 
     /// </summary> 
     private const string DLLNAME = "Gadget.Interop.dll"; 

     /// <summary> 
     /// Parameters for the constructor 
     /// </summary> 
     private ArrayList paramList = new ArrayList(); // Array list to hold constructor parameters 

     /// <summary> 
     /// Zusätzliche AppDomain 
     /// </summary> 
     private AppDomain appDomain; 


     /// <summary> 
     /// Standard Konstruktor 
     /// </summary> 
     public GadgetAdapter() { } 

     #region IGadgetInterop Members 
     /// <summary> 
     /// Adds an object to be passed to a class' constructor. Values must be passed to 
     /// this method in the same order of the constructor's arguments. 
     /// </summary> 
     /// <param name="parameter">Constructor agrument value</param> 
     public void AddConstructorParam(object parameter) 
     {     
      paramList.Add(parameter); 
     } 

     /// <summary> 
     /// Creates an instance of the specified type. Constructor parameters are used when 
     /// calling this method if they exist, but are forcibly cleared after object creation. 
     /// </summary> 
     /// <param name="assemblyFullPath">Full path to and name of the assembly to load</param> 
     /// <param name="className">Full namespace and class name of the type to create</param> 
     /// <returns>Instance of an object represented by the className arg ument</returns> 
     public object LoadType(string assemblyFullPath, string className) 
     { 
      try 
      { 
       ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.Name); 

       log.Info("Finally we arrived our C# code"); 
       return LoadTypeWithParams(assemblyFullPath, className, false); 
      } 
      catch (Exception ex) 
      { 
       // Javascript-friendly exception 
       throw new Exception("Finally we arrived c# code" + ex.Message); 
      } 
     } 
     /// <summary> 
     /// Creates an instance of the specified type. 
     /// <param name="preserveParams">Clears the constructor parameters if false</param> 
     /// <returns>Instance of an object represented by the className argument</returns> 
     public object LoadTypeWithParams(string assemblyFullPath, string className, bool preserveParams) 
     { 
      //Load Gadget.Interop.dll over the Gadget.Interop.dll 
      LoadLibrary(DLLNAME); 

      //Setup extra AppDomain 
      AppDomainSetup setup = new AppDomainSetup(); 
      setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; 

      setup = AppDomain.CurrentDomain.SetupInformation; 
      setup.PrivateBinPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); 
      setup.PrivateBinPathProbe = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); 
      setup.ApplicationName = "GadgetAdapter-Loader"; 
      setup.ShadowCopyFiles = "true"; 

      appDomain = AppDomain.CreateDomain(
       /*Generate a dynamic name*/ 
       "GadgetAdapter - Assembly" + Path.GetRandomFileName(), null, setup); 

      try 
      { 
       //Set security 
       object[] hostEvidence = { new Zone(SecurityZone.MyComputer) }; 

       //Create an Evidence based on the Security Zone 
       //Evidence intEvidence = new Evidence(hostEvidence, null); 

       //Load an assembly in an own application domain 
       return (appDomain.CreateInstanceFromAndUnwrap(
        assemblyFullPath, 
        className, true, BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public, 
        null, paramList.ToArray(), CultureInfo.CurrentCulture, null)); 
      } 
      catch (Exception ex) 
      { 
       //Eintrag ins EventLog schreiben 
       string sSource; 
       string sLog; 
       string sEvent; 

       sSource = "XXX Sidebar Gadget"; 
       sLog = "Sidebar Gadget"; 
       sEvent = "Unhandled Exception in Gadget.Interop.GadgetAdapter"; 

       //Eventlog Eintrag schreiben 
       if (!EventLog.SourceExists(sSource)) 
        EventLog.CreateEventSource(sSource, sLog); 
       EventLog.WriteEntry(sSource, sEvent + Environment.NewLine + ex.Message + Environment.NewLine + ex.InnerException, 
        EventLogEntryType.Error); 

       throw new Exception(ex.InnerException.ToString()); 
      } 
     } 

     /// <summary> 
     /// Call the object's Dispose method and sets the object to null; 
     /// </summary> 
     /// <param name="typeToUnload">Type implementing IDisposable to be destroyed</param> 
     public void UnloadType(object typeToUnload) 
     { 
      try 
      { 
       //Verfiy Unloadtype 
       if (typeToUnload != null && typeToUnload is IDisposable) 
       { 
        //Dispose 
        (typeToUnload as IDisposable).Dispose(); 

        if (appDomain != null) 
        { 
         //Unload ApplicationDomain 
         AppDomain.Unload(appDomain); 
         appDomain = null; 
        } 
       } 

       //Set instance to null 
       typeToUnload = null;     
      } 
      catch (Exception exception) 
      { 
       //Eintrag ins Eventlog schreiben 
       string sSource; 
       string sLog; 
       string sEvent; 

       sSource = "XXX Sidebar Gadget"; 
       sLog = "Sidebar Gadget"; 
       sEvent = "Unhandled Exception in Gadget.Interop.GadgetAdapter"; 

       //Eventlog Eintrag schreiben 
       if (!EventLog.SourceExists(sSource)) 
        EventLog.CreateEventSource(sSource, sLog); 
       EventLog.WriteEntry(sSource, sEvent + Environment.NewLine + exception.Message + Environment.NewLine + exception.InnerException, 
        EventLogEntryType.Error); 
      } 
     } 

     #endregion 

     #region IDisposable Members 

     /// <summary> 
     /// Dispose Methode for the GadgetAdapter 
     /// </summary> 
     public void Dispose() 
     { 
      //Clear constructor parameters 
      this.paramList.Clear(); 
      paramList = null; 

      try 
      { 
       //Unload the GadgetAdapter over Kernel32 functions 
       IntPtr hMod = IntPtr.Zero; 
       if (GetModuleHandleExA(0, DLLNAME, ref hMod)) 
       { 
        bool s = false; 
        do 
        { 
         s = FreeLibrary(hMod); 
        } while (s); 
       } 
      } 
      finally 
      { 
       GC.SuppressFinalize(this); 
      } 

     } 

     #region IObjectSafety Members 
     public enum ObjectSafetyOptions 
     { 
      INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001, 
      INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002, 
      INTERFACE_USES_DISPEX = 0x00000004, 
      INTERFACE_USES_SECURITY_MANAGER = 0x00000008 
     }; 

     public int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions) 
     { 
      ObjectSafetyOptions m_options = ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER | ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA; 
      pdwSupportedOptions = (int)m_options; 
      pdwEnabledOptions = (int)m_options; 
      return 0; 
     } 
     public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions) 
     { 
      return 0; 
     } 
     #endregion 

     #endregion 
    } 
} 

А вот интерфейс:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 

namespace Gadget.Interop 
{ 
    /// <summary> 
    /// Interface required COM registration. This interface outlines methods 
    /// used to create and destroy managed .NET types 
    /// </summary> 
    [ComVisible(true)] 
    [InterfaceType(ComInterfaceType.InterfaceIsDual)] 
    [Guid("618ACBAF-B4BC-4165-8689-A0B7D7115B05")] 
    public interface IGadgetInterop 
    { 
     object LoadType(string assemblyFullPath, string className); 
     object LoadTypeWithParams(string assemblyFullPath, string className, bool preserveParams); 
     void AddConstructorParam(object parameter); 
     void UnloadType(object typeToUnload); 
    } 
} 

Когда я пытаюсь простой CreateObject в VB Script

Set wshShell2 = CreateObject("GadgetInterop.GadgetAdapter") 

Я также попытался:

Set wshShell2 = CreateObject("Gadget.Interop.GadgetAdapter") 

Я получаю ошибку: компонент 800A01AD ActiveX не может создать объект

Кто-нибудь еще была такая же проблема?

EDIT: Я также вижу компонент в оле зрителя ...

Благодаря

+0

Вы запустили 'regasm' с опцией'/verbose', чтобы узнать, действительно ли он что-то регистрирует? Вы указали '/ tlb'? Вы также можете попытаться использовать средство просмотра OLE, чтобы узнать, была ли регистрация успешной. – Andre

+0

Привет, Андре, спасибо за ваш ответ. Я попытался запустить regasm с/verbose, и я также указал/tlb .. Ничего не изменилось, все еще не удалось создать объект .... Я вижу компонент в ole viewer – user886091

+0

, возможно, вы строите компонент как 32 бит и пытаетесь использовать его из 64-битного интерпретатора vbscript? Попробуйте использовать c: \ windows \ syswow64 \ wscript.exe для запуска скрипта. – yms

ответ

1

64 бит COM объекты не могут быть использованы непосредственно из 32 бит приложений и наоборот. В этом случае вы должны указать свой COM-объект на основе .NET как AnyCPU и зарегистрировать его для обеих архитектур процессора, как указано в this SO answer. В принципе, вам нужно запустить Regasm в

C: \ Windows \ Microsoft.NET \ Framework \ v2.0.50727>

и

C: \ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 >

Смежные вопросы