locked
Diagnostics.Process.Start only works fist time RRS feed

  • Question

  • Hi all,

    I'm using Diagnostics.Process.Start(Path) to open a pdf file. It works fine on first instance.

    The pdf file displays, then I close it. The next time I call Diagnostics.Process.Start(Path) it throws an error stating the file is in use by another application.

    Do I somehow need to terminate or dispose of anything so this works more than once?

    Thanks in advance.

    LP



    • Edited by dw80916 Tuesday, September 1, 2020 3:59 PM
    Tuesday, September 1, 2020 3:52 PM

Answers

  • Thanks all for your assistance. The following code works.

                            Form1.PrintDocument1.Print()
    
                            ' Insert delay to allow file to finish writing
                            Dim dteFutureDate As Date = Date.Now().AddSeconds(3)
                            Do Until Date.Now() > dteFutureDate
                            Loop
    
                            ' Launch Acrobat to display the PDF report
                            p.StartInfo.FileName = SummaryPDFPath & ".pdf"
                            p.Start()
                            p.WaitForExit()
                            p.Close()
    

    • Marked as answer by dw80916 Tuesday, September 1, 2020 7:06 PM
    Tuesday, September 1, 2020 7:06 PM

All replies

  • I did this

            Dim p As New Process
            p.StartInfo.FileName = path
            p.Start()
            p.WaitForExit() 'wait until Adobe quits

    Then closed the Adobe window and did it again.  Could NOT reproduce your error.


    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein

    Tuesday, September 1, 2020 4:05 PM
  • Hi

    ........... and, I did this with no problems opening a .pdf file over and over again.

    Dim p As New Process
    p.StartInfo.FileName = path
    p.Start()
    


    Regards Les, Livingston, Scotland

    Tuesday, September 1, 2020 4:13 PM
  • Used the suggested code:

                            Dim p As New Process
                            p.StartInfo.FileName = SummaryPDFPath & ".pdf"
                            p.Start()
                            p.WaitForExit()

    I still get the error.


    • Edited by dw80916 Tuesday, September 1, 2020 4:30 PM
    Tuesday, September 1, 2020 4:26 PM
  • Hi

    Have you opened the file 'normally' in another app (or browser or what ever)?


    Regards Les, Livingston, Scotland

    Tuesday, September 1, 2020 4:28 PM
  • If I set a breakpoint at p.StartInfo.Filename then step into p.Start the pdf file will display every time. Without the breakpoint it throws the error.
    Tuesday, September 1, 2020 4:55 PM
  • If I set a breakpoint at p.StartInfo.Filename then step into p.Start the pdf file will display every time. Without the breakpoint it throws the error.

    Hi

    Sorry, that means nothing to me as I can't even reproduce the problem.  Is the .pdf file on your local HDD (the same one your VB App is on)?


    Regards Les, Livingston, Scotland


    • Edited by leshay Tuesday, September 1, 2020 5:17 PM
    Tuesday, September 1, 2020 5:16 PM
  • What actually opens the .pdf file on your system?  On my system it is Acrobat Reader.

    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein


    • Edited by dbasnett Tuesday, September 1, 2020 5:45 PM
    Tuesday, September 1, 2020 5:45 PM
  • The application generates pdf reports that have date and time stamps in the filename then attempts to open the file. So it will always be a new filename each time it is called. So, I get the error even with a newly created file. I can open any of the files normally. I've even done a computer restart and tried using p.Close() but no help.

    Now I'm thinking there needs to be a delay or I need to test if file exists before proceeding to opening it. The breakpoint provided that delay.

    Tuesday, September 1, 2020 5:51 PM
  • Hi

    So, are you saying that your app first of all generates the .pdf file and then opens it (with the code you posted)? Then repeats the process but fails with the second attempt.


    Regards Les, Livingston, Scotland


    • Edited by leshay Tuesday, September 1, 2020 5:55 PM
    Tuesday, September 1, 2020 5:54 PM
  • Have you tried using Microsoft's Process Explorer (https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer) to find the process that is holding a handle to your pdf file?
    Tuesday, September 1, 2020 6:12 PM
  • Yes. My application generates the pdf report file then opens it. Each time a report is generated it will have a new filename. So that's why I don't understand it saying the file is already open. It can't be as it's a new file altogether. It's usually a few minutes between each report. Reports are on the same HDD different folder than the exe.

    The VERY first time I ran the code, it worked. Has not worked since.

    Tuesday, September 1, 2020 6:22 PM
  • Yes. My application generates the pdf report file then opens it. Each time a report is generated it will have a new filename. So that's why I don't understand it saying the file is already open. It can't be as it's a new file altogether. It's usually a few minutes between each report. Reports are on the same HDD different folder than the exe.

    The VERY first time I ran the code, it worked. Has not worked since.

    So I wrote code to create a new PDF every time a button was clicked. Still couldn't reproduce the error.

            Dim path2 As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
            'create a new file name
            path2 = IO.Path.Combine(path2, DateTime.Now.ToString("HH_mm_ss") & ".pdf")
    
            IO.File.Copy(path, path2) 'path is an existing file
    
            ' If IO.File.Exists(path2) Then
            Dim p2 As New Process
            p2.StartInfo.FileName = path2
            p2.Start()
            p2.WaitForExit()
            p2.Dispose()
            ' End If
    


    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein

    Tuesday, September 1, 2020 6:45 PM
  • This means the process which generates the PDF is holding on to a file handle. To test this generate the PDF, close the app and by double clicking on the new pdf via Windows Explorer if the file opens it's the generation process at fault.

    Not seeing the code, if possible refactor code to use "using" statements and open the new file after the using statement code has completed.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, September 1, 2020 7:01 PM
  • Hi

    The closest I could come to seeing the exception you are having was the following:

    See the code below - it creates 4 test files on the desktop.  If the .Close is not included, then, when the files are created on the desktop and the application is still running, the 'file open' exception occurs when trying to delete the file(s).  If the .Close is included then the files can be deleted without exception.  This just helps to point at your code leaving file(s) open when creating them.

    Option Strict On
    Option Explicit On
    Public Class Form1
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    		Dim folder As String = My.Computer.FileSystem.SpecialDirectories.Desktop
    		For i As Integer = 1 To 4
    			Dim path As String = IO.Path.Combine(folder, "Testing" & i.ToString & ".txt")
    			IO.File.CreateText(path).Close()
    			ProcessIt(path)
    		Next
    	End Sub
    	Sub ProcessIt(path As String)
    		Dim p As New Process
    		p.StartInfo.FileName = path
    		p.Start()
    	End Sub
    End Class


    Regards Les, Livingston, Scotland

    Tuesday, September 1, 2020 7:05 PM
  • Thanks all for your assistance. The following code works.

                            Form1.PrintDocument1.Print()
    
                            ' Insert delay to allow file to finish writing
                            Dim dteFutureDate As Date = Date.Now().AddSeconds(3)
                            Do Until Date.Now() > dteFutureDate
                            Loop
    
                            ' Launch Acrobat to display the PDF report
                            p.StartInfo.FileName = SummaryPDFPath & ".pdf"
                            p.Start()
                            p.WaitForExit()
                            p.Close()
    

    • Marked as answer by dw80916 Tuesday, September 1, 2020 7:06 PM
    Tuesday, September 1, 2020 7:06 PM
  • Hi

    OK you have managed to fix your issue.

    However, several people have contributed to the effort of finding a solution for you but you have ignored any indication of marking any of them as helpful (vote up) or answer.  The answer certainly wasn't your post!

    So, thank you for your question that wasn't even the right question!


    Regards Les, Livingston, Scotland

    Tuesday, September 1, 2020 7:14 PM
  • Thanks all for your assistance. The following code works.

                            Form1.PrintDocument1.Print()
    
                            ' Insert delay to allow file to finish writing
                            Dim dteFutureDate As Date = Date.Now().AddSeconds(3)
                            Do Until Date.Now() > dteFutureDate
                            Loop
    
                            ' Launch Acrobat to display the PDF report
                            p.StartInfo.FileName = SummaryPDFPath & ".pdf"
                            p.Start()
                            p.WaitForExit()
                            p.Close()

    This doesn't look like an answer, more like a band-aid.


    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein

    Tuesday, September 1, 2020 8:49 PM
  • Totally agree, seem there should be an assert e.g.

    Public Async Function IsFileInUse(filePath As String, waitFor As Integer) As Task(Of Boolean)
    
        Await Task.Delay(waitFor)
    
        Try
            Using File.Open(filePath, FileMode.Open)
            End Using
        Catch e As IOException
            Dim errorCode = Marshal.GetHRForException(e) And ((1 << 16) - 1)
            Return errorCode = 32 OrElse errorCode = 33
        End Try
    
        Return False
    
    End Function


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, September 1, 2020 9:12 PM