简体   繁体   English

为什么从Windows Forms应用程序调用批处理文件时不复制文件,而在Console应用程序中却可以工作?

[英]Why does the batch file not copy files when invoked from Windows Forms app but it works from Console app?

I have a Console app and a Winforms app that do the same. 我有一个控制台应用程序和一个Winforms应用程序都执行相同的操作。 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 . CopyRequiredFile启动Windows批处理文件,该文件使用xcopy将文件从网络文件夹复制到本地驱动器 But, when called from the Windows Forms app it doesn't copy the files . 但是, 当从Windows Forms应用程序调用时,它不会复制文件

I am a novice developer trying to develop framework and some internal tools for UI automation. 我是一名新手开发人员,尝试开发UI自动化的框架和一些内部工具。

Why does it work to copy the files when I invoke the functionality from the Console application, but not from the Windows Forms Application? 当我从控制台应用程序而不是Windows窗体应用程序调用功能时,为什么复制文件有效?

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. 我的Windows窗体应用程序:仅与此问题相关的代码。

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. InvokeEx是一种扩展方法,可以在需要时调用操作。 Help from stackoverflow! 来自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/ 因此,请在此处查看输出图像: 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. Helpers类代码 如果问题中不需要此代码,请告诉我。

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

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. Winforms应用程序中的问题(尽管使用相同代码的控制台应用程序中从来没有任何问题)是由xcopy中的错误引起的,因为当您重定向其输出时,您也需要重定向其输入。 So, adding this line to the ProcessInfo object in my code, fixed the issue. 因此,将此行添加到我的代码中的ProcessInfo对象中,可以解决此问题。

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 有关此问题的更多信息,请参见: 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. 希望这对某人有帮助。

Have you tested placing the batch file in the same folder where the Windows Forms exe is available? 您是否测试过将批处理文件放置在Windows Forms exe可用的同一文件夹中? Have you tried running the windows forms app with Admin rights? 您是否尝试过以管理员权限运行Windows窗体应用程序? 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? 您是否还验证了执行代码所使用的用户上下文,以及该文件夹是否具有该用户上下文的权限?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Windows 窗体应用程序中将数据从一个 OleDb 数据库复制到另一个数据库 - Copy data from one OleDb database to another in Windows Forms App 当我从控制台应用程序打开它时,为什么我的 Windows 窗体布局会发生变化? - Why does my Windows-Forms Layout change, when I am opening it from a Console-Application? 从任务计划程序运行时,Windows服务器上的计划的C#控制台应用程序不显示控制台 - Scheduled c# console app on windows server does not show console when ran from task scheduler 控制台应用程序能否知道已从批处理文件中调用它? - Can a Console App know it has been called from a batch file? 从控制台运行批处理文件时,为什么UNC路径不起作用? - Why does the UNC pathway not work when running batch file from console? 从 Windows Forms 应用程序执行批处理文件 - Executing a batch file from Windows Forms application 从C#控制台应用程序调用PowerShell脚本时,GetFileDropList为空 - GetFileDropList is empty in when PowerShell script invoked from C# console app 从Windows XAML应用运行控制台应用 - Run console app from Windows XAML app 为什么我的受 AAD 保护的 Azure Function 使用来自 UWP 应用程序的访问令牌调用时返回 401? - Why does my AAD-protected Azure Function returns 401 when invoked with an access token from a UWP app? SQLite ExecuteReader可从Console和Forms Apps运行,但不能从Windows Service运行 - SQLite ExecuteReader works from Console and Forms Apps but not from Windows Service
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM