{"id":55000317,"date":"2022-04-01T00:00:00","date_gmt":"2023-03-02T17:05:29","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=317"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"COMDLL_fuer_den_Zugriff_auf_die_YouTubeAPI","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/COMDLL_fuer_den_Zugriff_auf_die_YouTubeAPI\/","title":{"rendered":"COM-DLL f&uuml;r den Zugriff auf die YouTube-API"},"content":{"rendered":"<p><b>In der Artikelreihe &#8220;YouTube-Kanal mit VB.NET verwalten&#8221; haben wir Methoden vorgestellt, mit denen wir die Videos eines YouTube-Kanals auslesen und mit denen wir neue Videos hochladen oder die Eigenschaften bestehender Videos anpassen k&ouml;nnen. Diese Methoden wollen wir nun in einer DLL zusammenfassen, die wir in eine Office-Anwendung wie Excel oder Access einbinden k&ouml;nnen, um von dort aus beispielsweise Titel und Beschreibungstexte lesen und schreiben zu k&ouml;nnen. Im vorliegenden Artikel zeigen wir daher, wie wir die bereits beschriebenen Funktionen in einem neuen Projekt verwenden und daraus die gew&uuml;nschte DLL erstellen. In einem weiteren Artikel zeigen wir dann, wie Du von Excel aus die Daten der Videos eines Kanals in eine Excel-Tabelle einlesen kannst.<\/b><\/p>\n<h2>Projekt f&uuml;r die COM-DLL erstellen<\/h2>\n<p>Wenn wir eine COM-DLL erstellen wollen, auf die wir  von Office-Anwendungen aus per VBA zugreifen k&ouml;nnen, w&auml;hlen wir beim Erstellen eines neuen Projekts in Visual Studio den Typ <b>Klassenbibliothek (.NET Framework) &#8211; Ein Projekt zum Erstellen einer Klassenbibliothek (.dll) <\/b>und nicht <b>Klassenbibliothek &#8211; Ein Projekt zum Erstellen einer Klassenbibliothek f&uuml;r .NET Standard oder .NET Core <\/b>aus (siehe Bild 1). Mit letzterer k&ouml;nnen wir aktuell keine COM-DLLs erstellen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_02\/pic_317_001.png\" alt=\"Erstellen eines neuen Projekts\" width=\"700\" height=\"309,5555\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Erstellen eines neuen Projekts<\/span><\/b><\/p>\n<p>Im n&auml;chsten Schritt w&auml;hlen wir den Speicherort aus und geben als Projektnamen <b>YouTubeAPIV3 <\/b>an. Als Zielframework w&auml;hlen wir <b>.NET Core 3.1 <\/b>aus. Das neue Projekt erwartet uns dann in Visual Studio mit einer leeren Klasse namens <b>Class1.vb<\/b>.<\/p>\n<h2>NuGet-Pakete hinzuf&uuml;gen<\/h2>\n<p>F&uuml;r den Zugriff auf die YouTube-API v3 ben&ouml;tigen wir zwei NuGet-Pakete. Um diese hinzuzuf&uuml;gen, &ouml;ffnen wir mit <b>Projekt|NuGet-Pakete verwalten&#8230; <\/b>den <b>NuGet<\/b>-Bereich. Im Bereich <b>Durchsuchen <\/b>suchen wir nach den beiden Paketen <b>Google.Apis.YouTube.v3 <\/b>und <b>Google.Apis.Oauth2.v2 <\/b>und installieren diese.<\/p>\n<h2>Vorbereitungen f&uuml;r die COM-DLL<\/h2>\n<p>Damit die Klasse sp&auml;ter als COM-DLL verwendet werden kann, nehmen wir nun einige Einstellungen in den Projekteigenschaften vor. Dazu &ouml;ffnen wir die Projekteigenschaften mit einem Rechtsklick auf das Projekt im Projektmappen-Explorer und anschlie&szlig;ender Auswahl des Eintrags <b>Eigenschaften <\/b>aus dem nun erscheinenden Kontextmen&uuml;.<\/p>\n<p>Die erste Einstellung finden wir, wenn wir im Bereich <b>Anwendung <\/b>auf die Schaltfl&auml;che <b>Assemblyinformationen&#8230;<\/b> klicken. Das &ouml;ffnet den Dialog <b>Assemblyinformationen<\/b>, wo wir pr&uuml;fen, ob die Option <b>Assembly COM-sichtbar machen <\/b>aktiviert ist und holen dies gegebenenfalls nach (siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_02\/pic_317_003.png\" alt=\"Aktivieren von Assembly COM-sichtbar machen\" width=\"574,6265\" height=\"409,3622\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Aktivieren von Assembly COM-sichtbar machen<\/span><\/b><\/p>\n<p>Danach klicken wir links auf <b>Kompilieren<\/b>, um den entsprechenden Bereich einzublenden. Hier finden wir unten die Eigenschaft <b>F&uuml;r COM-Interop registrieren<\/b>, die wir aktivieren (siehe Bild 3).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_02\/pic_317_002.png\" alt=\"Aktivieren von F&uuml;r COM-Interop registrieren\" width=\"674,627\" height=\"585,7225\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Aktivieren von F&uuml;r COM-Interop registrieren<\/span><\/b><\/p>\n<h2>Klasse mit der Funktion zur Authentifizierung<\/h2>\n<p>F&uuml;r den Zugriff auf die YouTube API v3 ben&ouml;tigen wir eine Authentifizierung, die wir mit der im Artikel <b>YouTube-Kanal mit VB.NET verwalten, Teil 2 <\/b>(<b>www.vbentwickler.de\/316<\/b>) vorgestellten Klasse realisieren. Dazu f&uuml;gen wir die dort beschriebene Klasse <b>Authentication.vb <\/b>in unser neues Projekt ein. Damit wir diese von einem VBA-Projekt aus nutzen k&ouml;nnen, sind jedoch einige Anpassungen n&ouml;tig. Die erste ist eine tats&auml;chliche Funktionserweiterung. Wir m&ouml;chten das dabei gewonnene Token f&uuml;r den Zugriff auf die YouTube-API n&auml;mlich auch separat abrufen k&ouml;nnen, um gegebenenfalls einmal von einem VBA-Projekt aus direkt auf die YouTube-API zugreifen zu k&ouml;nnen.<\/p>\n<p>F&uuml;r den Betrieb als COM-DLL sind &uuml;berdies noch weitere &Auml;nderungen n&ouml;tig. Als Erstes ben&ouml;tigen wir einen Verweis auf den folgenden Namespace in jeder Klasse, die wir von VBA aus initialisieren und nutzen wollen:<\/p>\n<pre>Imports System.Runtime.InteropServices<\/pre>\n<p>Dies erm&ouml;glicht es uns, die zu ver&ouml;ffentlichenden Klassen so auszuzeichnen, dass wir von au&szlig;en auf diese zugreifen k&ouml;nnen. <\/p>\n<h2>Schnittstelle f&uuml;r die Authentifizierungsklasse<\/h2>\n<p>Wenn wir eine Klasse einfach nach au&szlig;en hin ver&ouml;ffentlichen, dann k&ouml;nnen wir beispielsweise von VBA aus immer noch auf einige .NET-Standard-Eigenschaften und -Methoden der Klasse zugreifen wie <b>GetHashCode<\/b>, <b>GetType <\/b>oder <b>ToString<\/b>. Wir wollen jedoch nur die von uns daf&uuml;r vorgesehenen Eigenschaften und Methoden anbieten. Dazu m&uuml;ssen wir eine Schnittstelle erstellen, die wir dann in Form der eigentlichen Klasse implementieren.<\/p>\n<p>Unsere Klasse <b>Authentication.vb <\/b>soll zwei Funktionen ver&ouml;ffentlichen: Die erste liefert das <b>YouTubeService<\/b>-Element und die zweite soll den beim Erstellen des <b>YouTubeService<\/b>-Elements generierten Token liefern und hei&szlig;t <b>Token<\/b>. Die Schnittstelle statten wir daher genau mit der Definition dieser beiden Funktionen aus:<\/p>\n<pre>&lt;InterfaceType(ComInterfaceType.InterfaceIsDual)&gt;\r\n<span style=\"color:blue;\">Public <\/span>Interface IAuthentication\r\n     Function AuthenticateOAuth(strPathClientSecrets _\r\n        <span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As <\/span>YouTubeService\r\n     Function Token()<span style=\"color:blue;\"> As String<\/span>\r\nEnd Interface<\/pre>\n<p>Wie Du siehst, zeichnen wir diese Schnittstelle mit der Annotation <b>InterFaceType <\/b>aus, der wir den Wert <b>ComInterfaceType.InterfaceIsDual <\/b>zuweisen. Was dies bedeutet, schauen wir uns in einem anderen Beitrag im Detail an.<\/p>\n<p>Die Klasse <b>Authenticate<\/b>, die wir in der gleichen Datei wie die Schnittstelle <b>IAuthenticate <\/b>speichern (<b>Authenticate.vb<\/b>), findest Du in Listing 1. Diese Klasse kennzeichnen wir ebenfalls mit der Annotation <b>ClassInterface<\/b>. F&uuml;r diese legen wir jedoch den Wert <b>ClassInterfaceType.None <\/b>fest. Das sorgt daf&uuml;r, dass diese Klasse nicht &ouml;ffentlich ist. Das ist kein Problem, denn ihre Elemente werden ja &uuml;ber die &ouml;ffentliche Schnittstelle <b>IAuthenticate <\/b>ver&ouml;ffentlicht.<\/p>\n<pre>&lt;ClassInterface(ClassInterfaceType.None)&gt;\r\n<span style=\"color:blue;\">Public Class<\/span> Authentication\r\n     Implements IAuthentication\r\n     <span style=\"color:blue;\">Private <\/span>_Token<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Public <\/span>Function AuthenticateOAuth(strPathClientSecrets<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As <\/span>YouTubeService _\r\n              Implements IAuthentication.AuthenticateOAuth\r\n         <span style=\"color:blue;\">Dim <\/span>objYouTubeService<span style=\"color:blue;\"> As <\/span>Google.Apis.YouTube.v3.YouTubeService\r\n         <span style=\"color:blue;\">Dim <\/span>objUserCredential<span style=\"color:blue;\"> As <\/span>UserCredential\r\n         <span style=\"color:blue;\">Dim <\/span>objStream<span style=\"color:blue;\"> As <\/span>FileStream\r\n         objStream = <span style=\"color:blue;\">New<\/span> FileStream(strPathClientSecrets, FileMode.Open, FileAccess.Read)\r\n         objUserCredential = GoogleWebAuthorizationBroker.AuthorizeAsync(\r\n             GoogleClientSecrets.FromStream(objStream).Secrets,\r\n             {YouTubeService.Scope.Youtube},\r\n             \"user\",\r\n             CancellationToken.None).Result\r\n         objYouTubeService = <span style=\"color:blue;\">New<\/span> YouTubeService(<span style=\"color:blue;\">New<\/span> BaseClientService.Initializer() <span style=\"color:blue;\">With<\/span> {\r\n             .HttpClientInitializer = objUserCredential\r\n         })\r\n         _Token = objUserCredential.Token.AccessToken.ToString\r\n         Return objYouTubeService\r\n     End Function\r\n     <span style=\"color:blue;\">Public <\/span>Function Token()<span style=\"color:blue;\"> As String<\/span> Implements IAuthentication.Token\r\n         Return _Token\r\n     End Function\r\n<span style=\"color:blue;\">End Class<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Definition der Klasse Authenticate.vb<\/span><\/b><\/p>\n<p>Au&szlig;erdem m&uuml;ssen wir f&uuml;r diese Klasse den Zusatz <b>Implements IAuthenticate<\/b> hinzuf&uuml;gen, damit diese die Schnittstelle implementiert. F&uuml;r die einzelnen Elemente der Schnittstelle, die wir implementieren, m&uuml;ssen wir ebenfalls jeweils einen Zusatz zur ersten Zeile hinzuf&uuml;gen. Dieser enth&auml;lt zus&auml;tzlich noch den Namen des Elements, das implementiert wird &#8211; f&uuml;r die Funktion <b>AuthenticateOAuth <\/b>lautet der Zusatz beispielsweise <b>Implements IAuthentication.AuthenticateOAuth<\/b>.<\/p>\n<p>Im Vergleich zu der Version der Funktion <b>AuthenticateOAuth<\/b>, die wir im Artikel <b>YouTube-Kanal mit VB.NET verwalten, Teil 2 <\/b>(<b>www.vbentwickler.de\/316<\/b>) vorgestellt haben, haben wir hier noch einen Parameter hinzugef&uuml;gt. Wir wollen die Handhabung der Datei <b>client_secrets.json<\/b>, welche die Authentifizierungsdaten der App enth&auml;lt, etwas &auml;ndern. Ihr Speicherort soll nicht fest im Code verdrahtet sein, sondern wir wollen diesen flexibel als Parameter &uuml;bergeben. So k&ouml;nnen wir diese Datei beispielsweise auch im gleichen Verzeichnis wie die aufrufende Anwendung &#8211; beispielsweise eine Access- oder Excel-Anwendung &#8211; speichern. Wie Du die Datei <b>client_secrets.json <\/b>erh&auml;ltst, lernst Du im Artikel <b>YouTube-Kanal mit VB.NET verwalten, Teil 1 <\/b>(<b>www.vbentwickler.de\/315<\/b>).<\/p>\n<p>Den Pfad zu dieser Datei &uuml;bergeben wir der Funktion <b>AuthenticateOAuth <\/b>als Parameter und nutzen diesen dann innerhalb der Funktion zum Einlesen der ben&ouml;tigten Daten aus der Datei.<\/p>\n<p>In <b>AuthenticateOAuth <\/b>haben wir au&szlig;erdem eine Zeile hinzugef&uuml;gt, welche den Wert der Eigenschaft <b>AccessToken <\/b>aus dem verwendeten <b>UserCredential<\/b>-Objekt in die lokale Variable <b>_Token <\/b>schreibt. Diesen kann die aufrufende Instanz &uuml;ber die Funktion Token abrufen.<\/p>\n<h2>Die Klasse YouTubeChannel<\/h2>\n<p>Die Klasse mit den Funktionen f&uuml;r den Zugriff auf die Daten eines YouTube-Channels haben wir <b>YouTubeChannel <\/b>genannt. Sie enth&auml;lt im Wesentlichen die Elemente, die wir im Artikel <b>YouTube-Kanal mit VB.NET verwalten, Teil 2 <\/b>(<b>www.vbentwickler.de\/316<\/b>) erl&auml;utert haben. Daher gehen wir hier nicht mehr im Detail auf die enthaltenen Anweisungen ein, sondern nur noch auf die notwendigen Anpassungen f&uuml;r die Verwendung in einer COM-DLL.<\/p>\n<p>Genau wie f&uuml;r die Klasse <b>Authenticate<\/b> erstellen wir auch f&uuml;r die Klasse <b>YouTubeChannel<\/b> eine Schnittstelle. Diese sieht wie in Listing 2 aus. Auch in der Klassendatei <b>YouTubeChannel.vb <\/b>f&uuml;gen wir oben einen Verweis auf den Namespace <b>System.Runtime.InteropServices <\/b>ein, damit wir die Annotationen f&uuml;r die Ver&ouml;ffentlichungen der Klasse definieren k&ouml;nnen.<\/p>\n<pre>Imports System.Runtime.InteropServices\r\n&lt;InterfaceType(ComInterfaceType.InterfaceIsDual)&gt;\r\n<span style=\"color:blue;\">Public <\/span>Interface IYouTubeChannel\r\n     Function GetAllVideos(strChannelID<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As <\/span>Collection\r\n     Sub AddPlaylist(strPlaylist<span style=\"color:blue;\"> As String<\/span>, strDescription<span style=\"color:blue;\"> As String<\/span>)\r\n     Sub UploadVideo(strVideoPath<span style=\"color:blue;\"> As String<\/span>, strTitle<span style=\"color:blue;\"> As String<\/span>, strDescription<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strThumbnail<span style=\"color:blue;\"> As String<\/span> = \"\")\r\n     Sub UploadThumbnail(strThumbnail<span style=\"color:blue;\"> As String<\/span>, strVideoID<span style=\"color:blue;\"> As String<\/span>)\r\n     Function GetVideo(strID<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As <\/span>MyVideo\r\n     Sub UpdateVideo(strID<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> strTitle<span style=\"color:blue;\"> As String<\/span> = \"\", <span style=\"color:blue;\">Optional<\/span> strDescription<span style=\"color:blue;\"> As String<\/span> = \"\", _\r\n         <span style=\"color:blue;\">Optional<\/span> strThumbnail<span style=\"color:blue;\"> As String<\/span> = \"\")\r\n     Property PathClientSecrets<span style=\"color:blue;\"> As String<\/span>\r\nEnd Interface<\/pre>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000317\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/data\/wp\/v2\/posts\/55000317?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000317\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"2ce33e69ce\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In der Artikelreihe &#8220;Youtube-Kanal mit VB.NET verwalten&#8221; haben wir Methoden vorgestellt, mit denen wir die Videos eines Youtube-Kanals auslesen und mit denen wir neue Videos hochladen oder die Eigenschaften bestehender Videos anpassen k&ouml;nnen. Diese Methoden wollen wir nun in einer DLL zusammenfassen, die wir in eine Office-Anwendung wie Excel oder Access einbinden k&ouml;nnen, um von dort aus beispielsweise Titel und Beschreibungstexte lesen und schreiben k&ouml;nnen. Im vorliegenden Artikel zeigen wir daher, wie wir die bereits beschriebenen Funktionen in einem neuen Projekt verwenden und daraus die gew&uuml;nschte DLL erstellen. In einem weiteren Artikel zeigen wir dann, wie Du von Excel aus die Daten der Videos eines Kanals in eine Excel-Tabelle einlesen kannst.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66022022,662022,44000035,44000025],"tags":[],"yst_prominent_words":[],"class_list":["post-55000317","post","type-post","status-publish","format-standard","hentry","category-66022022","category-662022","category-COMDLLs_programmieren","category-VBAProgrammierung"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000317","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000317"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000317\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000317"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}