仅在Vista(.net)中出现问题:从线程调用非托管dll(Shell32.dll,函数:SHEmptyRecycleBin)

时间:2022-09-29 16:56:19

********Platform: in Vista(ultimate or home/premium) it does not work, other OS(xp, windows7) it works***********

********平台:在Vista(终极或家庭/高级)它不起作用,其他操作系统(xp,windows7)它的工作原理***********

I'm emptying recycle bin using c++.net(or c#.net) inside a thread. When i do this straight (without thread) it works. But if thread used it doesn't. Please watch the code snippet below:

我在一个线程内使用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...?

这是什么问题......?

4 个解决方案

#1


Could it be because threads you create execute in the default security context, not in the security context of the main thread?

可能是因为您创建的线程在默认安全上下文中执行,而不是在主线程的安全上下文中执行?

See the doc on ExecutionContext for a hint. You can set the ExecutionContext on your thread and re-try.

有关提示,请参阅ExecutionContext上的doc。您可以在线程上设置ExecutionContext并重试。

#2


Have you called CoInitialize from your thread?

你有没有从你的线程中调用CoInitialize?

What error code is it returning?

它返回什么错误代码?

#3


Shell functions work with STA threads only, and .NET threads are MTA by default. You can set the thread to use single-apartment threading:

Shell函数仅适用于STA线程,默认情况下.NET线程是MTA。您可以将线程设置为使用单层线程:

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

#4


I don't know WHY that's happening, but have you tried other threading methods? Such as a BackgroundWorker component or ThreadPool.QueueUserWorkItem? Does the error still happen?

我不知道为什么会发生这种情况,但您是否尝试过其他线程方法?比如BackgroundWorker组件或ThreadPool.QueueUserWorkItem?错误是否仍然发生?

#1


Could it be because threads you create execute in the default security context, not in the security context of the main thread?

可能是因为您创建的线程在默认安全上下文中执行,而不是在主线程的安全上下文中执行?

See the doc on ExecutionContext for a hint. You can set the ExecutionContext on your thread and re-try.

有关提示,请参阅ExecutionContext上的doc。您可以在线程上设置ExecutionContext并重试。

#2


Have you called CoInitialize from your thread?

你有没有从你的线程中调用CoInitialize?

What error code is it returning?

它返回什么错误代码?

#3


Shell functions work with STA threads only, and .NET threads are MTA by default. You can set the thread to use single-apartment threading:

Shell函数仅适用于STA线程,默认情况下.NET线程是MTA。您可以将线程设置为使用单层线程:

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

#4


I don't know WHY that's happening, but have you tried other threading methods? Such as a BackgroundWorker component or ThreadPool.QueueUserWorkItem? Does the error still happen?

我不知道为什么会发生这种情况,但您是否尝试过其他线程方法?比如BackgroundWorker组件或ThreadPool.QueueUserWorkItem?错误是否仍然发生?