2009-05-27 78 views
0

********平臺:在Vista中(最終或家庭/高級版)它不起作用,其他操作系統(XP,Windows7)的工作***********問題只在Vista(.net):調用非託管dll(Shell32.dll,函數:SHEmptyRecycleBin)線程

我正在清空使用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);} 
} 
}; 
} 

這裏的問題是什麼......?

+0

您能分享一些關於它如何不起作用的細節(例外細節和類似情況)嗎? – 2009-05-27 06:41:07

+0

它不會拋出任何異常,但會返回負值。成功時(調用時沒有任何線程)返回0.在調用SHEmptyRecycleBin試圖用System.Console.WriteLine(Marshal。)捕獲錯誤結果後,設置[DllImport(「kernel32.dll」,SetLastError = true,...)]。 GetLastWin32Error()),雖然回收站未清空,但顯示「操作已成功完成」。 – Samir 2009-05-27 07:36:29

+0

它返回一個錯誤代碼?負值?數字是多少?更好的是:假設負數實際上是一個無符號的32位值,然後將其轉換爲十六進制。然後谷歌的十六進制錯誤代碼(例如80004005) – 2010-01-22 23:13:19

回答

0

我不知道爲什麼會發生這種情況,但是您是否嘗試了其他線程方法?如BackgroundWorker組件或ThreadPool.QueueUserWorkItem?錯誤是否仍然發生?

1

難道是因爲您創建的線程在默認安全上下文中執行,而不是在主線程的安全上下文中執行?

查看the doc on ExecutionContext的提示。您可以在您的線程上設置ExecutionContext並重試。

1

你有從線程中調用CoInitialize嗎?

它返回什麼錯誤代碼?

1

Shell函數僅適用於STA線程,而.NET線程默認情況下是MTA。您可以將線程設置爲使用單套線程:

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