2009-05-27 6 views
0

******** Plate-forme: dans Vista (ultime ou maison/premium), il ne fonctionne pas, autre système d'exploitation (xp, windows7) cela fonctionne ***********Problème uniquement sous Vista (.net): appel dll non géré (Shell32.dll, fonction: SHEmptyRecycleBin) à partir du fil

Je vide la corbeille en utilisant C++ .net (ou C# .net) dans un thread. Quand je fais cela directement (sans fil) cela fonctionne. Mais si le fil utilisé ne le fait pas. S'il vous plaît regarder l'extrait de code ci-dessous:

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);} 
} 
}; 
} 

quel est le problème ici ...?

+0

Pouvez-vous partager quelques détails sur comment cela ne fonctionne pas (détails de l'exception et similaires)? –

+0

il ne jette aucune exception, mais renvoie une valeur négative. En cas de succès (lorsqu'il est appelé sans thread) renvoie 0. Définissez également [DllImport ("kernel32.dll", SetLastError = true, ...)] après avoir appelé SHEmptyRecycleBin essayé d'attraper le résultat de l'erreur avec System.Console.WriteLine (Marshal. GetLastWin32Error()) qui indique "opération terminée avec succès" bien que la corbeille n'ait pas été vidée. – Samir

+0

Retourne un code d'erreur? Une valeur négative? Quel est le nombre? Mieux encore: supposons que le nombre négatif est en réalité une valeur 32 bits non signée, puis la convertit en hexadécimal. Ensuite, google pour le code d'erreur hexadécimal (par exemple 80004005) –

Répondre

0

Je ne sais pas POURQUOI cela se passe-t-il, mais avez-vous essayé d'autres méthodes de thread? Comme un composant BackgroundWorker ou ThreadPool.QueueUserWorkItem? L'erreur persiste-t-elle?

+0

essayé avec BackgroundWorker, mais le même résultat. – Samir

1

Est-ce parce que les threads que vous créez s'exécutent dans le contexte de sécurité par défaut, et non dans le contexte de sécurité du thread principal?

Voir the doc on ExecutionContext pour un indice. Vous pouvez définir ExecutionContext sur votre thread et réessayer.

+1

Je parie que c'est un problème d'autorisations. Vista UAC pourrait être dans le chemin. Windows 7 fait auto-élévation pour certaines tâches, ce qui pourrait expliquer pourquoi cela fonctionne sur 7 et non sur Vista. –

+0

Chesso, le lien traite avec FileDialogPermission. Quelle permission est nécessaire pour ce cas (le code ci-dessus). Si vous pouvez donner un extrait de code, comment cela va-t-il être utile? – Samir

1

Avez-vous appelé CoInitialize de votre thread?

Quel code d'erreur renvoie-t-il?

1

Les fonctions Shell fonctionnent uniquement avec les threads STA et les threads .NET sont MTA par défaut. Vous pouvez définir le thread pour utiliser le threading single-apartment:

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