「特別な」フォルダ、特にごみ箱のローカライズされた名前を見つけるための「正しい」Windows APIを見つけようとしています。ファイルをごみ箱に送るか、ファイルを直接削除するかを尋ねる、適切にローカライズされたダイアログ ボックスをユーザーに表示できるようにしたいと考えています。
実際の削除方法については、インターネット (および Stackoverflow) でたくさん見つけましたが、それは十分に簡単に思えます。テキストをローカライズできるようにしたいだけです。
「特別な」フォルダ、特にごみ箱のローカライズされた名前を見つけるための「正しい」Windows APIを見つけようとしています。ファイルをごみ箱に送るか、ファイルを直接削除するかを尋ねる、適切にローカライズされたダイアログ ボックスをユーザーに表示できるようにしたいと考えています。
実際の削除方法については、インターネット (および Stackoverflow) でたくさん見つけましたが、それは十分に簡単に思えます。テキストをローカライズできるようにしたいだけです。
コード サンプルと使用方法については、次の記事を参照してください。
http://www.codeproject.com/KB/winsdk/SpecialFolders.aspx
また、MSDN には、API 呼び出しで特別なフォルダーの場所を特定するのに役立つ記事があります。
実際、CodeProjectの記事はそれほど役に立たなかったので、ごみ箱のローカライズされた名前を取得するために使用した実際のコードでこの質問に答えると思いました。
このサンプルは、リソースの解放に関しても正しく動作しようとします。特に私のリソース管理でエラーを見つけた場合は、コメントを歓迎します。
public static string GetLocalizedRecycleBinName()
{
IntPtr relative_pidl, parent_ptr, absolute_pidl;
PInvoke.SHGetFolderLocation(IntPtr.Zero, PInvoke.CSIDL.BitBucket,
IntPtr.Zero, 0, out absolute_pidl);
try
{
PInvoke.SHBindToParent(absolute_pidl,
ref PInvoke.Guids.IID_IShellFolder,
out parent_ptr, out relative_pidl);
PInvoke.IShellFolder shell_folder =
Marshal.GetObjectForIUnknown(parent_ptr)
as PInvoke.IShellFolder;
// Release() for this object is called at finalization
if (shell_folder == null)
return Strings.RecycleBin;
PInvoke.STRRET strret = new PInvoke.STRRET();
StringBuilder sb = new StringBuilder(260);
shell_folder.GetDisplayNameOf(relative_pidl, PInvoke.SHGNO.Normal,
out strret);
PInvoke.StrRetToBuf(ref strret, relative_pidl, sb, 260);
string name = sb.ToString();
return String.IsNullOrEmpty(name) ? Strings.RecycleBin : name;
}
finally { PInvoke.ILFree(absolute_pidl); }
}
static class PInvoke
{
[DllImport("shell32.dll")]
public static extern int SHGetFolderLocation(IntPtr hwndOwner,
CSIDL nFolder, IntPtr hToken, uint dwReserved, out IntPtr ppidl);
[DllImport("shell32.dll")]
public static extern int SHBindToParent(IntPtr lpifq, [In] ref Guid riid,
out IntPtr ppv, out IntPtr pidlLast);
[DllImport("shlwapi.dll")]
public static extern Int32 StrRetToBuf(ref STRRET pstr, IntPtr pidl,
StringBuilder pszBuf, uint cchBuf);
[DllImport("shell32.dll")]
public static extern void ILFree([In] IntPtr pidl);
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214E6-0000-0000-C000-000000000046")]
public interface IShellFolder
{
[PreserveSig]
Int32 CompareIDs(Int32 lParam, IntPtr pidl1, IntPtr pidl2);
void ParseDisplayName(IntPtr hwnd, IntPtr pbc, String pszDisplayName,
UInt32 pchEaten, out IntPtr ppidl, UInt32 pdwAttributes);
void EnumObjects(IntPtr hwnd, int grfFlags,
out IntPtr ppenumIDList);
void BindToObject(IntPtr pidl, IntPtr pbc, [In] ref Guid riid,
out IntPtr ppv);
void BindToStorage(IntPtr pidl, IntPtr pbc, [In] ref Guid riid,
out IntPtr ppv);
void CreateViewObject(IntPtr hwndOwner, [In] ref Guid riid,
out IntPtr ppv);
void GetAttributesOf(UInt32 cidl,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
IntPtr[] apidl, ref uint rgfInOut);
void GetUIObjectOf(IntPtr hwndOwner, UInt32 cidl,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
IntPtr[] apidl, [In] ref Guid riid, UInt32 rgfReserved,
out IntPtr ppv);
void GetDisplayNameOf(IntPtr pidl, SHGNO uFlags, out STRRET pName);
void SetNameOf(IntPtr hwnd, IntPtr pidl, string pszName,
int uFlags, out IntPtr ppidlOut);
}
public enum CSIDL
{
BitBucket = 0x000a,
}
public enum SHGNO
{
Normal = 0x0000, ForParsing = 0x8000,
}
[StructLayout(LayoutKind.Explicit, Size = 520)]
public struct STRRETinternal
{
[FieldOffset(0)] public IntPtr pOleStr;
[FieldOffset(0)] public IntPtr pStr;
[FieldOffset(0)] public uint uOffset;
}
[StructLayout(LayoutKind.Sequential)]
public struct STRRET
{
public uint uType;
public STRRETinternal data;
}
public class Guids
{
public static Guid IID_IShellFolder =
new Guid("{000214E6-0000-0000-C000-000000000046}");
}
}