GetActiveObjectメソッドと同等の機能を.Net Core 8.0で実装する
はじめに
.NET Frameworkでは、System.Runtime.InteropServices.MarshalクラスのGetActiveObjectメソッドを使用して、既に実行中のCOMオブジェクトを取得することができました。
このメソッドは、指定されたクラス識別子(CLSID)に基づいて、実行中のCOMオブジェクトへの参照を取得する便利な機能を提供していました。
しかし、.NET Coreに移行すると、このメソッドは提供されておらず、開発者は代替手段を見つける必要があります。
.NET Coreは、クロスプラットフォームの互換性とパフォーマンスの向上を重視して設計されていますが、その結果として一部のAPIが削除されたり変更されたりしています。
GetActiveObjectメソッドもその一つで、.NET Coreでは直接利用することができません。このため、.NET Core 8.0で同様の機能を実現するには、P/Invoke(※)を使用してWindows APIのGetActiveObject関数を呼び出す必要があります。
この記事では、.NET Core 8.0でGetActiveObjectメソッドと同等の機能を実装する方法を詳しく解説します。具体的なコード例を通じて、P/Invokeを使用してCOMオブジェクトを取得する手順を示し、開発者がスムーズに.NET Coreへの移行を行えるようサポートします。
※P/Invoke…P/Invoke(Platform Invocation Services)とは、.NETアプリケーションからネイティブのアンマネージコード(主にCやC++で書かれたDLL)を呼び出すための機能です。これにより、.NETのマネージコードからWindows APIや他のネイティブライブラリの関数を利用することが可能になります。
前提条件
・開発ツール:VisualStudio2022
・開発言語:C#
・.Net FrameWorkから.Net Coreへの移行が完了している(詳しくはこちら)
現象
.Net FrameWork 4.8で作成されていたプロジェクトファイルを.Net Core 8.0へ移行してからビルドした際、「MarshalクラスにGetActiveObjectは存在しない」というエラーが発生した。
解決策
エラーが起きているプロジェクト内に新たな.csファイルを作成し、以下コードを書きます。
新たなファイルはここではPInvoke.csとします。
using System;
using System.Runtime.InteropServices;
namespace TQ84 {
public class COM {
[DllImport("oleaut32.dll", PreserveSig=false)]
static extern void GetActiveObject(
ref Guid rclsid,
IntPtr pvReserved,
[MarshalAs(UnmanagedType.IUnknown)] out Object ppunk
);
[DllImport("ole32.dll")]
static extern int CLSIDFromProgID(
[MarshalAs(UnmanagedType.LPWStr)] string lpszProgID,
out Guid pclsid
);
public static object getActiveObject(string progId) {
Guid clsid;
CLSIDFromProgID(progId, out clsid);
object obj;
GetActiveObject(ref clsid, IntPtr.Zero, out obj);
return obj;
}
}
}
コード説明
①GetActiveObject関数の定義
[DllImport("oleaut32.dll", PreserveSig=false)]
static extern void GetActiveObject(
ref Guid rclsid,
IntPtr pvReserved,
[MarshalAs(UnmanagedType.IUnknown)] out Object ppunk
);
DllImport
属性を使用して、oleaut32.dll
からGetActiveObject
関数をインポートしています。PreserveSig=false
は、メソッドがHRESULTを返さずに、例外をスローすることを指定しています。- 関数の引数は、CLSIDを参照渡しし、
pvReserved
には予約されているIntPtr
を渡します。 - 最後の引数は、
IUnknown
としてマーシャリングされたオブジェクトをアウトパラメータとして取得します。
②CLSIDFromProgID関数の定義
[DllImport("ole32.dll")]
static extern int CLSIDFromProgID(
[MarshalAs(UnmanagedType.LPWStr)] string lpszProgID,
out Guid pclsid
);
DllImport
属性を使用して、ole32.dll
からCLSIDFromProgID
関数をインポートしています。- 関数の引数は、
LPWStr
としてマーシャリングされたProgID(プログラム識別子)と、CLSIDをアウトパラメータとして取得します。
➂getActiveObjectメソッドの定義
public static object getActiveObject(string progId) {
Guid clsid;
CLSIDFromProgID(progId, out clsid);
object obj;
GetActiveObject(ref clsid, IntPtr.Zero, out obj);
return obj;
}
}
getActiveObject
メソッドは、指定されたProgIDを基に実行中のCOMオブジェクトを取得します。- まず、
CLSIDFromProgID
関数を使用してProgIDをCLSIDに変換します。 - 次に、
GetActiveObject
関数を使用して、取得したCLSIDに基づいて実行中のCOMオブジェクトを取得します。 - 最後に、取得したCOMオブジェクトを返します。
まとめ
.NET CoreでGetActiveObject
メソッドを使用するためには、P/Invokeを使用してWindows APIを呼び出す必要があります。これにより、.NET Core環境でも既に実行中のCOMオブジェクトを取得することが可能です。
テレワークによる運動不足が気になる方はこれ!
テレワークの増加に伴い、座りっぱなしの時間が増え、運動不足を感じるエンジニアも多いのではないでしょうか?長時間デスクに向かう日々の中で、心身の健康を維持するためには、適度な運動が欠かせません。
そこでおすすめなのがエアロバイクです。特に「フィットネスバイク 1年保証 本格派 スタイリッシュスピンバイク 1521 BK1521 アルインコ 直営店 ALINCOロングハンドル 負荷8段階 ドリンクホルダー付 安全設計 家庭用ネット限定品 大型宅配商品“>スピンバイク1521」をお勧めします。
どちらも高い性能を誇り、自宅で手軽に脂肪燃焼に繋がる有酸素運動ができるので、仕事の合間に気軽に体を動かすことができます。
初心者でダイエットが目的の方は「フィットネスバイク 1年保証 本格派 スタイリッシュスピンバイク 1521 BK1521 アルインコ 直営店 ALINCOロングハンドル 負荷8段階 ドリンクホルダー付 安全設計 家庭用ネット限定品 大型宅配商品“>スピンバイク1521」がいいと思います。
価格はそれぞれ15,800円と49,800円で決して安くはないですが、これを使うことで生活習慣病予防になると考えたら安いと思えるはずです。
エンジニアとしてのパフォーマンスを最大化するために、「フィットネスバイク 1年保証 本格派 スタイリッシュスピンバイク 1521 BK1521 アルインコ 直営店 ALINCOロングハンドル 負荷8段階 ドリンクホルダー付 安全設計 家庭用ネット限定品 大型宅配商品“>スピンバイク1521」で手軽に運動習慣を取り入れてみませんか?