【C#】MTP(WPD)なデジカメやらスマフォから,C#でファイルをコピーしたい
関連記事
- なんと!今週の土曜日も仕事してますた.来週の土曜日も仕事臭い.TCPソケット通信をゴリゴリ書いてる 【2025年08月30日(土)】
- 【ChatGPT o4】祝日なのに仕事ーバテすぎー今夜こそ絶命だーモルモルモル 【2025年03月20日(木)】
- 【#CSharp】制御系が動き出したべ 【2025年02月20日(木)】
- 【#CSharp】ひっさしぶりにガッツリなC#案件をやっているぞー 【2025年02月19日(水)】
- 今週もひたすらモノ書き #JAVA 祭りがまだまだ続く そろそろC#を書かせろー 【2024年12月04日(水)】
エクスプローラは,もちろんなし
アプリケーションでコピーをやるじぃ.
いや,今仕事でやっている某機械の出力データが,USB経由なMTP接続とか,凶悪な仕様なことが判明して
MTPはこれ.Media Transfer Protocolっす
エクスプローラ上で見たら,ドライブレターなしで表示される奴
![]()
WPD(Windows Portable Devices)とも呼ばれるらしい
ドライブレターが無いから,コマンドプロンプトでは,コピー出来んじぃ(いや,出来ない理由はもっと深いところにあるんじゃが)
さて,サンプルはC++で,チラチラと?
めんどくせぇ~~C#向けラッパーDLLで実装かぁ?だったんじゃが
C#でのやり方を発見!@Fun with MTP in C#:Andrew Trevarrow
COMの
PortableDeviceApi 1.0 Type Library
PortableDeviceTypes 1.0 Type Library
を引き込んでやればいいっぽい
そっから『PortableDeviceApi』でググって行ったら,日本語の記事ハケーン@Canonのデジカメからファイル一覧を取得したい:MSDN
おおおっ!まさしくこれやじ!!
しかもサンプルコード@C#なページヘのリンクへも@WPD: Transferring Content:Christophe Geers’ Blog ここのページのサンプルコードWPDTransferToDevice.zipが,まんまそのものでごわした(;´Д`)ハァハァ
んが,デジカメではファイル名が取れるけど
ターゲットの機械では,ファイル名が取れない.オブジェクト名=ファイル名は空で返ってくる(むむむっ
17時位からずっと,考えこむこと4時間(メシは食った.焼酎でへべれけになりながらソース追跡:爆)
分かった!分かった!!
COMから返ってきたオブジェクトをC#なオブジェクトに載せ替えてるけど
この際,COM側オブジェクトのプロパティのアクセスPIDを”ディレクトリ”と”ファイル”では,変えてやらないといけないっちゃ
private static PortableDeviceObject WrapObject(IPortableDeviceProperties properties, string objectId)
{
IPortableDeviceKeyCollection keys;
properties.GetSupportedProperties(objectId, out keys);
IPortableDeviceValues values;
properties.GetValues(objectId, keys, out values);
// Get the name of the object
string name;
var property = new _tagpropertykey();
property.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC,
0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);
property.pid = 4; //WPD_OBJECT_NAME
//property.pid = 12;
values.GetStringValue(property, out name);
//この辺から追加↓矢印
if (name == "") //取れなかったらファイルかも?
{
property = new _tagpropertykey();
property.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC,
0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);
//property.pid = 4;
property.pid = 12; //WPD_OBJECT_ORIGINAL_FILE_NAME
values.GetStringValue(property, out name);
}
//この辺から追加↑矢印
// Get the type of the object
Guid contentType;
property = new _tagpropertykey();
property.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC,
0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);
property.pid = 7; //WPD_OBJECT_CONTENT_TYPE
values.GetGuidValue(property, out contentType);
var folderType = new Guid(0x27E2E392, 0xA111, 0x48E0, 0xAB, 0x0C,
0xE1, 0x77, 0x05, 0xA0, 0x5F, 0x85);
var functionalType = new Guid(0x99ED0160, 0x17FF, 0x4C44, 0x9D, 0x98,
0x1D, 0x7A, 0x6F, 0x94, 0x19, 0x21);
if (contentType == folderType || contentType == functionalType)
{
return new PortableDeviceFolder(objectId, name);
}
return new PortableDeviceFile(objectId, name);
}
ファイル名は,WPD_OBJECT_NAME-PIDで返してくれる機械(@キャノンのデジカメ)やら,WPD_OBJECT_ORIGINAL_FILE_NAME-PIDで返してくれる機械(@客から借りてる謎機械)やら,
実装がメーカーによって適当やっちゃ(爆
これで何とかなりそう.
最悪,借りてきている機械をファームレベルでハッキングしようかとも考えておったが(GRB爆
このサンプル,エラートラップやら甘々なんで,明日以降暇々で
再実装しちゃおう.上のコードも,下手すっと落ちるわ(笑
うへっ!22時じゃん
これで,ゆっくり寢れそうじゃ(;´Д`)ハァハァ


お~つか~れ~さ~ん
んでもっておやすみ~
>>mokemoke@週末はお出かけ予定♪ さま
爆睡したけど,夢の中でもソースを追っかけておった(笑
起きてまた,このソースを弄っておりまする(爆