COM Interop, hur svårt kan det vara?
mars 17, 2009 21:23Varför är det så att en del problem dyker upp igen och igen när man sitter och utvecklar och varje gång man letar efter lösningen känner man igen sig väldigt väl… lite för väl? Till sist slutar det med att man kommer på vad det är och inser att detta har jag bråkat med förrut, fått frågor om och till och med hjälpt andra med flera gånger under de senaste åren. Ja, det är väl just detta kriterie som gör att en fråga hamnar på en FAQ lista och ställs gång efter gång.
Hur var det nu med COM Interop då? Jo, just detta teknikområde tycks rymma oändliga möjligheter att glömma nån liten detalj och sedan sitter man och felsöker och timmarna bara rusar iväg.
Dagens scenario var en .NET assembly med några interface som skulle anropas från en native-klient på en testmaskin med en nära nog produktionsmässig installation av operativsystem och verktyg. Det är nästan lustigt hur felsökningen långsamt letar sig fram till en lösning. Först testas det på en utvecklarmaskin, där det förstås fungerar. Sedan börjar någon gå på spåret att det kan vara rättigheter som saknas, nähä, inte det heller. Är det verkligen rätt fil vi installerar, det är ju mer än en gång man trott det men haft fel… Man tänker så det knakar, pratar med fler kollegor, börjar gräva i registryt… Skumt, inget spår av den aktuella GUID som borde finnas där. Men vi har ju gjort registreringen av komponenten om och om igen, fram och tillbaks. Nåväl, efter lång felsökning och en god portion frustration, tankar kring att implementera en annan lösning utan COM och lite andra mindre framgångsrika försök hittades felet och avhjälptes under stort jubel. Projektkollegan som hade spenderat mest tid med felsökningen tyckte att lösningen borde vi nog skriva upp och rama in för framtiden. Vi får se om en bloggpost kan vara jämförbart med en inramning.
En .NET assembly som innehåller ett COM gränssnitt och ska bli åtkomlig från COM klienter ska genomgå följande steg för att man ska undvika frustration:
- Registrera .NET assemblyn för att COM-runtime systemet ska kunna lokalisera den
- Generera ett COM Type Library för att klienten ska kunna interagera med de publika typer som finns i assemblyn
- Driftsätta assemblyn antingen i samma katalog som klienten eller i Global Assembly Cache
Verktyget för att göra detta är RegAsm. Syntaxen är som följer:
Microsoft (R) .NET Framework Assembly Registration Utility 2.0.50727.3074
Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.
Syntax: RegAsm AssemblyName [Options]
Options:
/unregister Unregister types
/tlb[:FileName] Export the assembly to the specified type library and register it
/regfile[:FileName] Generate a reg file with the specified name instead of registering the types. This option cannot be used with the /u or /tlb options
/codebase Set the code base in the registry
/registered Only refer to already registered type libraries
/asmpath:Directory Look for assembly references here
/nologo Prevents RegAsm from displaying logo
/silent Silent mode. Prevents displaying of success messages
/verbose Displays extra information
/? or /help Display this usage message
Hade vi inte använt RegAsm då? Jodå, men den lilla väsentliga parametern /tlb hade fallit bort.
Enklaste fallet att registrera och generera rätt Type Library blir så här:
C:\dotnet>RegAsm MyNETAssembly.dll /tlb
Observera att verktyget TlbExp också finns tillgängligt men det skapar enbart type library filen utan att göra korrekt registrering av den. Så RegAsm är trevligare.
Nu återstår att se hur länge det tar att felsöka nästa gång det händer… Men “lagen om att det inte får gå för lätt” kommer väl nu att slå in och se till att det blir ett annat problem vi får leta efter nästa gång.
För att ett COM-objekt ska vara nåbart från .NET måste det vara reggat på maskinen (dvs, existera i registry). På Vista kan UAC:n sätta käppar i hjulet, eftersom registreringen sker under fel konto (userkontot och inte adminkontot). Att registrera objektet under "Run as administrator" kan lösa problem.
Dessutom, om man arbetar i en nerlåst miljö kan man behöva använda DCOMCnfg.exe för att tilldela rättigheter till det konto man kör som (annars tillåts kontot inte instansiera objektet).
/Tomas
Comments are closed.