Windows でもゴミ箱

Linux ばかりに触っていたらマニアックになるので Windows を久々に。

せっかくゴミ箱について興味をもったので Windows でも色々調べてみる。
OS の仕様としてゴミ箱を持つ Windows ではコマンドとかはどうなっているのかな?

コマンドプロンプトでごみ箱へファイルを移動させるにはどうすればよいのでしょうか? -OKWave

XP では c:\recycler 以下のはずだけど…てかドライブ毎ユーザー毎に存在するんだが何時の話?
試しにやってみた、ごみ箱に残らないとか書いているけどつまりこうなっているだけだと思う。

cmd_move

アプリを紹介しているけど VC++ を持っているならの SHFileOperation を使って簡単に作(略
なんにせよ Windows でも Shell API からしかアクセスできないんだ、ふむふむ。

OS 非依存の仮想マシンであるはずの .NET Framework はどうなのかな?

ファイルをゴミ箱へ削除(C#)について – Insider.NET

やはり P/Invoke でアクセスしなさい!にしているようで。
そんな糞面倒なことをするより VC++ でラッピングした dll を作って(略
それにしても「がっかり」って人… .NET Framework が何なのか解っているのかな?

Python は…当然 gio モジュールなんか使えるはずもなく。
これも VC++ でラッピングした dll を作って(もういいよ

Windows Power Shell なら結構簡単に

Windows Script Programming: PowerShellでファイルやフォルダをごみ箱に捨てる。

全然簡単じゃネェ!デフォルトで手段を用意してくれている分マシなだけだ。

うわぁ…つまりシェルてかこの手のことをやろうとすると VC++ が必要になるわ。
ま、こんなことを書いたしせっかくなのでゴミ箱へ送る DLL の作り方を書いておこう。
Visual Studio の入っている Vista の HDD に繋ぎ替えて…メンドクサ。

VisualStudio を起動する、VC++ Exp でも同じはず。
trash という名前の新規 Win32 コンソールプロジェクトを作る。
ウイザードを進めてアプリケーションの種類を「DLL」にして完了。
そして Python から使う場合にはまずやらなきゃいけないこと。

stdcall

と呼び出し規約を __stdcall にする、意味は勝手に調べてね。
達人なら違うと言うだろうけど普通の人ならそれ以外はデフォルトのままでいい。
つまりデフォルトの UNICODE ビルドだが今はそのほうが自然だろう。

追記
忘れていた!Releace 版だけでいいんだが
コード生成のランタイムライブラリを「マルチスレッド」にして。

multi

「マルチスレッド DLL」のままだと VC9 ランタイムも配らなきゃいけなくなる。
7kb が 41kb に増えるけどこれで DLL 単体で配布できるようになる
VC++ が入っている環境だと普通に動くので忘れがちなんですよねココ。
追記おわり

stdafx.h の最後の行に下記を追記

#include <shellapi.h>

コード

#include "stdafx.h"

extern "C" __declspec(dllexport)
BOOL trash(LPCWSTR szFileName)
{
	SHFILEOPSTRUCT sfos;
	ZeroMemory(&sfos, sizeof(SHFILEOPSTRUCT));
	wchar_t szOpFile[1024];
	wcscpy_s(szOpFile, 1024, szFileName);
	szOpFile[wcslen(szOpFile) + 1] = L'?0';
	sfos.hwnd = NULL;
	sfos.wFunc = FO_DELETE;
	sfos.pFrom = szOpFile;
	sfos.fFlags = FOF_SILENT | FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
	if (!SHFileOperation(&sfos))
	{
		return TRUE;
	}
	return FALSE;
}

trash.zip

DllMain を書いて Visual Studio 2008 でビルドしたら警告になった。
分離されているのか、targetver.h といい親切なのか余計なお世話なのか。

細かいことは→の「APIで学ぶWindows徹底理解」に書いています。
ちなみに私が買ったこの本はもう読み直ししすぎてボロボロです。

後はそのままビルドで DLL の完成。
Python.exe があるディレクトリに trash.dll をコピーします。

exp

ここまでくれば python からは毎度のように ctypes を利用して

import ctypes

dll = ctypes.windll.trash
if dll.trash("C:\\Python30\\gomi.txt"):
    print("ok")
else:
    print("miss")

こんな感じであっさりゴミ箱へ捨てられます。
2.* ではファイル名を UNICODE にするのをお忘れなく。
どうしても Python でやらなきゃいけない場合以外は VC++ で作ったほうが(略