3

I have this:

    Dim myTemp As String
    myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf"

    System.IO.File.Copy(myFile, "c:\" & myTemp)
    Application.DoEvents()
    OpenFile(myTemp)

The problem is that when I call OpenFile, which is just a call to a sub that opens a file, it cannot find the file. This is because it is calling it so quickly that the program doesn't have time to actually create the file before the open takes place.

I thought that DoEvents() would rectify this but it does not. I need to wait until the file is created before I open the file. How can I do that?

johnny
  • 19,272
  • 52
  • 157
  • 259

11 Answers11

3

I don't really know much VB.NET, but isn't Copy a blocking call? Are you sure you're not just trying to open the file from the wrong location (or the unescaped backslash invalidates the path)?

What about this? I've added the drive letter to OpenFile, and escaped the backslash both places.

Dim myTemp As String
myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf"

System.IO.File.Copy(myFile, "c:\\" & myTemp)
OpenFile("c:\\" & myTemp)
Simon B. Jensen
  • 978
  • 5
  • 12
1

This is ugly but it works for me

 Function WaitForFile(fullPath, wdelay)
    Dim vd_start As Date
    vd_start = Now()
    Dim vd_end As Date
    Dim wsec, wmin, whour, wt5string As Integer
    Dim wtstring As String
    Dim count As Integer
    Dim wscale As Integer
    Dim vd_1 As Date
    Dim Vo_fileinfo As FileInfo

    Dim fs As FileStream

    wsec = Format(wdelay Mod 60, "00")
    wmin = Format(Int(wdelay / 60), "00")
    whour = Format(Int(wdelay / (60 * 60)), "00")
    wtstring = CStr(whour) + ":" + CStr(wmin) + ":" + CStr(wsec)
    Dim duration = New System.TimeSpan(0, whour, wmin, wsec)
    vd_end = vd_start.Add(duration)

    On Error GoTo error1
    Dim vsize1, vsize2 As Long
    While vd_start < vd_end
        fs = New FileStream(fullPath, FileMode.Open)
        fs.ReadByte()
        fs.Seek(0, SeekOrigin.Begin)
        fs.Close()
        Vo_fileinfo = New FileInfo(fullPath)
        vsize1 = Vo_fileinfo.Length
        Threading.Thread.Sleep(500)
        Vo_fileinfo = New FileInfo(fullPath)
        vsize2 = Vo_fileinfo.Length
        If vsize1 <> vsize2 Then GoTo error1
        GoTo finalgoto
error1:
        Err.Clear()
        vd_start = Now()
    End While

    WaitForFile = False
    GoTo Endgoto
finalgoto: WaitForFile = True
Endgoto:
End Function 
Adz
  • 11
  • 1
1

Ideally you should perform the copy on a separate thread that informs the main GUI thread when it is done so it can then perform the open through an Invoke call.

Otávio Décio
  • 73,752
  • 17
  • 161
  • 228
  • +1 - You should always perform a blocking operation in a background thread, especially if it is for an operation that will block for a long time (such as copying a large file). See BackgroundWorker on MSDN for more info. – Justin Ethier Mar 09 '10 at 17:58
1

Use FileSystemWatcher to alert you when the file is created. No loops.

https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6165137.html

Community
  • 1
  • 1
Andrew
  • 11
  • 1
  • This is not working either, I use the FileSystemWatcher to display an image as soon as it is created and (for large images) I receive the File is already in use by another process error. I solved this checking for exclusive file access. – tommasop May 08 '13 at 13:49
0
dim SourceFile as string
dim DestinationFile as string

SourceFile = "c:/archivo.txt"
DestinationFile = "c:/destino/archivo.txt"

If System.IO.File.Exists(SourceFile) = True Then

    System.IO.File.Copy(SourceFile, DestinationFile, True)
    'or
    'My.Computer.FileSystem.CopyFile(SourceFile, DestinationFile, FileIO.UIOption.AllDialogs, FileIO.UICancelOption.DoNothing)

    SourceFile = ""
    DestinationFile = ""

else

    MessageBox.Show("the file don't copy!") 

end if 
Leo
  • 37,640
  • 8
  • 75
  • 100
0

This is a bit hacky, but it should work.

Do Until (System.IO.File.Exists("C:\" & myTemp))
    Threading.Thread.Sleep(1)
Loop
Tom Anderson
  • 10,807
  • 3
  • 46
  • 63
  • I dont' think this will work if the file takes a while to copy. – JohnFx Jan 12 '09 at 23:23
  • The copy is a blocking call, the issue he is getting is the processing time between the release of the blocking call and the next code step. This bit of code just helps the OS catch up. – Tom Anderson Jan 12 '09 at 23:24
  • That sounds a little fishy to me. If it is blocking it should finish the operation by the time it returns control back to the calling module. Are you thinking that the OS isn't releasing the lock on the file quickly enough perhaps? – JohnFx Jan 12 '09 at 23:27
  • i have found this to be the case with files over a few k. for some reason opening a file right after copying it takes a few for the OS to catch up. – Tom Anderson Jan 12 '09 at 23:28
0

That isn't really what Doevents is used for. It is most frequently used to let the UI message queue clear out (let the UI have some CPU time to refresh). It is slightly more complex than I am describing, but that isn't the point of your question so I will move on.

Try this to make the critical section of your code block:

SyncLock Me
  System.IO.File.Copy(myFile, "c:\" & myTemp)
  Application.DoEvents()
End SyncLock

OpenFile(myTemp)
JohnFx
  • 34,542
  • 18
  • 104
  • 162
  • BTW: Application.DoEvents description from MSDN is this "Processes all Windows messages currently in the message queue." The message queue is a way that Windows allows inputs to wait in line before going to the UI (Mouse/keyboard events,etc). Your code "blocks" or stops up that line temporarily. – JohnFx Jan 12 '09 at 23:31
0

In addition to Tom's answer, isnt it better to put a Application.DoEvents() rather then making the thread sleep?

masfenix
  • 7,736
  • 11
  • 45
  • 60
0

First, you should not call DoEvents anywhere. For the most part, when it is used, it is a hack to circumvent what should really be an asynchronous operation.

That being said, the Copy method is a synchronous operation. The call to OpenFile will not occur until the call to Copy completes.

That being said when the call to OpenFile occurs, if the file does not exist, it is because you copied it to the wrong place, or because some other process is working on the file in question.

casperOne
  • 73,706
  • 19
  • 184
  • 253
0

I thinf Synclock is not good for this case

for explaination, MSDN can help me

The SyncLock statement ensures that multiple threads do not execute the same statements at the same time. When the thread reaches the SyncLock block, it evaluates the expression and maintains this exclusivity until it has a lock on the object that is returned by the expression. This prevents an expression from changing values during the running of several threads, which can give unexpected results from your code.

in my opinion, copy is blocking method, so thread waits until copying is done

can`t be problem in another place?

drizzt
  • 2,756
  • 6
  • 27
  • 41
-1

System.Threading.Thread.Sleep(1000);

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
scottm
  • 27,829
  • 22
  • 107
  • 159