Проблема только в Vista (.net): вызов неуправляемой библиотеки DLL (Shell32.dll, функция: SHEmptyRecycleBin) из потока - PullRequest
0 голосов
/ 27 мая 2009

******** Платформа: в Vista (Ultimate или Home / Premium) не работает, в других ОС (xp, windows7) она работает ***********

Я очищаю корзину, используя 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);}
}
};
}

в чем здесь проблема ...?

Ответы [ 4 ]

1 голос
/ 23 января 2010

Функции оболочки работают только с потоками STA, а потоки .NET по умолчанию являются MTA. Вы можете настроить поток для использования потоков с одной квартирой:

th->SetApartmentState(ApartmentState::STA);
th->Start();
1 голос
/ 28 мая 2009

Может быть потому, что создаваемые вами потоки выполняются в контексте безопасности по умолчанию, а не в контексте безопасности основного потока?

См. документ по ExecutionContext для подсказки. Вы можете установить ExecutionContext в своем потоке и повторить попытку.

1 голос
/ 23 января 2010

Вы вызвали CoInitialize из вашей темы?

Какой код ошибки он возвращает?

0 голосов
/ 27 мая 2009

Я не знаю, ПОЧЕМУ это происходит, но вы пробовали другие методы потоков? Например, компонент BackgroundWorker или ThreadPool.QueueUserWorkItem? Ошибка по-прежнему происходит?

...