Créer des évenements [Résolu]

Signaler
Messages postés
403
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008
-
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
-
Bonjour,

je cherche à déclancher certaines actions lorsque je manipule des fichiers dans un dossier (celà peut être toutes sorte de manipulations : suppression,ajout, modification ou simple séléction d'un fichier). Est-il facile de créer des évenements tels que ceux ci ? Si oui, comment faire ?

merci d'avance pour votre aide.

Mathmax
A voir également:

30 réponses

Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Vu que les évènements ne marche pas chez toi, on va utiliser une timer.

( C'est un programme WinForm et comme l'autre il faut les deux libs et les deux namespaces. )

public partial class Form1 : Form
{
    private InternetExplorer ie = null;
    private TextBox tb = null;
    private Timer t = null;


    public Form1( )
    {
        InitializeComponent( );


        tb = new TextBox( );
        tb.Multiline = true;
        tb.ReadOnly = true;
        tb.BackColor = Color.Black;
        tb.ForeColor = Color.White;
        tb.Dock = DockStyle.Fill;
        tb.ScrollBars = ScrollBars.Both;


        this.Size = new Size( 640, 480 );
        this.Controls.Add( tb );


        string url = "C:\";
        object o = null;


        ie = new InternetExplorer( );
        ie.Visible = true;
        ie.Navigate( url, ref o, ref o, ref o, ref o );


        t = new Timer( );
        t.Interval += 250;
        t.Tick += new EventHandler( Timer_Tick );
        t.Start( );
    }


    private void Timer_Tick( object sender, EventArgs e )
    {
        try
        {
            if ( ie.ReadyState == tagREADYSTATE.READYSTATE_COMPLETE )
            {
                tb.Clear( );


                ShellFolderView view = ( ShellFolderView )ie.Document;


                if ( view.FocusedItem != null )
                    tb.AppendText( "[ FOCUSED ] " + view.FocusedItem.Name );


                foreach ( FolderItem item in view.SelectedItems( ) )
                    tb.AppendText( "\r\n[ SELECTED ] " + item.Name );
            }
        }
        catch ( COMException ex )
        {            if ( ( uint )ex.ErrorCode 0x80010108 || ( uint )ex.ErrorCode 0x800706BA ) // RPC_E_*
            {
                // Cette exception est bien utile, elle permet de détecter
                // la fermeture de l'explorateur sans gérer les évènements.
                tb.AppendText( "\r\n[ END ] " + "Internet Explorer est fermé." );
                // On arrête et dispose le timer.
                t.Stop( );
                t.Dispose( );
                t = null;
            }
            else
            {
                // Ca arrive si on va trop vite, c'est pas grave,
                // suffit de catcher l'exception et de continuer.
                tb.AppendText( "\r\n[ ERROR ] " + ex.Message );
                // Pour avoir le temps de lire l'erreur.
                // Juste pour le débogage.
                System.Threading.Thread.Sleep( 2000 );
            }
        }
    }
}

Si ça ne marche toujours pas, faut oublier l'idée d'utiliser les composants COM du Shell.
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
C'est un événement, il est exécuté après l'appelle à Navigate même si il est defini avant dans le code.
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Salut, ces évènements existent déja via la classe FileSystemWatcher.
Messages postés
403
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Oui merci, mais en fait ce qui m'interesse le plus, c'est déclancher des actions lorsqu'un fichier est séléctionné. Cet évenement n'existe pas dans la classe FileSystemWatcher. Est-il possible de créer un tel évenement ?

Mathmax
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Oui c'est possible mais c'est pas simple..

Tu veux surveiller le changement de fichier selectionné dans une fenêtre de l'explorateur que tu ouvres toi même ou dans toutes les fenêtres si il y en a plusieurs d'ouvertes ?
Messages postés
403
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Je veux surveiller le changement de fichier selectionné dans une fenêtre de l'explorateur que le programme ouvre au préalable (toujours la même fenêtre).

Mathmax
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Comme j'utilise le Shell il faut ajouter 2 composants COM à ton projet, "Microsoft Shell Control and Automation" ( shell32.dll ) et "Microsoft Internet Controls" ( shdocvw.dll ), et les deux espace de noms correspondant "Shell32" et "SHDocVw". ( c'est un programme en mode console ).


 


private static void Main( string[ ] args )
{
    string url =  "C:\";
    object o = null;


    InternetExplorer ie = new InternetExplorer( );
    ie.DocumentComplete += delegate
    {
        try
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine( url );


            ShellFolderView doc = ( ShellFolderView )ie.Document;
            doc.SelectionChanged += delegate
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine( doc.FocusedItem.Name );
            };


            ShellFolderViewOC oc = new ShellFolderViewOC( );
            oc.SetFolderView( doc ); // Redirige les events O_o
        }
        catch
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine( "Error" );
        }
    };


    ie.Visible = true;
    ie.Navigate( url, ref o, ref o, ref o, ref o );


    Console.ReadLine( );
}
Messages postés
403
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Je n'obtiens aucune erreur à la compilation de ton programme. En revanche j'en obtiens une à l'execution du programme. A la ligne "ie.DocumentComplete += delegate", j'obtiens le message "Exception has been thrown by the target of an invocation."

Mathmax
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
J'ai pas ça.. Si c'est une TargetInvocationException ce serait bien que tu donne l'exception contenue dans la propriété InnerException de cette dernière..
Messages postés
403
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Désolé, je ne vois pas comment obtenir ce qu'il y a dans la porpriété InnerExeption. Je clique sur :
"Check the InnerExeption property for more information", mais je n'obtiens pas d'informations.

J'ai fait un zip du projet. Peut-être, peux-tu tester chez toi si tu obtiens aussi cette erreur ? Tu peux le télécharger à cette adresse :
http://www.orkos.com/tests/ConsoleApplication1.zip

Mathmax
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Je viens tester ton projet il marche parfaitement chez moi.. Je vois pas trop.. Je suis sous XP SP2. Peut être tu utilises la version bêta de IE 7 !?
Messages postés
403
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Je suis également sous XP SP2. Habituellement j'utilise Firefox, mais le problème persiste même si j'utilise IE 6 comme navigateur par défaut. Je te fais une copie-écran du message d'erreur qui m'est retourné pas Visual Studio.Tu peux la voir ici :
http://www.orkos.com/tests/erreur.jpg
Peut-être peut-on modifier légèrement la fonctionnalité du programme pour éviter cette erreur ?

merci pour ton aide

Mathmax
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
La capture ne m'aide pas trop.. faudrait vraiment avoir l'InnerException pour comprendre, rajoute le code suivant au tout début de Main et fais un copier/coller du message d'erreur stp.

Je vais voir si on peut se passer de l'évènement DocumentComplete, mai il risque d'avoir d'autres erreurs.

As tu essayé avec un autre répertoire que inetpub, il est peut être protégé par IIS.

AppDomain appDomain = AppDomain.CurrentDomain;
appDomain.UnhandledException +=  delegate ( object sender, UnhandledExceptionEventArgs e )
{
    string msg = e.ExceptionObject.ToString( );
    string inner = ( ( Exception )e.ExceptionObject ).ToString( );
    Console.WriteLine( msg + "\n\n" + inner );
};
Messages postés
403
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Voici le message d'erreur obtenu :

<hr size="2" width="100%" />System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidCastException: Unable to cast COM object of type 'SHDocVw.InternetExplorerClass' to interface type 'System.Runtime.InteropServices.ComTypes.IConnectionPointContainer'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{B196B284-BAB4-101A-B69C-00AA00341D07}' failed due to the following error: Cette interface n'est pas prise en charge (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
   at SHDocVw.DWebBrowserEvents2_EventProvider..ctor(Object )
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle._InvokeConstructor(Object[] args, SignatureStruct& signature, IntPtr declaringType)
   at System.RuntimeMethodHandle.InvokeConstructor(Object[] args, SignatureStruct signature, RuntimeTypeHandle declaringType)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
   at System.__ComObject.CreateEventProvider(Type t)
   at System.__ComObject.GetEventProvider(Type t)
   at SHDocVw.InternetExplorerClass.add_DocumentComplete(DWebBrowserEvents2_DocumentCompleteEventHandler )
   at ConsoleApplication1.Program.Main(String[] args) in D:\Mes documents\Visual Studio 2005\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 25
   at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidCastException: Unable to cast COM object of type 'SHDocVw.InternetExplorerClass' to interface type 'System.Runtime.InteropServices.ComTypes.IConnectionPointContainer'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{B196B284-BAB4-101A-B69C-00AA00341D07}' failed due to the following error: Cette interface n'est pas prise en charge (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
   at SHDocVw.DWebBrowserEvents2_EventProvider..ctor(Object )
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle._InvokeConstructor(Object[] args, SignatureStruct& signature, IntPtr declaringType)
   at System.RuntimeMethodHandle.InvokeConstructor(Object[] args, SignatureStruct signature, RuntimeTypeHandle declaringType)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
   at System.__ComObject.CreateEventProvider(Type t)
   at System.__ComObject.GetEventProvider(Type t)
   at SHDocVw.InternetExplorerClass.add_DocumentComplete(DWebBrowserEvents2_DocumentCompleteEventHandler )
   at ConsoleApplication1.Program.Main(String[] args) in D:\Mes documents\Visual Studio 2005\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 25
   at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
<hr size="2" width="100%" />
J'ai aussi essayé le répértoire C: mais voyant que ça ne marchait pas j'ai essayé avec inetpub. Je n'ai pas obtenu de meilleurs résultats avec ce dossier.

Si c'est l'insatance de InternetExplorer qui pose problème, peut être peut-on essayé avec une commande du style :  "System.Diagnostics.Process.Start(MyFolder.FullName);" ?

Mathmax
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Avec une instance de Process je vois pas comment faire pour le moment..

Ce qui est bizarre c'est que ce code semble léver un exception chez toi  ??

private static void Main( string[ ] args )
{
    Console.WriteLine( Environment.Version ); // 2.0.50.727.42 et toi ??
   
    InternetExplorer ie = new InternetExplorer( );
    // using System.Runtime.InteropServices.ComTypes;
    IConnectionPointContainer cpc = ( IConnectionPointContainer )ie;


    Console.WriteLine( "OK" );
    Console.ReadLine( );
}
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Modérateur
Dernière intervention
30 octobre 2008
49
J'apport peut etre rien au sujet, mais c'est juste pour dire que ca marche parfaitement chez moi aussi (meme version que toi Lutinore)
Mx
MVP C# 
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Si si justement, merci beaucoup Mx, tu as testé juste le dernier exemple ou tout le programme pour detecter le changement de séléction ?
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Modérateur
Dernière intervention
30 octobre 2008
49
Les 2 tournent sans erreur :)

Mx
MVP C# 
Messages postés
403
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Chez moi ton bout de code fonctionne, Environment.Version retourne 2.0.50727.42 mais la classe IConnectionPointContainer n'est pas reconnue. Je l'ai mise en commentaire pour compiler le programme.
Par contre le programme pour detecter le changement de séléction ne marche toujours pas.

Finalement, as-tu vu si l'on peut se passer de l'évènement DocumentComplete ?
Mathmax
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Si tu commentes l'interface IConnectionPointContainer ça n'a plus de sens, j'ai justement fait ce code pour voir si tu avais une exception avec cette interface.

Si tu as un bien rajouté le namespace et que tu peux pas compiler, c'est incompréhensible.

IConnectionPointContainer est une interface du framework 2.0 contenue dans l''espace de nom System.Runtime.InteropServices.ComTypes dans mscorlib.dll, ( il n y a donc pas de référence à rajouter ). C'est comme si tu me disais que tu n'as pas la classe Console ou Form !!?