Reputation: 106
I have a Console app and a Winforms app that do the same. The common functionality is in a class being reused by both.
The CopyRequiredFile, starts a windows batch file which uses xcopy to copy files from a network folder to a local drive. But, when called from the Windows Forms app it doesn't copy the files.
I am a novice developer trying to develop framework and some internal tools for UI automation.
Why does it work to copy the files when I invoke the functionality from the Console application, but not from the Windows Forms Application?
My Console App:
public class Program
{
private static readonly Action<string> OutputAction = s => Console.WriteLine(s);
private static readonly IProgress<string> Progress = new Progress<string>(OutputAction);
public static void Main(string[] args)
{
HelpersCopy.CreateRequiredDirectories(Progress);
HelpersCopy.CopyRequiredFiles(Progress, true);
HelpersCopy.StartHub(Progress);
HelpersCopy.StartNode(Progress);
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
My Windows Forms app: Only code that is relevant to this question.
private void button1_Click(object sender, EventArgs e)
{
Action<string> outputAction = s => txtOutput.InvokeEx(t => t.Text += s + Environment.NewLine);
IProgress<string> progress = new Progress<string>(outputAction);
txtOutput.Clear();
HelpersCopy.CreateRequiredDirectories(progress);
HelpersCopy.CopyRequiredFiles(progress, true);
HelpersCopy.StartHub(progress);
HelpersCopy.StartNode(progress);
}
InvokeEx is an extension method to invoke the action if required. Help from stackoverflow!
Unfortunately, I cannot post images because I don't have the required points. So, please see the output images here: https://www.flickr.com/photos/61600076@N05/sets/72157649781440604/
Helpers Class Code Please let me know if this code is not required in the question.
public class HelpersCopy
{
public static void CopyRequiredFiles(IProgress<string> progress, bool hideWindow = false)
{
progress.Report(string.Format("Copying latest version of executables...{0}", Environment.NewLine));
var currentDirectory = Directory.GetCurrentDirectory();
ExecuteCommand(String.Format(@"{0}\Copy latest Selenium files.bat", currentDirectory), progress, hideWindow: hideWindow);
progress.Report(string.Format("\r\nLatest version of executables copied successfully{0}", Environment.NewLine));
}
private static void ExecuteCommand(string fileName, IProgress<string> progress, string command = null, bool hideWindow = true)
{
if (hideWindow)
{
var processInfo = new ProcessStartInfo(fileName, command)
{
CreateNoWindow = true,
UseShellExecute = false,
// *** Redirect the output ***
RedirectStandardError = true,
RedirectStandardOutput = true
};
var process = new Process { StartInfo = processInfo, EnableRaisingEvents = true };
process.ErrorDataReceived += (sender, args) => progress.Report(args.Data);
process.OutputDataReceived += (sender, args) => progress.Report(args.Data);
var started = process.Start();
progress.Report(string.Format("process started: {0}", started));
progress.Report(string.Format("process id: {0}", process.Id));
progress.Report(string.Format("process start info: {0} {1}", process.StartInfo.FileName, process.StartInfo.UserName));
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
int ExitCode = process.ExitCode;
progress.Report(string.Format("ExitCode: {0}{1}", ExitCode, Environment.NewLine));
process.Close();
}
else
{
var process = Process.Start(fileName, command);
if (process.HasExited)
{
throw new Exception(string.Format("Process exited. Exit code: {0}", process.ExitCode));
}
}
}
}
My batch file
@echo off
echo Deleting existing mappings...
net use z: /delete /yes
echo Mapping network drives...
net use z: \\company-filestore\Selenium /user:company-filestore\Automation Selen1um
z:
cd "Hub and Node Executables"
echo Copying latest Selenium jars...
xcopy "z:\Hub and Node Executables" "C:\Selenium\" /R /Y /S /Z
echo Finished copying latest Selenium jars...
echo All done
Upvotes: 0
Views: 437
Reputation: 11
Have you tested placing the batch file in the same folder where the Windows Forms exe is available? Have you tried running the windows forms app with Admin rights? Just to knockout the possibility of insufficient permissions.
have you also verified the user context with which the code is executed and if the folder has permissions for the user context?
Upvotes: 0
Reputation: 106
The issue in winforms app (although, there was never any issue in console app using the same code) was being caused by a bug in xcopy in that when you redirect its output you need to redirect its input as well. So, adding this line to the ProcessInfo object in my code, fixed the issue.
RedirectStandardInput = true
More information on the issue is here: https://social.msdn.microsoft.com/Forums/vstudio/en-US/ab3c0cc7-83c2-4a86-9188-40588b7d1a52/processstart-of-xcopy-only-works-under-the-debugger?forum=netfxbcl
Hope this helps someone.
Upvotes: 2