vb.netproblem-steps-recorder

Integrate PSR in a VB.NET application


Since PSR (Problem Steps Recorder) cannot be considered a widely used tool, I was thinking of integrating it in my VB.NET application.

It could be a useful tool for understanding how users arrive to problems and to reproduce issues and errors. More information about PSR: http://blogs.msdn.com/b/patricka/archive/2010/01/04/using-the-secret-windows-7-problem-step-recorder-to-create-step-by-step-screenshot-documents.aspx

I think that integrating it in an application will help users to use it even if maybe they don't know it exists and help the maintainer to have more information about how a user gets problems.

Is there somebody who has already done such a thing, possibly using VB.NET?

Suggestions?

Thanks in advance.


Solution

  • This post got no interest (and only 23 views :( ), so I spent some time to write my own class to integrate PSR in my application.

    I had to adapt my code (it is a part of a bigger project) and I had to translate comments from Italian to English, but the following should work (or require minimal changes):

    Public Class clsPSRDemo
    Private WithEvents prcPSR As New Process
    Private i32TimeSpent As Int32
    Private bEventHandled As Boolean
    Friend Event Exited As EventHandler
    
    ''' <summary>
    ''' Tracks User action using PSR and send the file obtained through email
    ''' </summary>
    ''' <remarks>AA20140801 - ☮ Andrea Antonangeli per © Octet - Ingegneria dei Sistemi - S.r.l.</remarks>
    Friend Function TrackActions() As String
        Dim OSVersion As Version = Environment.OSVersion.Version
        Dim Win7Version As Version = Version.Parse("6.1.7600")
        Dim strFilePSR As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\MyProject\PSRFile" & Format(Now, "yyyyMMdd_HHmmss") & ".zip"   'Change this depending on your needs
        Const i32Timeout As Int32 = 600000 '(10 minuti)
        Const i32SleepInterval As Int32 = 200   '(0,2 secondi)
    
        i32TimeSpent = 0
        bEventHandled = False
        Try
            'Check Windows version
            If OSVersion.CompareTo(Win7Version) < 0 Then
                MessageBox.Show("You must have Windows 7 or newer", "Unusable function", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                Return "Err: SO too old"
                Exit Function
            End If
            Dim strPSRPath As String = Environment.GetFolderPath(Environment.SpecialFolder.System) & "\psr.exe "
            'Check if psr.exe exists (should always be true, but who knows...)
            If IO.File.Exists(strPSRPath) = False Then
                MessageBox.Show("Could not find file 'psr.exe' in folder " & Environment.GetFolderPath(Environment.SpecialFolder.System), "Funzione non utilizzabile", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return "Err: PSR not found"
                Exit Function
            End If
            'Start PSR and check event when finished
            prcPSR.StartInfo.FileName = strPSRPath
            prcPSR.StartInfo.CreateNoWindow = True
            prcPSR.StartInfo.Arguments = " /start /maxsc 50 /exitonsave 1 /output " & strFilePSR
            prcPSR.EnableRaisingEvents = True
            prcPSR.Start()
        Catch ex As Exception
            MessageBox.Show("Error executing PSR." & ex.Message, "Retry.")
            Return "Err: PSR excepion " & ex.Message
        End Try
        'Wait for "Exited" event for the time specified in i32Timeout (10 minutes)
        Do While Not bEventHandled
            i32TimeSpent += i32SleepInterval
            If i32TimeSpent > i32Timeout Then
                MessageBox.Show("Timeout (10 minutes). We stop tracking", "Operazion not completed", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                prcPSR.CloseMainWindow()
                prcPSR.Close()
                Return "Err: Timeout"
                Exit Function
            End If
            Application.DoEvents()
            System.Threading.Thread.Sleep(i32SleepInterval)
        Loop
        MessageBox.Show("Thanks, your steps have been recorded and now we are sending them through email", "Operation completed", MessageBoxButtons.OKCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)
        Dim strMsgUscita As String = String.Empty
        Try
            Dim MailTicket As New clsMandaMail
            With MailTicket
                .Mittente = frmOpzioni.prpMailMittente
                .MandoCC = .Mittente    'Metto il mittente in copia 
                .MandoA = "supportosocrate@octet.it"
                .Soggetto = "Messaggio TAS del " & Now.ToString & " eseguito da " & objOctetLib.DimmiNomeUtente & " da computer " & objOctetLib.DimmiNomeQuestoComputer
            End With
            'La creo
            Dim mailToBeSent As New Net.Mail.MailMessage("yourUserMail@hisdomain.com", "yoursupportmail@yourdomain.it", "PSR file attached", "Check the .zip file attached")
            If Not IO.File.Exists(strFilePSR) Then
                MessageBox.Show("Il file " & strFilePSR & " was NOT found." & vbCrLf & "Check folder " & My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\MyProject & and send it to support manually", "PSR file not found.", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                strMsgUscita = "Err: PDR file not found"
                Return strMsgUscita
                Exit Function
            End If
            Dim PSRAttachment As New Net.Mail.Attachment(strFilePSR)
            mailToBeSent.Attachments.Add(PSRAttachment)
            'Sending
            Dim MailClient As New Net.Mail.SmtpClient("CustomerFavoriteSMTPServer")
            MailClient.UseDefaultCredentials = True
            MailClient.Send(mailToBeSent)
        Catch ex As Exception
            MessageBox.Show("Error sending mail " & ex.Message, "Error.", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            strMsgUscita = "Err: mail NOT sent"
        End Try
        Return strMsgUscita
    End Function
    
    'Exited event 
    Private Sub prcPSR_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles prcPSR.Exited
        bEventHandled = True
        Debug.Print("Exited at " & prcPSR.ExitTime & " code " & prcPSR.ExitCode)
    End Sub  
    End Class
    

    Hope it helps if you have my same needs. Enjoy.