COM-yhteentoimivuus ja ajonaikaiset kutsukääreet
Käyttäkää COM-komponentteja C#:sta RCW:n avulla, tuokaa tyyppikirjastoja ja käsitelkää HRESULT-poikkeuksia.
COM-yhteentoimivuus ja ajonaikaiset kutsukääreet on ilmainen C# Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C# Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C# Academy-kurssilla on yhteensä 4 oppituntia.
Mitä COM-yhteentoimivuus on
COM (Component Object Model) on Microsoftin perinteinen binäärirajapintastandardi, jota käytetään edelleen Officessa, Windows Shellissä, DirectX:n vanhoissa rajapinnoissa ja monissa yritystyökaluissa. .NET voi käyttää COM-komponentteja yhteentoimivuuskääreiden kautta, jotka muuntavat hallittujen olioiden ja COM-rajapintojen välillä.
Runtime Callable Wrapperit (RCW)
Kun käytät COM-oliota .NETistä, CLR luo Runtime Callable Wrapperin (RCW) eli COM-olion ympärille hallitun välityspalvelimen. RCW huolehtii automaattisesti viitelaskennasta (AddRef/Release), COM-apartmentien säikeistyksestä ja COM- sekä .NET-tyyppien välisestä marshalaamisesta.
// The RCW is created automatically when you instantiate a COM class
// via a registered ProgID or CLSID
// Example: create an Excel Application COM object
Type excelType = Type.GetTypeFromProgID("Excel.Application")!;
object excelApp = Activator.CreateInstance(excelType)!;
// excelApp is an RCW — the CLR wraps the underlying IDispatch COM object
// COM AddRef is called; CLR tracks references
Console.WriteLine(excelApp.GetType().Name); // ApplicationClassTyyppikirjastojen tuominen (TLB)
tlbimp.exe-työkalu (Type Library Importer) lukee COM-tyyppikirjaston (.tlb-tiedoston tai .dll-tiedostoon upotetun kirjaston) ja tuottaa .NET-yhteentoimivuuskokoonpanon, joka sisältää vahvasti tyypitetyt RCW-luokat ja rajapintamäärittelyt.
// From a Developer Command Prompt:
// tlbimp MyComLib.dll /out:MyComLib.Interop.dll
// Or reference via Visual Studio:
// Add Reference → COM → Microsoft Excel 16.0 Object Library
// → Generates Microsoft.Office.Interop.Excel.dll automatically
// The generated Interop assembly contains:
// - Interface types (matching COM vtable layout)
// - Co-class wrappers (implement the interfaces)
// - Enum types (from the type library)
// - Delegate types for COM event sinksCOM-olion käyttäminen interop-kokoonpanon kautta
Kun olet lisännyt viittauksen interop-kokoonpanoon, COM-tyypit näyttävät tavallisilta .NET-tyypeiltä. Metodikutsu välittyy RCW:n kautta COM:n vtable-dispatchiksi. Vapauta COM-oliot aina asianmukaisesti resurssivuotojen välttämiseksi.
using Microsoft.Office.Interop.Excel;
Application excel = new Application();
excel.Visible = false;
Workbooks books = excel.Workbooks;
Workbook wb = books.Add();
Worksheet ws = (Worksheet)wb.Sheets[1];
((Range)ws.Cells[1, 1]).Value = "Hello, COM!";
wb.SaveAs(@"C:\Temp\test.xlsx");
wb.Close();
// Release COM RCW explicitly
Marshal.ReleaseComObject(ws);
Marshal.ReleaseComObject(wb);
Marshal.ReleaseComObject(books);
excel.Quit();
Marshal.ReleaseComObject(excel);Marshal.ReleaseComObject
COM käyttää viitelaskentaa: AddRef/Release. RCW kutsuu Release-metodia vasta, kun GC kerää sen, mikä voi tapahtua paljon myöhemmin. Kutsu Marshal.ReleaseComObject()-metodia pienentääksesi RCW:n viitelaskuria välittömästi ja vapauttaaksesi COM-olion odottamatta GC:tä.
// Pattern: release COM objects in finally block
Application? excel = null;
Workbook? wb = null;
try
{
excel = new Application();
wb = excel.Workbooks.Add();
// ... do work ...
}
finally
{
if (wb != null) Marshal.ReleaseComObject(wb);
if (excel != null)
{
excel.Quit();
Marshal.ReleaseComObject(excel);
}
// Force GC to clean up any remaining RCWs
GC.Collect();
GC.WaitForPendingFinalizers();
}HRESULT ja COM-poikkeukset
COM-metodit palauttavat HRESULT-arvoja ilmoittaakseen onnistumisesta tai epäonnistumisesta. RCW tarkistaa HRESULT-arvon automaattisesti ja heittää COMException-poikkeuksen tai tarkemman poikkeuksen, kun arvo ilmaisee epäonnistumista. Käsittele niitä tavallisella try/catch-rakenteella.
try
{
// COM method that might fail
Workbook wb = excel.Workbooks.Open(@"C:\missing.xlsx");
}
catch (COMException ex) when (ex.HResult == unchecked((int)0x800A03EC))
{
// Excel-specific HRESULT for file not found
Console.WriteLine($"Excel error: {ex.Message}");
}
catch (COMException ex)
{
// General COM failure
Console.WriteLine($"COM error 0x{ex.HResult:X8}: {ex.Message}");
}Myöhäinen sidonta dynamic-avainsanalla
Jos käytettävissä ei ole tyyppikirjastoa tai interop-kokoonpanoa, voit käyttää C#:n dynamic-avainsanaa myöhäissidottuun COM-dispatchiin (IDispatch). Tämä on hitaampaa, koska dispatch-tunnisteet ratkaistaan ajonaikana, mutta generoitua käärettä ei tarvita.
// Late-bound COM via dynamic — no interop DLL needed
Type type = Type.GetTypeFromProgID("Word.Application")!;
dynamic word = Activator.CreateInstance(type)!;
word.Visible = false;
dynamic docs = word.Documents;
dynamic doc = docs.Add();
doc.Content.Text = "Late-bound COM example";
doc.SaveAs2(@"C:\Temp\test.docx");
doc.Close();
word.Quit();
Marshal.ReleaseComObject(doc);
Marshal.ReleaseComObject(docs);
Marshal.ReleaseComObject(word);COM-tapahtumavastaanottimet
COM-oliot lähettävät tapahtumia yhteyspisteiden kautta. Interop-kokoonpano generoi tapahtumavastaanotinrajapinnat. Tapahtumiin liitytään tavallisten .NET-delegaattien ja -tapahtumien avulla, ja RCW huolehtii COM:n IConnectionPoint-kytkennästä.
using Microsoft.Office.Interop.Excel;
Application excel = new Application();
excel.Visible = true;
// Subscribe to COM event via generated event wrapper
excel.WorkbookBeforeClose += (wb, ref cancel) =>
{
Console.WriteLine($"Closing: {wb.Name}");
// Set cancel = true to prevent close
};
excel.WorkbookOpen += (wb) =>
{
Console.WriteLine($"Opened: {wb.Name}");
};
// Open a workbook to trigger events
excel.Workbooks.Open(@"C:\Temp\test.xlsx");COM-apartmentit: STA vs. MTA
Monet COM-komponentit, erityisesti käyttöliittymiin liittyvät komponentit, kuten Office, edellyttävät yksisäikeistä apartmentia (STA). Merkitse STA-COM-olioita luovat säikeet aina attribuutilla [STAThread] (Main) tai määritä säikeen apartment-tila ennen säikeen käynnistämistä.
// Console apps default to MTA — COM Office automation requires STA
// Option 1: Mark Main with [STAThread]
[STAThread]
static void Main()
{
var excel = new Microsoft.Office.Interop.Excel.Application();
// ...
}
// Option 2: Run on an STA thread manually
Thread staThread = new Thread(() =>
{
var excel = new Microsoft.Office.Interop.Excel.Application();
// ...
excel.Quit();
Marshal.ReleaseComObject(excel);
});
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
staThread.Join();ComImport ja COM-rajapintojen manuaaliset määrittelyt
Voit määrittää COM-rajapinnat manuaalisesti käyttämällä attribuutteja [ComImport], [Guid] ja [InterfaceType]. Tämä on hyödyllistä, kun tyyppikirjastoa ei ole tai tarvitset vain osan suuresta COM-rajapinnasta.
[ComImport]
[Guid("00000000-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IUnknown
{
void QueryInterface(ref Guid riid, out IntPtr ppvObject);
int AddRef();
int Release();
}
// Declare a specific COM interface you want to consume:
[ComImport]
[Guid("0000010C-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPersist
{
void GetClassID(out Guid pClassID);
}Pikatarkistus
Mikä on Runtime Callable Wrapperin (RCW) tehtävä .NETin COM-yhteentoimivuudessa?
Kertaus: COM-yhteentoimivuus ja Runtime Callable Wrapperit
Keskeiset opit:
- RCW on COM-olion ympärille muodostettu hallittu välityspalvelin; CLR luo sen automaattisesti jokaiselle COM-oliolle
- Luo vahvasti tyypitettyjä interop-kokoonpanoja käyttämällä
tlbimp.exe-työkalua tai Visual Studion References-toimintoa - Vapauta COM-oliot heti kutsumalla
Marshal.ReleaseComObject()-metodia – älä odota GC:n suorittamaa keräystä - COM-virheet näkyvät
COMException-poikkeuksina, jotka sisältävät alkuperäisen HRESULT-arvon dynamicmahdollistaa myöhäissidotun COM-dispatchin ilman interop-kokoonpanoa- Office- ja käyttöliittymäkomponentit edellyttävät STA-säiettä – käytä
[STAThread]-attribuuttia tai määritä apartment-tila
Opi C# tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 93
- Oppitunnit
- 346
Usein kysytyt kysymykset
Onko oppitunti ”COM-yhteentoimivuus ja ajonaikaiset kutsukääreet” ilmainen?
Kyllä – oppitunnin ”COM-yhteentoimivuus ja ajonaikaiset kutsukääreet” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C# Academy-kurssin, päivitä CoddyKit PROhon. C# Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”COM-yhteentoimivuus ja ajonaikaiset kutsukääreet”?
Käyttäkää COM-komponentteja C#:sta RCW:n avulla, tuokaa tyyppikirjastoja ja käsitelkää HRESULT-poikkeuksia. Harjoittelet C# Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C# Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C# Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”COM-yhteentoimivuus ja ajonaikaiset kutsukääreet”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C# Academy-oppitunnilla?
Kyllä. Jokainen C# Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- P/Invoken perusteet
- LibraryImport ja lähdekoodin generoima P/Invoke
- Turvaton koodi, osoittimet ja kiinteät puskurit
- COM-yhteentoimivuus ja ajonaikaiset kutsukääreet