J'ai écrit un simple objet COM en C# avec une seule méthode, appelée GetMac. Je n'arrive pas à le faire marcher. J'essaie d'y accéder à partir d'une ancienne application Borland C++ Builder 4 (BCB4), que je sais être ancienne, et qui n'est plus beaucoup utilisée, mais je suis capable d'accéder à d'autres objets COM à partir d'elle. La machine de développement Borland exécute Windows XP, donc je cible l'objet COM C# l'infrastructure .NET 4.0. J'ai copié le fichier DLL et PDB de la machine C# Visual Studio vers la machine XP. Je me suis inscrit via la commande suivante:Objet COM écrit en C# - Récupère la classe, mais pas les méthodes
"%WINDIR%\Microsoft.NET\Framework\v4.0.30319\regasm.exe" TRSDotNetCOM.dll /tlb /nologo /codebase
Je suis en mesure d'instancier l'amende objet COM (classe) via la ligne de code suivante:
Variant TDN = CreateOleObject("TRSDotNetCOM.TRSCOM_Class");
Si je change la chaîne de nom, il doesn ne fonctionne pas, donc je sais que j'ai cette partie correcte.
Cependant, lorsque je tente d'appeler la méthode comme suit:
MacV = TDN.OleFunction(funcNameV,counterV,macKeyV);
... Je reçois une exception d'exécution (malheureusement, il y a un problème à l'exception de BCB4 manipulation pour les appels OLE, la seule information du débogueur me donne est "Exception s'est produite").
Étant donné que je suis capable d'appeler d'autres objets COM à partir de la même application BCB4 de la même manière, je ne pense pas que le problème concerne mon code C++. Je pense que c'est un problème avec la DLL COM créée par C#, ou l'enregistrement de celle-ci.
Pour explorer cela, j'ai utilisé Microsoft OLE/COM Object Viewer pour parcourir mon système pour l'objet OLE. J'ai été capable de trouver mon objet comme "TRSDotNetCOM.TRSCOM_Class", comme prévu.
Je suis tout nouveau à l'aide de l'Explorateur d'objets OLE/COM, donc j'espère que je regarde les bonnes choses ci-dessous:
Quand j'élargissons la classe, je vois ce qui suit:
J'ai fait un clic droit sur _Object et j'ai choisi "View", puis "View Type Info". Ensuite, le volet sur la droite affiche:
[ uuid(65074F7F-63C0-304E-AF0A-D51741CB4A8D), hidden, dual, nonextensible,
custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "System.Object")
] dispinterface _Object {
properties:
methods:
[id(00000000), propget,
custom({54FC8F55-38DE-4703-9C4E-250351302B1C}, "1")]
BSTR ToString();
[id(0x60020001)]
VARIANT_BOOL Equals([in] VARIANT obj);
[id(0x60020002)]
long GetHashCode();
[id(0x60020003)]
_Type* GetType(); };
Quand je développez l'arborescence à gauche, ce que je vois:
Je ne vois pas répertorié nulle part là-dedans ma méthode « getmac » . Donc, je pense que d'une manière ou d'une autre la méthode n'est pas visible pour COM, ou qu'elle n'est pas enregistrée via regasm.
Voici la source de l'objet COM:
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace TRSDotNetCOM
{
[Guid("80ef9acd-3a75-4fcd-b841-11199d827e8f")]
public interface TRSCOM_Interface
{
[DispId(1)]
string GetMac(string counter, string macKey);
}
// Events interface Database_COMObjectEvents
[Guid("67bd8422-9641-4675-acda-3dfc3c911a07"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface TRSCOM_Events
{
}
[Guid("854dee72-83a7-4902-ab50-5c7a73a7e17d"),
ClassInterface(ClassInterfaceType.None),
ComVisible(true),
ComSourceInterfaces(typeof(TRSCOM_Events))]
public class TRSCOM_Class : TRSCOM_Interface
{
public TRSCOM_Class()
{
}
[ComVisible(true)]
public string GetMac(string counter, string macKey)
{
// convert counter to bytes
var counterBytes = Encoding.UTF8.GetBytes(counter);
// import AES 128 MAC_KEY
byte[] macKeyBytes = Convert.FromBase64String(macKey);
var hmac = new HMACSHA256(macKeyBytes);
var macBytes = hmac.ComputeHash(counterBytes);
var retval = Convert.ToBase64String(macBytes);
return retval;
}
}
}
Je n'assurerai et d'entrer dans les propriétés du projet et cochez la case « Enregistrer pour COM Interop ». J'ai également généré un fichier de nom sécurisé avec l'utilitaire "sn", et chargé le fichier dans la section Signing des paramètres.
Alors ...
1) Suis-je à la recherche dans le bon endroit dans l'objet OLE/COM Viewer pour ma méthode?
2) Si oui, pourquoi ma méthode ne serait-elle pas visible ou ne serait-elle pas enregistrée?
3) Des idées de quoi d'autre pourrait être faux?
MISE À JOUR: Voici le code mis à jour avec les suggestions de Joe W et Paulo. (Il ne fonctionne toujours pas cependant)
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace TRSDotNetCOM
{
[Guid("80ef9acd-3a75-4fcd-b841-11199d827e8f"),
ComVisible(true)]
public interface TRSCOM_Interface
{
[DispId(1)]
string GetMac(string counter, string macKey);
}
// Events interface Database_COMObjectEvents
[Guid("67bd8422-9641-4675-acda-3dfc3c911a07"),
ComImport,
ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface TRSCOM_Events
{
}
[Guid("854dee72-83a7-4902-ab50-5c7a73a7e17d"),
ClassInterface(ClassInterfaceType.None),
ComDefaultInterface(typeof(TRSCOM_Interface)),
ComVisible(true),
ComSourceInterfaces(typeof(TRSCOM_Events))]
public class TRSCOM_Class : TRSCOM_Interface
{
public TRSCOM_Class()
{
}
public string GetMac(string counter, string macKey)
{
// convert counter to bytes
var counterBytes = Encoding.UTF8.GetBytes(counter);
// import AES 128 MAC_KEY
byte[] macKeyBytes = Convert.FromBase64String(macKey);
var hmac = new HMACSHA256(macKeyBytes);
var macBytes = hmac.ComputeHash(counterBytes);
var retval = Convert.ToBase64String(macBytes);
return retval;
}
}
}
Joe W. - Ok, j'ai juste essayé votre suggestion. J'ai enlevé ComVisible de la fonction et l'ai ajouté à la déclaration d'interface. J'ai reconstruit la DLL, l'ai copiée, enregistrée de nouveau, et cela n'a pas fait de différence. Je reçois toujours l'exception et je ne vois toujours rien à propos de ma méthode dans le programme OLE/COM Object Viewer. – JoeMjr2
J'écrirais un simple script VB pour le tester et sortir les trucs de Borland de l'équation. Peut-être que l'erreur de script VB aurait de meilleurs diagnostics ... –
Joe W, merci pour la suggestion. Je pense que c'est une excellente nouvelle étape. Je ne connais pas VB, cependant. Y a-t-il une chance que je puisse obtenir des instructions pour faire cela, avec le code VB équivalent pour instancier mon objet et appeler ma méthode? – JoeMjr2