12/18/2004

RemoteTunes 完成

RemoteTunes、できた。C#.NET+DCOMでiTunesをリモート操作します。
remotetunes

コードの肝は以下のライブラリで、GUI部分は単にこれらを呼んでいるだけです。これを作ると何がいいって、デバッグしやすいってだけですかね。tlbimpしたDLLを使ってもいいんですけど。


using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace ITunesLib {
[ComImport()]
[Guid("9FAB0E27-70D7-4E3A-9965-B0C8B8869BB6")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IITObject {
[DispId(0x60020001)]
string Name { get; set; }
}

[ComImport()]
[Guid("4CB0915D-1E54-4727-BAF3-CE6CC9A225A1")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IITTrack : IITObject {
[DispId(0x60030005)]
string Album { get; set; }
[DispId(0x60030007)]
string Artist { get; set; }
}

[ComImport()]
[Guid("9DD6680B-3EDC-40db-A771-E6FE4832E34A")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IITunes {
[DispId(0x60020000)]
void BackTrack();
[DispId(0x60020002)]
void NextTrack();
[DispId(0x60020003)]
void Pause();
[DispId(0x60020004)]
void Play();
[DispId(0x60020008)]
void Resume();
[DispId(0x6002000a)]
void Stop();
[DispId(0x60020037)]
IITTrack CurrentTrack {
get;
}
}

[ComImport()]
[Guid("DC0C2640-1415-4644-875C-6F4D769839BA")]
[ClassInterface(ClassInterfaceType.None)]
public class ITunesApp : IITunes {
#region IITunes メンバ

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60020000)]
extern void IITunes.BackTrack();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60020002)]
extern void IITunes.NextTrack();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60020003)]
extern void IITunes.Pause();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60020004)]
extern void IITunes.Play();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60020008)]
extern void IITunes.Resume();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x6002000a)]
extern void IITunes.Stop();
[DispId(0x60020037)]
extern IITTrack IITunes.CurrentTrack {
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60020037)] get;
}

#endregion
}
}


でもって、クライアント側にiTunesをインスコするのはめんどくさいに決まってるので、iTunes.exeからTYPELIBリソースをエクスポートして、iTunesTypeLib.tlbとかいう名前でファイルを作ります。

クライアント側には.NET Framework 1.1を入れて、RemoteTunes.exeとiTunesTypeLib.tlbをコピーします。regtlb.exeあたりを使って、iTunesTypeLib.tlbをレジストリに登録しましょう。この作業は、iTunesをクライアント側にも入れているなら不要です。

さらに、次のようなレジストリエントリを作ります。「RemoteServerName」のところ、iTunesが入ってるマシンの名前(Windows名)を入れること。


Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\AppID\{F98206B5-F052-4965-9FA0-85F61BC3C19D}]
@="iTunes"
"RemoteServerName"="HEY THIS IS WHERE YOUR ITUNES SERVER NAME SHOULD BE"

[HKEY_CLASSES_ROOT\AppID\iTunes.exe]
"AppID"="{F98206B5-F052-4965-9FA0-85F61BC3C19D}"

[HKEY_CLASSES_ROOT\CLSID\{DC0C2640-1415-4644-875C-6F4D769839BA}]
@="iTunes Class"
"AppID"="{F98206B5-F052-4965-9FA0-85F61BC3C19D}"

[HKEY_CLASSES_ROOT\CLSID\{DC0C2640-1415-4644-875C-6F4D769839BA}\ProgID]
@="iTunes.Application.1"

[HKEY_CLASSES_ROOT\CLSID\{DC0C2640-1415-4644-875C-6F4D769839BA}\TypeLib]
@="{9E93C96F-CF0D-43f6-8BA8-B807A3370712}"

[HKEY_CLASSES_ROOT\CLSID\{DC0C2640-1415-4644-875C-6F4D769839BA}\VersionIndependentProgID]
@="iTunes.Application"

[HKEY_CLASSES_ROOT\Interface\{9DD6680B-3EDC-40DB-A771-E6FE4832E34A}]
@="IiTunes"

[HKEY_CLASSES_ROOT\Interface\{9DD6680B-3EDC-40DB-A771-E6FE4832E34A}\ProxyStubClsid]
@="{00020424-0000-0000-C000-000000000046}"

[HKEY_CLASSES_ROOT\Interface\{9DD6680B-3EDC-40DB-A771-E6FE4832E34A}\ProxyStubClsid32]
@="{00020424-0000-0000-C000-000000000046}"

[HKEY_CLASSES_ROOT\Interface\{9DD6680B-3EDC-40DB-A771-E6FE4832E34A}\TypeLib]
@="{9E93C96F-CF0D-43F6-8BA8-B807A3370712}"
"Version"="1.2"


さてさてこれでインスコは終わりなんですが、昨今のWindowsはセキュリティが厳しいので、作業はまだあるんですな。まず、管理ツールでコンポーネント サービスを開いて、コンポーネント サービス-コンピュータ-マイ コンピュータ-DCOM の構成と展開すると、段ボール箱にボールが入ったアイコンがいっぱい出ますね。中に「iTunes」があるんで、右クリックでプロパティを開けます。で、「ID」タブで「対話ユーザー」を選択しましょう。これやらないと、GUIをもつDCOMサーバーは、たいていまともに動きません。

実はクライアント側でも「コンポーネント サービス」でサーバー名とか設定できるんですが、今回は上のレジストリ設定でやっちゃったので、なし。

それと、XP SP2とかでファイアウォールを使ってる場合は、サーバー側でTCP 135を開けないとDCOMは使えません。

さらに、サーバー側のWindowsで有効なWindowsユーザーと同じユーザー名パスワードのユーザーをクライアント側でも使って、RemoteTunes.exeを起動しないと、セキュリティではねられます。ドメインなら同じユーザーでいいけど、自宅でActive Directory、しないよなぁ。。

そういうわけで久々のDCOMプログラミングは意外にすんなりいったのでした。あー、強いていえば、iTunesにはCOMイベントも定義されているんだけど、うまく拾えませんでした。

0 件のコメント: