Windows7では、エクスプローラ上でUSBメモリのドライブを
右クリックすると「取り外し」というメニューが現れて、
これをクリックすると取り外せる状態になりますが、
(参考:http://pasofaq.jp/windows/mycomputer/removeusb.htm)
これと同じ事をDelphiでできないでしょうか?
例えば、
何かの関数('G');
とかすると、Gドライブが外れる、というものが理想ですが・・。
コレでしょうか?
[How can i remove a USB flash disk programmatically using delphi? (stack overflow)]
http://stackoverflow.com/questions/434688/how-can-i-remove-a-usb-flash-disk-programmatically-using-delphi
以前同じ事で悩んだので質問してます。
https://www.petitmonte.com/bbs/answers?question_id=6974
DEKO様、ありがとうございます。
リンク先にあったコードは一部分のようで、動作しそうも無く、
さらにあったリンク先はCのコードでして・・・
take様、ありがとうございます。
リンク先(http://okapony.hp.infoseek.co.jp/download/delphi/tips3.html)は切れていました;;
色々リンクが切れているようですが
このライブラリには含まれているようです。
http://www42.tok2.com/home/okapony/download/delphi/SetupApiSample.lzh
こんにちは.
>リンク先にあったコードは一部分のようで、動作しそうも無く、
試してないというこですね.かわりにやってみました.
ただし,以下の修正をしました.
(1) #134を削除しました.
RootName := ADrive + ':' + #134; --> RootName := ADrive + ':';
(2) 最後のところに end; を追加しました.
finally
// Close the volume so other processes can use the dr
end; //追加
end; //追加
ボタンクリックを次のようにしました.
procedure TForm1.Button2Click(Sender: TObject);
begin
EjectVolume('E');
end;
動作確認は,Windows 7 U64 + Dlephi XE です.
「もったいないオバケ」が出てきそうですね.
>リンク先(http://okapony.hp.infoseek.co.jp/download/delphi/tips3.html)は切れてい
ました;;
これ,「おかぽん」さんのサイトです.
昨年だか,URL変わりました.
http://www42.tok2.com/home/okapony/
で,ダウンロードのリンクのリダイレクトが (CGI)が修正されていないようです.
すでにtake さんのレスがありますが,以下から
DeviceReStart.lzh あるいは,SetupApiSample.lzh をダウンロードすると含まれています.
http://www42.tok2.com/home/okapony/download/delphi/
DEKOさんのリンク先で、'improve this answer'をクリックすると全文を見ることができます、念のため。
で、最後の部分は次のようになってます(原文のまま)。
// Close the volume so other processes can use the drive
CloseHandle(VolumeHandle);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
EjectVolume('E');
end;
[1]: http://support.microsoft.com/default.aspx?scid=kb;en-us;165721
[2]: http://stackoverflow.com/questions/85649/safe-remove-usb-drive-using-win32-api#321097
[3]: http://stackoverflow.com/users/12458/concept03
Novさんどうも.
CloseHandle(VolumeHandle);
がないとマズイですね.失礼しました.
全く関係ないのですが,
>'improve this answer'をクリックすると全文を見ることができます、念のため。
見逃しました.でも,なんでこういうもったいぶったページ構成なんでしょうね?
コードが長い場合も想定してということもあるのでしょうけど.
ややこしいです.
コードをスクロール表示するインラインも好きじゃないですが.
今はこういうのが多いですね.時代の流れについて行かれません.
これも質問とは関係ないですが、
>でも,なんでこういうもったいぶったページ構成なんでしょうね?
一見様お断り的なサイトなのでしょうか。
'improve this answer'をクリックして中身が見えてしまうのは、サイト管理人の意図する使い方ではないかも知れません...もしくは、回答者については来るものは拒まず、とか...
take様、ありがとうございます。
http://www42.tok2.com/home/okapony/download/delphi/SetupApiSample.lzh
で試してみますと、OSの機能での取り外しと全く同じにできました。^^
ただ、XPでは動作したのですが、Win7では一覧にUSBのドライブが表示されず、
取り外し以前に選択もできませんでした;;
Mr.XRAY様、Nov様、ありがとうございます。
DEKOさんのリンク先のを試してみますと、XPもWin7もドライブのアクセスは
できなくなるのですが、エクスプローラ上にはドライブの表示が残ったままに
なってしまいます・・・この段階でUSBメモリを外せば自動的に表示は消えるのですが、
これが正しい姿とは思えず・・。
>ただ、XPでは動作したのですが、Win7では一覧にUSBのドライブが表示されず
USBメモリの判定処理を工夫すればある程度対応出来ますよ。
下記コードでWindows7の環境でも動作してます。
ただしカードリーダーをUSBメモリと誤認識してしまい。
さらにそれを取り外そうとすると無限ループしました。
function TUSBEject.EjectUSB: Boolean;
var
d : TDeviceNode;
snn : string;
i,j : Integer;
begin
result := False;
FUsbDevices.GetDeviceInfo(nil); // リムーバブルかつUSBの名称を含む機器情報を取得
for j := 0 to FUsbDevices.Count-1 do begin // USBデバイスの数だけループ
d := FUsbDevices.Items[j]; // j番目のUSBデバイスクラス参照
for i := 0 to d.DeviceNodeCount-1 do begin // USBデバイスに関連するノード分ループ
snn := d.DeviceNodeName[i]; // USBのデバイス名称を取得
if not d.Removable then continue; // 取り外せないデバイスは無視
if not d.DisableEnable then continue; // 無効に出来ないデバイスは無視
if not CheckUsbMemory(snn) then continue; // USBメモリではない場合無視
result := d.EjectDevice(); // USBデバイスを取り外す
exit;
end;
end;
end;
ソースが少し不足してた
D-Zまでのドライブ名の情報のいずれかと一致するなら
USBのドライブとして判定
function TUSBEject.CheckUsbMemory(const str: string): Boolean;
var
i : Integer;
s : string;
begin
result := False;
for i := Ord('D') to Ord('Z') do begin
s := FUsbDevices.DriveToDeviceName(Char(i));
if str = s then begin
result := True;
exit;
end;
end;
end;
take様、何度もありがとうございます。
やはりWin7では動作しませんでした。
64bitOSなのですが、その辺りも何かあるのかもと思ったりしてます・・・
ただ、DEKOさんのリンク先のコードで試していると、Win7でも動作しました。
再起動とかしたのが良かったのかもと^^;
ただ、エクスプローラからドライブは消えるのですが、
タスクトレイで普通表示される「〜安全に取り外すことができます。」という
メッセージは表示されず、不安は残ります^^;
とりあえずこれでなんとか運用してみようと思います。
皆様、ありがとうございました。
解決済みということですが、http://www42.tok2.com/home/okapony/
ここの中の人なので、登場してみました(が、ステハンw)。
なお、64bit環境は保持していないので、動作確認はできません。
> del弟子 2012/05/22(火) 11:31:34 <初心者> 書込者ID:[ #!( ]
> ただ、XPでは動作したのですが、Win7では一覧にUSBのドライブが表示されず、
SetupApiSample.lzhのサンプルで、「USBデバイス取得クラスのテスト」ボタンにより
ドライブが表示されないということだと思うので、Win7x64では、デバイスのクラス名が
違うのかもしれません。
サンプルでは固定値('USB' or 'CDROM' or 'Volume')にしているので、大文字小文字の違いでも
表示されなくなりますね。
サンプルのフォームで、TForm1.OnSelectDevice で 引数の aCanSelect を
無条件 True にすると、全てのデバイスが列挙されるようになります。
ここで左側のツリーに表示されるようになったのであれば、デバイスのクラス名が
Win7x64で、変更になっているからだと思われます。
'USB2.0'とかになっているのかもしれません。
解説ページを作るモチベーションもないので、あくまでサンプルということでご理解お願いします。
> DEKO 2012/05/21(月) 14:35:28 書込者ID:[ "!$#" ]
> http://stackoverflow.com/questions/434688/how-can-i-remove-a-usb-flash-disk-programmatically-using-delphi
ここのコードを見てみましたが、これはCD/DVDトレイの開閉でよく見たソースです。
これでUSBデバイスのとりはずしが可能なのは初めて知りました。
エクスプローラーの表示が変わらないのが、リフレッシュ(F5)で改善されるのであれば
「WM_COMMAND 41504」(または$A220)で検索すれば、見つかります。
# 最後になりますが、cgiのリンク切れすいません(こんなとこで謝る)。
# 移転してcgiのパーミッションとかの設定も変わったり、なにかとめんどくさ・・・
# いえ、cgiを使わないように、気がついたところから修正しました。
# 直リンOKです。好きにしてください。
> エクスプローラーの表示が変わらないのが、リフレッシュ(F5)で改善されるのであれば
> 「WM_COMMAND 41504」(または$A220)で検索すれば、見つかります。
Explorer に SHChangeNotify() で更新通知してやればイケるかもです。
SHChangeNotify(SHCNE_MEDIAREMOVED, SHCNF_FLUSH, nil, nil);
or
SHChangeNotify(SHCNE_MEDIAREMOVED, SHCNF_FLUSHNOWAIT, nil, nil);
ツイート | ![]() |