Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    6

    [VB.NET] Ottenere / Accedere elenco attività del task manager (No Processi)

    Buona sera a tutti, scrivo poiché sto creando un programma in VB.NET (VS2012) che deve tenere il conto di quanto tempo si lavora su più commesse. Il programma ha 6 tasti per aprire fino a 6 file diversi e, appena ne avvia uno, fa partire il relativo timer. PROBLEMA: la funzione per verificare se un file è aperto, crea problemi con AutoCAD su 2/7 PC (apertura in modalità esclusiva ogni tot tempo catturando le eccezioni), quindi ho supposto di controllare tra i processi attivi. Il problema nasce dal fatto che AutoCAD, come Microsoft Word, mostra il nome nella MainWindowTitle solo del file in primo piano rendendomi impossibile verificare gli altri. Ho notato che nel Task Manager tra i processi c'è solo un acad.exe però in ATTIVITA' compaiono tutti i file .dwg. DOMANDA: è possibile accedere alle attività del task manager per comparare la lista con i file aperti?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Che vuoi dire?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    6
    Ciao, intendevo dire se posso ottenere la lista delle attività elencate nel task manager. Non i processi però. Ho dimenticato un pezzo nel primo post: invece dell'apertura in modalità esclusiva, ho deciso di cercare il processo acad.exe e confrontare il mainwindowtitle con il file aperto, ma qui sorge il problema sopra elencato.
    Grazie

  4. #4
    La lista dei processi del task manager non è nulla di magico - semplicemente, è l'enumerazione delle finestre top-level visibili. Per fare quello che ti interessa dovrebbe essere sufficiente enumerare le finestre in questione (con la API EnumWindows), filtrare quelle visibili (IsWindowVisible), recuperare il process id associato (GetWindowThreadProcessId) e confrontarlo con quello di acad.exe; in questa maniera dovresti ottenere tutte le finestre di Autocad; per recuperarne la caption basta la solita GetWindowText.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    6
    Grazie mille MItaly, ho impiegato un po' di tempo per trovare gli esempi strettamente collegati a VB.NET comunque ho risolto:
    __________________________
    CODICE MODULO "Funzioni.vb"
    ------------------------------------
    codice:
    ''Questo semplice programma trova tutte le finestre aperte sullo schermo 
    ''e ne comunica all'utente titolo e indirizzo di memoria (handle).
    ''
    ''
    ''Il sorgente è stato riadattato per uso di esercizio.
    Imports System.Runtime.InteropServices
    
    Module Funzioni
        Public ArrayListEvent As New List(Of String)
    
        'Le funzioni che risiedono nelle librerie di sistema lavorano
        'a basso livello, come già detto, perciò i tipi
        'più frequentemente incontrati sono IntPtr (puntatore
        'intero) e Int32 (intero a 32 bit). Nonostante ciò, esse
        'possono anche richiedere tipi di dato molto più complessi,
        'come in questo caso. La funzione che useremo necessita di
        'un delegate come parametro.
        Public Delegate Function EnumCallback(ByVal Handle As IntPtr, _
            ByVal lParam As Int32) As Boolean
    
        'La funzione EnumDesktopWindows è definita nella libreria
        'C:WINDOWSsystemsystem32user32.dll. Dato che si tratta di una
        'libreria di sistema, possiamo omettere il percorso e scrivere solo
        'il nome (provvisto di estensione). Come vedete, il nome con cui
        'è dichiarata è lo stesso dl metodo definito
        'in user32.dll. Per importarla correttamente, però, anche
        'i parametri usati devono essere identici, almeno per tipo.
        'Infatti, per identificare univocamente un metodo che potrebbe
        'essere provvisto di overloads, è necessario sapere solo
        'il nome del metodo e la quantità e il tipo di parametri.
        'Anche cambiando il nome a un parametro, la signature non
        'cambia, quindi mi sono preso la libertà di scrivere
        'dei parametri più "amichevoli", poiché la
        'dichiarazione originale - come è tipico del C - 
        'prevede dei nomi assurdi e difficili da ricordare.
        <DllImport("user32.dll")> _
        Public Function EnumDesktopWindows(ByVal DesktopIndex As IntPtr, _
            ByVal Callback As EnumCallback, ByVal lParam As Int32) As Boolean
            'Notare che il corpo non viene definito
        End Function
    
        'Questa funzione ha il compito di ottenere il titolo di
        'una finestra provvisto in input il suo indirizzo (handle).
        'Notare che non restituisce una stringa, ma un Int32. 
        'Infatti, la maggiore parte dei metodi definiti nelle librerie
        'di sistema sono funzioni che restituiscono interi, ma questi
        'interi sono inutili. Anche se sono funzioni, quindi, le si
        'può trattare come banali procedure. In questo caso,
        'tuttavia, l'intero restituito ha uno scopo, ed equivale
        'alla lunghezza del titolo della finestra.
        'GetWindowText, dopo aver identificato la finestra,
        'ne deposita il titolo nello StringBuilder, che, essendo
        'un tipo reference, viene sempre passato per indirizzo.
        'Capacity indica invece il massimo numero di caratteri
        'accettabili.
        <DllImport("user32.dll")> _
        Public Function GetWindowText(ByVal Handle As IntPtr, _
            ByVal Builder As System.Text.StringBuilder, ByVal Capacity As Int32) As Int32
        End Function
    
        Public Function GetWindowTitle(ByVal Handle As IntPtr)
            'Crea un nuovo string builder, con una capacità
            'di 255 caratteri
            Dim Builder As New System.Text.StringBuilder(255)
            'Richiama la funzione di sistema per ottenere il
            'titolo della finestra
            GetWindowText(Handle, Builder, Builder.Capacity)
            'Dopo la chiamata a GetWindowText, Builder conterrà
            'il titolo: lo restituisce alla funzione
            Return Builder.ToString
        End Function
    
        Public Function FoundWindow(ByVal Handle As IntPtr, _
            ByVal lParam As Int32) As Boolean
            'Ottiene il titolo della finestra
            Dim Title As String = GetWindowTitle(Handle)
            'Scrive a schermo le informazioni sulla finestra
            If Title <> "" Then
                Debug.WriteLine(Handle.ToInt32 & "  -  " & Title)
                ArrayListEvent.Add(Handle.ToInt32 & "  -  " & Title)
            End If
            'Restituisce sempre True: come già detto, i
            'risultati delle funzioni di sistema non sono sempre
            'utili, se non al sistema operativo stesso
            Return True
        End Function
    
        'Enumera tutte le finestra
        Public Sub EnumerateWindows()
            'Inizializza il metodo callback
            Dim Callback As New EnumCallback(AddressOf FoundWindow)
            Dim Success As Boolean
    
            'Richiama la funzione di sistema. IntPtr.Zero come primo
            'parametro indica che il desktop da considerare è
            'quello correntemente aperto. Il secondo parametro
            'fornisce l'indirizzo del metodo callback, che verrà
            'chiamato ogni volta che sia stata trovata una nuova finestra
            Success = EnumDesktopWindows(IntPtr.Zero, Callback, 0)
    
            'Se la funzione non ha successo, restituisce un errore
            If Success = False Then
                Debug.WriteLine("Si è verificato un errore nell'applicazione!")
            End If
        End Sub
    
        Sub Main()
            Debug.WriteLine("Questo programma enumera tutte le finestre aperte.")
            EnumerateWindows()
        End Sub
    End Module
    
    '###############################################
    codice:
    'CODICE FORM1
    'Con un BUTTON cerco il file aperto tramite INDEXOF
    -----------------------------------------------------------
    
    For i As Integer = 0 To Funzioni.ArrayListEvent.Count - 1
          If Funzioni.ArrayListEvent.Item(i).ToString.IndexOf(Path.GetFileNameWithoutExtension(OpenFileDialog1.FileName)) <> -1 Then
               MsgBox("TROVATO!")
          End If
    
    '###############################################
    Confermo il funzionamento poichè ho scritto in una listbox l'elemento di indice (i) ad ogni ciclo del FOR e il MsgBox compare esattamente alla trascrizione del file che ho cercato.

    Potete chiudere. Mi spiegate inoltre come posso scrivere RISOLTO nel titolo?
    Grazie ragazzi

  6. #6
    Originariamente inviato da igeko7
    Potete chiudere. Mi spiegate inoltre come posso scrivere RISOLTO nel titolo?
    Grazie ragazzi
    Su questo forum non c'è né l'usanza di "chiudere" il thread né di piazzare il "risolto" nel titolo (anche se ci stiamo pensando ), per cui si può lasciare così.

    Ricordati però in futuro di mettere il codice tra tag [CODE] ... [/CODE], altrimenti perde l'indentazione; questa volta ho corretto io.

    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    6
    OSP! grazie mille ancora! leggo molti forum ma è il secondo in cui scrivo e sono novizio
    Detto ciò vi pongo l'ulteriore problema in cui mi sono imbattuto: il codice funziona ma se richiamo il modulo ogni tot tempo con il timer (e di conseguenza faccio ripassare la lista) questo non si aggiorna, rimostrandomi il file anche se chiuso. Come faccio a cancellare la lista o fare un refresh

    codice:
     Public Function TROVA(ByVal FileName As String) As Boolean                      'funzione che controlla se un file è aperto
            Funzioni.Main()
            For i As Integer = 0 To Funzioni.ArrayListEvent.Count - 1
                ListBox1.Items.Add(ArrayListEvent(i).ToString)
                If Funzioni.ArrayListEvent.Item(i).ToString.IndexOf(Path.GetFileNameWithoutExtension(FileName)) <> -1 Then
                    Return True
                    Exit Function
                 End If
            Next
            Return False
    end function
    Come faccio a fare un refresh della lista attività?

  8. #8
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    6
    Originariamente inviato da igeko7
    OSP! grazie mille ancora! leggo molti forum ma è il secondo in cui scrivo e sono novizio
    Detto ciò vi pongo l'ulteriore problema in cui mi sono imbattuto: il codice funziona ma se richiamo il modulo ogni tot tempo con il timer (e di conseguenza faccio ripassare la lista) questo non si aggiorna, rimostrandomi il file anche se chiuso. Come faccio a cancellare la lista o fare un refresh

    codice:
     Public Function TROVA(ByVal FileName As String) As Boolean                      'funzione che controlla se un file è aperto
            Funzioni.Main()
            For i As Integer = 0 To Funzioni.ArrayListEvent.Count - 1
                ListBox1.Items.Add(ArrayListEvent(i).ToString)
                If Funzioni.ArrayListEvent.Item(i).ToString.IndexOf(Path.GetFileNameWithoutExtension(FileName)) <> -1 Then
                    Return True
                    Exit Function
                 End If
            Next
            Return False
    end function
    Come faccio a fare un refresh della lista attività?
    Io avrei risolto temporaneamente così:
    codice:
     Public Function TROVA(ByVal FileName As String) As Boolean                      'funzione che controlla se un file è aperto
            Funzioni.Main()                                                             'richiama ilmodulo "funzioni.vb" che crea la lista delle applicazioni aperte
            For i As Integer = 0 To Funzioni.ArrayListEvent.Count - 1                   'fa passare la lista fino a quando trova il nome del file aperto...
                If Funzioni.ArrayListEvent.Item(i).ToString.IndexOf(Path.GetFileNameWithoutExtension(FileName)) <> -1 Then
                    Funzioni.ArrayListEvent.Clear()                                     '...interrompe la ricerca e pulisce la lista per riutilizzarla
                    For j As Integer = 0 To Funzioni.ArrayListEvent.Count - 1
                        Funzioni.ArrayListEvent.Item(j) = ""
                    Next
                    Return True                                                         'ritorna TRUE ed esce
                    Exit Function
                End If
            Next                                                                        'se non trova il file nella lista, ritorna FALSE
            Return False
        End Function
    Soluzioni più eleganti?

  9. #9
    Uhm, ma banalmente fare
    codice:
    ListBox1.Items.Clear();
    prima di popolare il listbox?
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    6
    Originariamente inviato da MItaly
    Uhm, ma banalmente fare
    codice:
    ListBox1.Items.Clear();
    prima di popolare il listbox?
    Grazie della risposta. Il fatto è che il listbox l'ho rimosso poiché mi serviva solo come prova visiva ma non compare nel form di progettazione. Il problema è proprio l'arraylistevent che una volta che viene generato, se non ripulito rimane sempre lo stesso. Così funziona ma volevo avere dei pareri. grazie mille

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.