Resolved Is it OK to start a process in BackgroundWorker

aaaron

Well-known member
Joined
Jan 23, 2011
Messages
216
Programming Experience
10+
VB.NET:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        Dim tmp As String() = CStr(e.Argument).Split("?"c)
        Dim folder1 As String = tmp(0)
        Dim folder2 As String = tmp(1)
        Dim procInfo As New ProcessStartInfo
        With procInfo
            .FileName = "xcopy"
            .Arguments = folder1 & " " & folder2 & " /c /d /e /h /i /k /q /r /s /x /y"
            .CreateNoWindow = True
            .UseShellExecute = False
        End With
        Dim proc As Process = Process.Start(procInfo)
        Do While Not proc.HasExited
            If BackgroundWorker1.CancellationPending Then
                proc.Kill()
            End If
        Loop
    End Sub

The two folder strings look OK
I've tried a few things but the above code always shows proc.HasExited as True.
What am I doing wrong?
 
Last edited by a moderator:
Solution
Do you see different behaviour if you start the process on the UI thread? If not, what's the problem?

You shouldn't be using a BackgroundWorker at all though. The point of a BackgroundWorker is to keep the UI thread free while you do other work but the only reason that you have other work to do is that you're using that awful loop. Get rid of that loop and there's no need to prevent the UI freezing.
VB.NET:
Private WithEvents xcopyProcess As Process

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim sourceFolderPath = "source folder path here"
    Dim destinationFolderPath = "destination folder path here"
    Dim arguments = $"""{sourceFolderPath}"" ""{destinationFolderPath}"" /c /d /e /h /i /k /q /r...
Do you see different behaviour if you start the process on the UI thread? If not, what's the problem?

You shouldn't be using a BackgroundWorker at all though. The point of a BackgroundWorker is to keep the UI thread free while you do other work but the only reason that you have other work to do is that you're using that awful loop. Get rid of that loop and there's no need to prevent the UI freezing.
VB.NET:
Private WithEvents xcopyProcess As Process

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim sourceFolderPath = "source folder path here"
    Dim destinationFolderPath = "destination folder path here"
    Dim arguments = $"""{sourceFolderPath}"" ""{destinationFolderPath}"" /c /d /e /h /i /k /q /r /s /x /y"
    Dim psi As New ProcessStartInfo("xcopy",
                                    arguments) With {.CreateNoWindow = True,
                                                     .UseShellExecute = False}

    xcopyProcess = Process.Start(psi)
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    xcopyProcess.Kill()
    xcopyProcess = Nothing
End Sub

Private Sub xcopyProcess_Exited(sender As Object, e As EventArgs) Handles xcopyProcess.Exited
    'The process has completed.
    xcopyProcess = Nothing
End Sub
 
Solution
Thanks for the reply.

Am I doing something dumb?
I had to make a few changes to fit my configuration.
It still does not do the copy
I add the HasExited as a check and it shows True

VB.NET:
Private WithEvents xcopyProcess As Process
   Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
       Dim tmp As String() = CStr(e.Argument).Split("?"c)
       Dim sourceFolderPath As String = tmp(0)
       Dim destinationFolderPath As String = tmp(1)
       'QuickWatch shows arguments as:  """C:\Users\Cal\Desktop\JUNK1"" ""C:\Users\Cal\Desktop\JUNK2"" /c /d /e /h /i /k /q /r /s /x /y"
       Dim arguments As String = $"""{sourceFolderPath}"" ""{destinationFolderPath}"" /c /d /e /h /i /k /q /r /s /x /y"
       Dim psi As New ProcessStartInfo("xcopy",
                                   arguments) With {.CreateNoWindow = True,
                                                    .UseShellExecute = False}
       xcopyProcess = Process.Start(psi)
       If xcopyProcess.HasExited Then
           Debug.WriteLine("HasExited is true")
       End If
   End Sub


================
REVISION: Works with /c /e /h /s

Thanks
 
Last edited:
on this line:
ProcessStartInfo("xcopy", arguments) With {.CreateNoWindow = True, .UseShellExecute = False}
where it says xcopy this for the program so your code can not be injected with malicious code you also need to include xcopy to you arguments line

ProcessStartInfo:
Dim arguments as string = "xcopy" + source + " " + Destination  + " " + Swithces
ProcessStartInfo("xcopy", arguments) With {.CreateNoWindow = True, .UseShellExecute = False}

this is just a rough example, the first part of processStarinfo and for executable name the arguments is for the whole arguments line including "xcopy" aswell.

sorrry if this is a bit mish mash, but I've just recently done this also in a program of my own

also put the files extension .exe or what ever it may be


PrrotekNickz xD
 
@ProtekNickz that is neither how xcopy command works nor how Process/ProcessStartInfo classes work. Arguments is only the switches passed to the application.
 
If I'm right in thinking as I just did this on C++ and their not to far dissimilar, then to do a secure execution of the shell command would be similar to

C++ tid bit example:
char appName[] = "xcopy.exe";
char args[] = "xcopy.exe source destination";

CreateProcess(appName , args, 0, 0, FALSE,0 ,0 ,0 , &si, &pi);]

this is the only reason I'm saying this, If i don't place the executables name in the application name and the argument line the program won't function corrrectly, for one if I don't place it in application name it come up on windows defender as a virus which is weird in it's self , and if I don't place it in the argument line the command simply won't run, plus it makes it more awkward to inject code in to it, hence the securer option, if I'm wrong then maybe it's just in C++ you need to do it this way.


ProtekNickz xD
 
so.... if this is the case the difference between CreateProcess and ProcessStartInfo, Is ProcessStartInfo will be more susceptible to a code injection than a CreateProcess in that terms, Would their be a similar convention to defer such an attack, Yes I know this is only a deterrence , but it does halt the code from running if the application name is different than the running process.

Just a thought.


ProtekNickz xD
 
The .Net Process class is like everything else deep down implemented with native calls, how that is implemented specifially is not relevant for this thread. In any case your suggested solution in post 4 is just uninformed and wrong. By the way OP has explained that the problem was just with the switches and marked this old thread Resolved.
 
lol ask a legitimate question and get bum fluffed xD.

np, just another experience I guess

ProtekNickz xD
 
If you have a question of your own then start a new thread of your own for that topic.
 
Back
Top