2009-05-27 14 views
0

********プラットフォームからアンマネージdll(Shell32.dll、関数:SHEmptyRecycleBin)を呼び出すプラットフォーム:Vista(最終版または自宅/プレミアム)では動作しません。他のOS(xp、windows7)は動作します。***********Vista(.net)のみの問題:スレッドから

スレッド内でC++ .net(またはc#.net)を使用してごみ箱を空にしています。私はこれをまっすぐに(スレッドなしで)行うと動作します。しかし、スレッドが使用されていない場合はそれがありません。以下のコードスニペットをご覧ください:

namespace EmptyRecycleBin_C{ 
enum RecycleFlags 
{ 
    SHERB_NOCONFIRMATION = 0x00000001, 
    SHERB_NOPROGRESSUI = 0x00000002, 
    SHERB_NOSOUND = 0x00000004 
}; 
public ref class Form1 : public System::Windows::Forms::Form{ 

[DllImport("Shell32.dll",CharSet=CharSet::Unicode)] 
static System::UInt32 SHEmptyRecycleBin(IntPtr hwnd, String^ pszRootPath, RecycleFlags dwFlags); 

private: void button1_Click(System::Object^ sender, System::EventArgs^ e) 
{ 
    Thread^ th = gcnew System::Threading::Thread(gcnew ThreadStart(this, &Form1::doEmpty)); 
    th->Start(); 
    //this->doEmpty(); // this line works just fine 
} 

private: void doEmpty() 
{ 
    try{ 
     SHEmptyRecycleBin(IntPtr::Zero, String::Empty, RecycleFlags::SHERB_NOCONFIRMATION); 
    }catch(Exception^ ex) 
    {Diagnostics::Debug::Write(ex->Message);} 
} 
}; 
} 

whats the problem here ...?

+0

どのように動作しないのかについての詳細を分かち合うことができますか(例外の詳細など)? –

+0

例外をスローしませんが、負の値を返します。成功した場合(スレッドなしで呼び出された場合)、0が返されます。SHEmptyRecycleBinを呼び出した後、[DllImport( "kernel32.dll"、SetLastError = true、...)を設定すると、System.Console.WriteLine(Marshal。ごみ箱は空になっていませんが、「操作は正常に完了しました」というGetLastWin32Error())。 – Samir

+0

エラーコードが返されますか?負の値ですか?番号は何ですか?さらに良いことに、負の数が実際には符号なしの32ビット値であると仮定し、それを16進数に変換します。その後、Googleの16進エラーコード(例:80004005)の –

答えて

0

なぜそれが起こっているのか分かりませんが、他のスレッド方法を試しましたか? BackgroundWorkerコンポーネントやThreadPool.QueueUserWorkItemなどがありますか?エラーはまだ発生しますか?

+0

をBackgroundWorkerで試しましたが、同じ結果になりました。 – Samir

1

作成したスレッドは、メインスレッドのセキュリティコンテキストではなく、デフォルトのセキュリティコンテキストで実行される可能性がありますか?

ヒントについてはthe doc on ExecutionContextを参照してください。あなたのスレッドでExecutionContextを設定し、再試行することができます。

+1

私はそれが許可の問題だと思う。 VistaのUACは途方もない可能性があります。 Windows 7では、特定のタスクの自動高度化が行われるため、Vistaではなく7で動作する理由を説明することができます。 –

+0

Chesso、リンクはFileDialogPermissionを扱います。この場合、どのような権限が必要です(上記のコード)。これを行う方法をコードスニペットで伝えることができれば、本当に役に立ちます。 – Samir

1

スレッドからCoInitializeを呼び出しましたか?

どのようなエラーコードが返されますか?

1

シェル関数はSTAスレッドのみで動作し、.NETスレッドは既定でMTAです。

th->SetApartmentState(ApartmentState::STA); 
th->Start();