Link to home
Start Free TrialLog in
Avatar of BTMExpert
BTMExpert

asked on

File not moving

I'm using

Dim proc As New Diagnostics.Process()

//some code with a file

proc.WaitForExit(1000)
proc.Close()

File.Move()

I get an error saying the file is still in use.  How else can I close the process so I can move the file?
SOLUTION
Avatar of systan
systan
Flag of Philippines image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of BTMExpert
BTMExpert

ASKER

I've tried .WaitForExit, Close, Kill, and Dispose.  None are working.  I still get that error.  I put  a timestamp after every instance of proc to see how long it took to finish and it's pretty instant.  I have 3 instances running.  So my code is like this
Dim proc As New Diagnostics.Process()

For loop

proc.Start()
proc.close()

proc.Start()
proc.close()

proc.Start()
proc.close()

File.Move

Next

Open in new window

I've also tried
Dim proc As New Diagnostics.Process()

For loop

proc.Start()


proc.Start()


proc.Start()
proc.close()

File.Move

Next

Open in new window

to no success
It's impossible that you can't kill the process unless it has been hold by anything else in the service.

Try to find out the main controller of the application you want to kill

or you have not pointed out the right process to kill
eq.
For Each p As Process In Process.GetProcesses
            If p.ProcessName = "WINWORD" Then
                p.Kill()
            End If
            If p.ProcessName = "EXCEL" Then
                p.Kill()
            End If
            If p.ProcessName = "MSPUB" Then
                p.Kill()
            End If
        Next

Open in new window


or you could try this code to:
      Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
    <DllImport("USER32.DLL")> _
           Private Shared Function GetShellWindow() As IntPtr
    End Function
    <DllImport("USER32.DLL")> _
    Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
    End Function
    <DllImport("USER32.DLL")> _
    Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
    End Function
    <DllImport("USER32.DLL")> _
    Private Shared Function EnumWindows(ByVal enumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
    End Function
    Private hShellWindow As IntPtr = GetShellWindow()
    Private dictWindows As New Dictionary(Of IntPtr, String)
    Private currentProcessID As Integer
    <System.Runtime.InteropServices.DllImport("kernel32.dll")> _
    Private Shared Function TerminateThread(ByVal hThread As IntPtr, ByVal dwExitCode As UInteger) As Boolean
    End Function
    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Private Shared Function PostMessage(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wparam As IntPtr, ByVal lparam As IntPtr) As Boolean
    End Function
    
    Public Function GetOpenWindowsFromPID(ByVal processID As Integer) As IDictionary(Of IntPtr, String)
        dictWindows.Clear()
        currentProcessID = processID
        EnumWindows(AddressOf enumWindowsInternal, 0)
        Return dictWindows
    End Function


  Private Function enumWindowsInternal(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
        If (hWnd <> hShellWindow) Then
            Dim windowPid As UInt32
            If Not IsWindowVisible(hWnd) Then
                Return True
            End If
            Dim length As Integer = GetWindowTextLength(hWnd)
            If (length = 0) Then
                Return True
            End If
            GetWindowThreadProcessId(hWnd, windowPid)
            If (windowPid <> currentProcessID) Then
                Return True
            End If
            Dim stringBuilder As New StringBuilder(length)
            GetWindowText(hWnd, stringBuilder, (length + 1))
            dictWindows.Add(hWnd, stringBuilder.ToString)
        End If
        Return True
    End Function

    Private Function searchndestroy(ByVal dfilename As String) As Boolean
        Dim found As Boolean = False
        Dim ext As String = Nothing
        For Each proces As Process In Process.GetProcesses
            Dim windows As IDictionary(Of IntPtr, String) = GetOpenWindowsFromPID(proces.Id)
            For Each kvp As KeyValuePair(Of IntPtr, String) In windows
                If kvp.ToString.Contains(dfilename) Then
                    proces.Kill()
                    found = True
                    Exit For
                End If
		''//or
		If kvp.Value = ("Microsoft Office Activation Wizard") Then
		    PostMessage(kvp.Key, &H10, 0, 0)
                    ''//TerminateThread(kvp.key,1)
		    found = True
                    Exit For
                End If
            Next
            If found = True Then Exit For
        Next
''//you can use LISTBOX to view the kvp.value of the application
   End Function

Open in new window


if still not killing?  it means somethings holding the process, an application in the services.
It's impossible that you can't kill the process unless it has been hold by anything else in the service.

Try to find out the main controller of the application you want to kill

or you have not pointed out the right process to kill
eq.
For Each p As Process In Process.GetProcesses
            If p.ProcessName = "WINWORD" Then
                p.Kill()
            End If
            If p.ProcessName = "EXCEL" Then
                p.Kill()
            End If
            If p.ProcessName = "MSPUB" Then
                p.Kill()
            End If
        Next

Open in new window


or you could try this code to:
      Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
    <DllImport("USER32.DLL")> _
           Private Shared Function GetShellWindow() As IntPtr
    End Function
    <DllImport("USER32.DLL")> _
    Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
    End Function
    <DllImport("USER32.DLL")> _
    Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
    End Function
    <DllImport("USER32.DLL")> _
    Private Shared Function EnumWindows(ByVal enumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
    End Function
    Private hShellWindow As IntPtr = GetShellWindow()
    Private dictWindows As New Dictionary(Of IntPtr, String)
    Private currentProcessID As Integer
    <System.Runtime.InteropServices.DllImport("kernel32.dll")> _
    Private Shared Function TerminateThread(ByVal hThread As IntPtr, ByVal dwExitCode As UInteger) As Boolean
    End Function
    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Private Shared Function PostMessage(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wparam As IntPtr, ByVal lparam As IntPtr) As Boolean
    End Function
    
    Public Function GetOpenWindowsFromPID(ByVal processID As Integer) As IDictionary(Of IntPtr, String)
        dictWindows.Clear()
        currentProcessID = processID
        EnumWindows(AddressOf enumWindowsInternal, 0)
        Return dictWindows
    End Function


  Private Function enumWindowsInternal(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
        If (hWnd <> hShellWindow) Then
            Dim windowPid As UInt32
            If Not IsWindowVisible(hWnd) Then
                Return True
            End If
            Dim length As Integer = GetWindowTextLength(hWnd)
            If (length = 0) Then
                Return True
            End If
            GetWindowThreadProcessId(hWnd, windowPid)
            If (windowPid <> currentProcessID) Then
                Return True
            End If
            Dim stringBuilder As New StringBuilder(length)
            GetWindowText(hWnd, stringBuilder, (length + 1))
            dictWindows.Add(hWnd, stringBuilder.ToString)
        End If
        Return True
    End Function

    Private Function searchndestroy(ByVal dfilename As String) As Boolean
        Dim found As Boolean = False
        Dim ext As String = Nothing
        For Each proces As Process In Process.GetProcesses
            Dim windows As IDictionary(Of IntPtr, String) = GetOpenWindowsFromPID(proces.Id)
            For Each kvp As KeyValuePair(Of IntPtr, String) In windows
                If kvp.ToString.Contains(dfilename) Then
                    proces.Kill()
                    found = True
                    Exit For
                End If
		''//or
		If kvp.Value = ("Microsoft Office Activation Wizard") Then
		    PostMessage(kvp.Key, &H10, 0, 0)
                    ''//TerminateThread(kvp.key,1)
		    found = True
                    Exit For
                End If
            Next
            If found = True Then Exit For
        Next
''//you can use LISTBOX to view the kvp.value of the application
   End Function

Open in new window


if still not killing?  it means somethings holding the process, an application in the services.
When I try to run the Kill(), it gives me an error "Access is denied"

I'm using ffmpeg to convert video files if that makes a difference.  It didn't think it would that's why I don't know why p.Kill() doesn't work.  Thank you for your help so far.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
In this case, this was what I was looking for.  I didn't know there was a Exited().  Thank you systan