2009-11-14 15 views
5

Sto provando a chiamare un metodo che ho scritto in C# da VBScript.Impossibile chiamare il codice C# da vbscript - Errore ActiveX

Ho seguito quasi tutte le istruzioni che riesco a trovare sul Web e ho ancora problemi.

In particolare sto ottenendo

Error: ActiveX component can't create object

Code: 800A01AD

Finora ho fatto quanto segue:

  1. Set ComVisible(true)
  2. registrato utilizzando regasm /codebase
  3. Forte di nome mio assemblaggio
  4. confermato che sta nel registro e punta al corre posizione ct
  5. Realizzato classe pubblico
  6. non dispongono di metodi statici
  7. reso il metodo che voglio chiamare pubblico
  8. avere un costruttore senza parametri
  9. esplicitamente definito un GUID

miei sguardi VBScript così:

set oObject = CreateObject("TTTTTT.FFFFF.CCCCCCCCC") 

Il mio codice C# l ooks come questo:

using System; 
using System.IO; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace XXXXX.YYYYY 
{ 
    [ComVisible(true)] 
    [Guid("3EB62C37-79BC-44f7-AFBD-7B8113D1FD4F")] 
    [ProgId("TTTTTT.FFFFF.CCCCCCCCC")] 
    public class CCCCCCCCC 
    { 
     public void MyFunc() 
     { 
      // 
     } 
    } 
} 

Qualcuno può aiutare?

+0

Potrebbe inviare la dichiarazione di classe per la classe C#, tra cui la dichiarazione dello spazio dei nomi che racchiude e tutti gli attributi sulla classe? – itowlson

+0

Ciao, ho aggiornato la mia domanda con il mio codice. – Grant

+0

Hai visto http://stackoverflow.com/questions/769332/how-to-call-c-dll-function-from-vbscript? – abatishchev

risposta

2

Ecco un semplice progetto con pochi passaggi, per iniziare.

codice C#:

using System; 
using System.Reflection; 
using System.Runtime.CompilerServices; 
using System.Runtime.InteropServices; 

[assembly:System.CLSCompliant(true)] 
[assembly: ComVisible(true)] 
// The following GUID is for the ID of the typelib if this project is exposed to COM 
[assembly: Guid("7d9c5cd3-73d4-4ab1-ba98-32515256c0b0")] 

namespace Cheeso.ComTests 
{ 
    [Guid("7d9c5cd3-73d4-4ab1-ba98-32515256c0b1")] 
    public class TestReply 
    { 
     public string salutation; 
     public string name; 
     public string time; 
    } 

    [Guid("7d9c5cd3-73d4-4ab1-ba98-32515256c0b2")] 
    public class TestObj 
    { 
     // ctor 
     public TestObj() {} 

     public TestReply SayHello(string addressee) 
     { 
      return SayHello(addressee, "hello"); 
     } 

     public TestReply SayHello(string addressee, string greeting) 
     { 
      string x = String.Format("{0}, {1}!", greeting, addressee); 
      Console.WriteLine("{0}", x); 

      TestReply r = new TestReply 
      { 
       salutation = greeting, 
       name = addressee, 
       time = System.DateTime.Now.ToString("u") 
      }; 
      return r; 
     } 
    } 
} 

VBScript codice client:

Function Main() 
    Dim obj 
    Dim reply 
    set obj = CreateObject("Cheeso.ComTests.TestObj") 
    Set reply = obj.SayHello("Evgeny") 
    WScript.Echo "Reply at: " & reply.time 
    Set reply = obj.SayHello_2("Evgeny", "wassup") 
    WScript.Echo "Reply at: " & reply.time 
End Function 

Main 

Costruire:

(produce your .snk file, once) 
csc.exe /t:library /debug+ /keyfile:Foo.snk /out:TestObj.dll TestObj.cs 
regasm /codebase TestObj.exe 

Poi basta eseguire il VBScript (attraverso cscript.exe).

Una volta che la cosa di base funziona, è possibile modificarla, aggiungere GAC, rendere esplicita la libreria dei tipi, aggiungere un ProgId esplicito e così via.

ps: FYI, questo esempio mostra cosa succede con i metodi .NET sovraccaricati su una classe registrata per interoperabilità. C'è un _2 (_3, _4, ecc. Implicito) aggiunto al nome del metodo.

+0

+1 per un esempio completo. – rekire

+0

Nel sistema x64 potrebbe essere necessario creare il file .reg utilizzando l'opzione/regfile in regasm e quindi importarlo manualmente. Altrimenti non c'erano le chiavi corrispondenti CLSID \ {GUID} nel registro - erano sotto HKCR \ Wow6432Node \ CLSID \ {GUID} –

4

Hai letto questo articolo: COM Interop Exposed

Nel last page (3) di questo articolo, c'è una lista:

  1. definire un'interfaccia .NET per le metodi che si desidera esporre a COM.
  2. Assegnare un GUID a quell'interfaccia con l'attributo "Guid".
  3. Chiedi alla classe di implementare l'interfaccia come prima interfaccia.
  4. Assegnare un GUID a quella classe con l'attributo "Guid" .
  5. Aggiungere il "ClassInterface(ClassInterfaceType.None)" attributo evitare regasm/TlbExp da creare un'interfaccia vuota predefinita .
  6. Inserire un numero di versione specifica nell'attributo AssemblyVersion.
  7. Creare una coppia di chiavi con nome sicuro per l'assembly e puntare ad esso tramite l'attributo AssemblyKeyFile.
  8. Aggiungi l'assembly nella Global Assembly Cache,
  9. Registra l'assembly per COM utilizzando il comando Regasm insieme l'opzione "/ NR" per generare una libreria dei tipi COM .

Non sono sicuro che GAC e ClassInterfaceType.None siano i pezzi mancanti del tuo puzzle, potresti voler provarlo. In bocca al lupo!

+0

grazie per la tua risposta o.k.w. Ho controllato tutti gli articoli nell'articolo e sfortunatamente sto ancora ricevendo lo stesso errore. – Grant

+0

Forse è possibile codificare da zero un componente da quei codici di esempio e vedere se funziona. In caso contrario, forse il problema si trova altrove e non il tuo codice.Mi dispiace, non ho potuto offrire più assistenza. I collegamenti –

+0

sono interrotti – bluish

4

Non c'è niente di veramente sbagliato nel codice e hai seguito la procedura di installazione corretta, dal suono di esso. Il codice di errore che si ottiene tuttavia indica chiaramente che l'interprete di script ha problemi nell'individuare o caricare l'assembly. Il modo migliore per risolvere questo problema è con l'utilità ProcMon di SysInternals.

ho eseguito il codice, senza difficoltà, queste sono state le voci più rilevanti nel registro ProcMon:

22 12:04:41.1795038 PM WScript.exe 55280 RegOpenKey HKCR\TTTTTT.FFFFF.CCCCCCCCC SUCCESS Desired Access: Read 
26 12:04:41.1795682 PM WScript.exe 55280 RegOpenKey HKCR\TTTTTT.FFFFF.CCCCCCCCC\CLSID SUCCESS Desired Access: Read 
29 12:04:41.1796996 PM WScript.exe 55280 RegQueryValue HKCR\TTTTTT.FFFFF.CCCCCCCCC\CLSID\(Default) SUCCESS Type: REG_SZ, Length: 78, Data: {3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F} 
34 12:04:41.1797653 PM WScript.exe 55280 RegOpenKey HKCR\CLSID\{3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F} SUCCESS Desired Access: Read 
62 12:04:41.1802539 PM WScript.exe 55280 RegOpenKey HKCR\CLSID\{3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F}\InprocServer32 SUCCESS Desired Access: Read 
71 12:04:41.1804181 PM WScript.exe 55280 RegQueryValue HKCR\CLSID\{3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F}\InprocServer32\(Default) SUCCESS Type: REG_SZ, Length: 24, Data: mscoree.dll 
824 12:04:41.2425662 PM WScript.exe 55280 RegQueryValue HKCR\CLSID\{3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F}\InprocServer32\1.0.0.0\CodeBase SUCCESS Type: REG_SZ, Length: 124, Data: file:///c:/projects/ClassLibrary2/obj/Debug/ClassLibrary2.DLL 
... Lots of .NET keys... 
1239 12:04:41.2970169 PM WScript.exe 55280 CreateFile C:\projects\ClassLibrary2\obj\Debug\ClassLibrary2.dll SUCCESS Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened 
0

può essere, tutti i vostri problemi sono causati da VS. Provare a compilare la libreria dalla riga di comando digitando

csc.exe /t:library AClass.cs /keyfile:Foo.snk - produce your key file with VS! 
regasm /codebase /tlb AClass.dll 

VS stanno aggiungendo un po 'di cose del genere/avvertono:/noconfig e così via, ed inoltre l'aggiunta di riferimenti ad un altro assemblee come System.Core e così via, e a volte causa gli errori. Per me, la compilazione da csc ha funzionato.