2009-11-04 19 views
8

Ho creato una DLL in C# utilizzando il framework .NET 3.0.Esegui codice .NET 3.0 da Office 2003

Di seguito si riporta il codice della mia DLL

namespace CompanyName.Net 
{ 
    [Guid("F7075E8D-A6BD-4590-A3B5-7728C94E372F")] 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [ProgId("CompanyName.Net.Webrequest")] 
    public class WebRequest 
    { 
     public string Result { get; private set; } 
     public string Url { get; set; } 
     public string StatusDescription { get; private set; } 
     public HttpStatusCode StatusCode { get; private set; } 

     public WebRequest() 
     { 
      //explicit constructor 
     }  

     public string GetResponse(string url) 
     { 
      System.Net.WebRequest webreq = System.Net.WebRequest.Create(url); 
      HttpWebResponse response = (HttpWebResponse) webreq.GetResponse(); 
      // Store the status. 
      StatusDescription = response.StatusDescription; 
      StatusCode = response.StatusCode; 
      // Get the stream containing content returned by the server. 
      Stream dataStream = response.GetResponseStream(); 
      // Open the stream using a StreamReader for easy access. 
      StreamReader reader = new StreamReader(dataStream); 
      // Read the content. 
      Result = reader.ReadToEnd(); 
      // Cleanup the streams and the response. 
      reader.Close(); 
      dataStream.Close(); 
      response.Close(); 
      //return the response 
      return Result; 
     } 
    } 
} 

Sto cercando di ottenere questo codice per eseguire dal codice VBA di Office 2003. La DLL è stata firmata utilizzando la firma predefinita di Visual Studio 2008.

sono riuscito a riferimento il mio assemblaggio con la creazione di un file TLB utilizzando

regasm /tlb c:\CompanyName.Net.dll 

Ma quando voglio creare un'istanza dell'oggetto:

Private Sub Command0_Click() 
    Dim o As Object 
    Set o = CreateObject("CompanyName.Net.WebRequest") 
    Dim s As String 
    s = o.GetResponse("http://www.google.be") 
    MsgBox s 
End Sub 

ottengo il seguente errore :

ActiveX component can't create Object

Cosa sto facendo male?

La macchina con cui sto eseguendo il test ha installato .NET nel framework .NET 3.5.

risposta

10

OK, dopo alcune belle idee di Thorsten Dittmar ho finalmente ottenuto il risultato. Alcune cose che sono emerse durante la nostra discussione e le altre cose che ho trovato sul web: deve essere installato sul computer di destinazione

quadro
  1. .NET.
  2. . Necessario installare il supporto programmabilità sulla macchina di destinazione.
  3. In AssemblyInfo.cs assicurarsi di impostare

    [assembly: ComVisible(true)]

  4. Come Thorsten sottolineato è necessario avere costruttore pubblico senza parametri nella classe .Net.

  5. Assicurarsi di selezionare "Registra per COM Interop" nella scheda Costruisci nella pagina Proprietà del progetto.
  6. Assicurarsi di firmare il progetto utilizzando la scheda Firma nella pagina Proprietà del progetto.
  7. Registrare la DLL sul computer di destinazione eseguendo questo comando. Il parametro /codebase sembrava fare il trucco per me. Il percorso della libreria dei tipi (.tlb) o della DLL non ha importanza. Potete trovare regasm in C: \ Windows \ Microsoft.Net \ Framework \ v2.050727 \ RegAsm.exe

    regasm c:\CompanyName.Net.dll /tlb:CompanyName.Net.tlb /codebase

  8. riferimento il file TLB nel vostro editor VBA utilizzando Strumenti> Riferimenti.

  9. Trascinare la DLL da C: \ al GAC in C: \ Windows \ assembly \ (inizialmente non l'avevo capito, ma a quanto pare è necessario che Office trovi l'assembly.)

Questo dovrebbe fare il trucco.

Ho anche aggiornato la mia classe Webrequest aggiungendo un'interfaccia per abilitare il supporto IntelliSense in VB6 (che purtroppo non funziona in VBA).

+0

Questa è la guida più succinta e completa su questo problema che ho trovato dopo ore di tentativi per farlo funzionare. Grazie. –

2

È necessario un costruttore esplicito senza parametri nella classe COM. Modifica la definizione della tua classe in:

namespace CompanyName.Net 
{ 
    [Guid("F7075E8D-A6BD-4590-A3B5-7728C94E372F")] 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [ProgId("CompanyName.Net.Webrequest")] 
    public class WebRequest 
    { 
     public string Result { get; private set; } 
     public string Url { get; set; } 
     public string StatusDescription { get; private set; } 
     public HttpStatusCode StatusCode { get; private set; } 

     public WebRequest() 
     { 
     } 

     public string GetResponse(string url) 
     { 
      System.Net.WebRequest webreq = System.Net.WebRequest.Create(url); 
      HttpWebResponse response = (HttpWebResponse) webreq.GetResponse(); 
      // Store the status. 
      StatusDescription = response.StatusDescription; 
      StatusCode = response.StatusCode; 
      // Get the stream containing content returned by the server. 
      Stream dataStream = response.GetResponseStream(); 
      // Open the stream using a StreamReader for easy access. 
      StreamReader reader = new StreamReader(dataStream); 
      // Read the content. 
      Result = reader.ReadToEnd(); 
      // Cleanup the streams and the response. 
      reader.Close(); 
      dataStream.Close(); 
      response.Close(); 
      //return the response 
      return Result; 
     } 
    } 
} 

Questo dovrebbe funzionare.

+0

Ho appena provato ma mi dà ancora lo stesso errore. Ho contrassegnato il mio progetto come "registro per l'interoperabilità COM" ma nessuna gioia. Forse il modo in cui sto chiamando la mia funzione in VBA è sbagliato? Sono in perdita – Peter

+0

Hai registrato nuovamente la DLL? –

+0

Ho ricreato il file tlb che dovrebbe anche registrare di nuovo la dll. Posso provare ad aggiungerlo nuovamente al GAC? – Peter