Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以编程方式调用批处理文件时输出不正确_C#_Batch File_Jboss_Cmd_Wix - Fatal编程技术网

C# 以编程方式调用批处理文件时输出不正确

C# 以编程方式调用批处理文件时输出不正确,c#,batch-file,jboss,cmd,wix,C#,Batch File,Jboss,Cmd,Wix,我试图为我的产品自动安装服务器补丁,我开始了解Wix工具集。 我希望在我的安装程序中得到JBoss版本。从cmd获得相同的命令是standalone.bat--version。 因此,从我的安装程序中,我创建了一个CustomAction,试图在其中运行它并获得输出 public static string runRunnableBatch(string path){ Process exploitVersionService = new Process(); string ru

我试图为我的产品自动安装服务器补丁,我开始了解Wix工具集。 我希望在我的安装程序中得到JBoss版本。从cmd获得相同的命令是
standalone.bat--version
。 因此,从我的安装程序中,我创建了一个CustomAction,试图在其中运行它并获得输出

public static string runRunnableBatch(string path){
    Process exploitVersionService = new Process();
    string runnableBinPath = path;
    exploitVersionService.StartInfo.WorkingDirectory = path + "bin";
    exploitVersionService.StartInfo.FileName = path + "bin\\standalone.bat";
    exploitVersionService.StartInfo.CreateNoWindow = false;
    exploitVersionService.StartInfo.Arguments = string.Format("--version");
    exploitVersionService.StartInfo.UseShellExecute = false;
    exploitVersionService.StartInfo.RedirectStandardOutput = true;
    exploitVersionService.StartInfo.RedirectStandardInput = false;
    exploitVersionService.Start();
    exploitVersionService.WaitForExit();
    // /*
    string opt = "";
    while (!exploitVersionService.StandardOutput.EndOfStream){
        opt += exploitVersionService.StandardOutput.ReadLine();
    }
    // */
    //using (StreamWriter writer = new StreamWriter("D:\\_log.txt"))
    //using (StreamReader reader = exploitVersionService.StandardOutput){
    //    writer.AutoFlush = true;
    //    for (; ; ){
    //        string textLine = reader.ReadLine();
    //        if (textLine == null)
    //            break;
    //        writer.WriteLine(textLine);
    //    }
    //}
    //StreamReader exploitVersionFeed = exploitVersionService.StandardOutput;
    //string output = exploitVersionFeed.ReadToEnd();
    return opt;
}
当我这样做时,作为输出得到的只是整个输出字符串的第一行

我需要代码中的整个字符串,以便从正则表达式中提取版本

也试过了

public static string runRunnableBatch(string path){
    string executableBinPath = path + "bin";
    string executableBinPath_BatchCmd = "cd " + "\"" + executableBinPath + "\"";
    string outputFileName = "TempVerInfoHolder.txt";
    string outputFilePath = executableBinPath+@"\TempVerInfoHolder1.txt";
    string versionRetriever_BatchCmd = @"standalone.bat --version > " + "\""+outputFilePath+"\"";
    string partitionName_BatchCmd = @Strings.Utils.getPartitionFromPath(path);

    // Creating command sequence
    SortedList<int, string> commandSequence = new SortedList<int, string>();

    // ~ d:
    commandSequence.Add(1, partitionName_BatchCmd);
    // ~ cd %path%
    commandSequence.Add(2, executableBinPath_BatchCmd);
    // ~ standalone.bat --version > %filename%
    commandSequence.Add(3, versionRetriever_BatchCmd);
    runCommandFromSequence(commandSequence);

    // Run together

    return "";
}

private static void runCommandFromSequence(SortedList<int, string> commandSequence){
    Process seqCmdExecHost = new Process();

    ProcessStartInfo psi = new ProcessStartInfo();
    psi.FileName = "cmd.exe";
    psi.RedirectStandardInput = true;
    psi.RedirectStandardOutput = true;
    psi.UseShellExecute = false;
    psi.CreateNoWindow = false;

    seqCmdExecHost.StartInfo = psi;
    seqCmdExecHost.Start();

    using (StreamWriter writer = seqCmdExecHost.StandardInput) {
        if (writer.BaseStream.CanWrite) {
            foreach (int item in commandSequence.Keys){
                MessageBox.Show(seqCmdExecHost.Id.ToString());
                MessageBox.Show(commandSequence[item]);
                writer.WriteLine(commandSequence[item]);   
            }
        }

        string opt = "";
        while (!seqCmdExecHost.StandardOutput.EndOfStream){
            opt += seqCmdExecHost.StandardOutput.ReadLine();
        }
    MessageBox.Show("Exited? " + seqCmdExecHost.HasExited);
    MessageBox.Show("O/P? " + opt);
    }
}
公共静态字符串runnablebatch(字符串路径){
字符串executableBinPath=路径+“bin”;
字符串executableBinPath\u BatchCmd=“cd”+“\”“+executableBinPath+”\”;
字符串outputFileName=“tempverinfo.txt”;
字符串outputFilePath=executableBinPath+@“\TempVerInfoHolder1.txt”;
字符串versionRetriever\u BatchCmd=@“standalone.bat--version>“+”\”+输出文件路径+“\”;
string partitionName_BatchCmd=@Strings.Utils.getPartitionFromPath(path);
//创建命令序列
SortedList commandSequence=新的SortedList();
//~d:
Add(1,partitionName\u BatchCmd);
//~cd%路径%
Add(2,executableBinPath_BatchCmd);
//~standalone.bat--版本>%filename%
Add(3,versionRetriever\u BatchCmd);
runCommandFromSequence(commandSequence);
//一起跑
返回“”;
}
私有静态无效runCommandFromSequence(SortedList commandSequence){
Process seqCmdExecHost=新流程();
ProcessStartInfo psi=新的ProcessStartInfo();
psi.FileName=“cmd.exe”;
psi.INPUT=真;
psi.0输出=真;
psi.UseShellExecute=false;
psi.CreateNoWindow=假;
seqCmdExecHost.StartInfo=psi;
seqCmdExecHost.Start();
使用(StreamWriter writer=seqCmdExecHost.StandardInput){
if(writer.BaseStream.CanWrite){
foreach(commandSequence.Keys中的int项){
Show(seqCmdExecHost.Id.ToString());
MessageBox.Show(commandSequence[item]);
writer.WriteLine(commandSequence[项目]);
}
}
字符串opt=“”;
而(!seqCmdExecHost.StandardOutput.EndOfStream){
opt+=seqCmdExecHost.StandardOutput.ReadLine();
}
MessageBox.Show(“已退出?”+seqCmdExecHost.hasExit);
MessageBox.Show(“O/P?”+opt);
}
}
我也尝试过其他方法。切换上述函数的注释代码就是其中之一

从代码级别执行时获取输出

调用“D:\Servers\VA\XYZ\JBoss-7.1.1-Final\bin\standalone.conf.bat

从cmd手动运行同一命令时输出

调用D:\Servers\VA\XYZ\JBoss-7.1.1-Final\bin\standalone.conf.bat

====================================================================== JBoss引导环境

JBOSS_HOME:D:\Servers\VA\XYZ\JBOSS-7.1.1-Final

JAVA:C:\ProgramFiles\JAVA\jdk1.7.0\U 67\bin\JAVA

JAVA_选项

====================================================================== 正在侦听地址为8787的传输dt_套接字

19:08:08333信息[org.jboss.modules]jboss模块版本1.1.1.GA

JBoss AS 7.1.1.最终版本“Brontes”

按任意键继续

我的观察是,一旦从standalone.bat调用嵌套的standalone.conf.bat,流就会关闭

如果有任何解决方法可以获得字符串/缓冲区/流的完整输出,将不胜感激


谢谢

您可以调用命令行应用程序,而不是调用批处理文件

exploitVersionService.StartInfo.WorkingDirectory = path + "bin";
exploitVersionService.StartInfo.FileName = "cmd.exe";
exploitVersionService.StartInfo.CreateNoWindow = false;
exploitVersionService.StartInfo.Arguments = string.Format(" /c \"{0}\" --version",path + "bin\\standalone.bat");

我找到了一个方法来实现这一点。 我以编程方式创建了批处理文件,并使用cmd运行它

public static void createBatchToGetVersion(string path)
            {
                CustomLogger.getInstance().debug("Started creating batch file");
                BatchOps.executableBinPath = path + "bin";
                CustomLogger.getInstance().debug("Ëxecutable bin path: " + BatchOps.executableBinPath);
                BatchOps.tempBatchFileName = "JBossVerCmd.bat";
                BatchOps.holderFileName = @"JBossVerHolder.txt";
                BatchOps.absoluteHolderPath = Strings.Utils.normalize(executableBinPath) + holderFileName;
                CustomLogger.getInstance().debug("Normalized absoluteHolderPath: " + BatchOps.absoluteHolderPath);

                CustomLogger.getInstance().debug("Checking if JBOSS_HOME entered by user actuallty points to JBOSS");
                if (!File.Exists(Strings.Utils.normalize(executableBinPath) + "standalone.bat"))
                {
                    CustomLogger.getInstance().error("standalone.bat not found. JBOSS_HOME Dir is not correctly entered");
                    throw new CustomExceptions.DirectoryNotAcceptableException("Bad directory is assigned to JBOSS_HOME or JBOSS_HOME structure corrupted");
                }

                /*
                 * Batch file formation.
                 * Contains:
                 * Start file
                 * D:
                 * cd D:\Fusion Server\jboss 7.1.1\bin
                 * @echo | call standalone.bat --version > sample.txt   
                 * @echo Done
                 * End file
                 * @echo is required here because it exits the cmd when completed whithout having the user pressing any key
                */
                string changePartition_cmd = Strings.Utils.getPartitionFromPath(path);
                string changeDirectory_cmd = @"cd " + BatchOps.executableBinPath;
                string getVersion_cmd = @"@echo | call standalone.bat --version > " + holderFileName;
                string exitCmd = @"@echo Done";

                CustomLogger.getInstance().debug("Command to be written on batch file");
                CustomLogger.getInstance().debug("\r\n" + changePartition_cmd + "\r\n" + changeDirectory_cmd + "\r\n" + getVersion_cmd + "\r\n" + exitCmd);

                SortedList<int, string> commandSequence = new SortedList<int, string>();
                CustomLogger.getInstance().debug("Initializing command sequence.");
                commandSequence.Add(1, changePartition_cmd);
                commandSequence.Add(2, changeDirectory_cmd);
                commandSequence.Add(3, getVersion_cmd);
                commandSequence.Add(4, exitCmd);

                // Will create one if file never existed and open one delete the content and set the pointer to the begnning
                // if already existed
                StreamWriter batchFileWriter = null;
                try
                {
                    CustomLogger.getInstance().debug("Establishing stream to and from temp batch file");
                    batchFileWriter = new StreamWriter(tempBatchFileName);
                    CustomLogger.getInstance().debug("Command sequence ready to be written on temp batch file.");
                    Perform.writeToStreamFromSequence(batchFileWriter, commandSequence);
                    CustomLogger.getInstance().debug("Command sequence successfully written");
                }
                catch (IOException ex)
                {
                    CustomLogger.getInstance().error("Error while writing command sequence.\n" + ex.ToString());
                    // throw exception to CustomAction
                    throw new IOException("Error while writing commandSequence");

                }
                finally
                {
                    // Not required. Stream already closed in writeToStreamFromSequence
                }
            }


            public static void runTempBatchFile()
            {
                Process seqCmdExecHost = new Process();
                ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", @"/c " + BatchOps.tempBatchFileName);
                procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                seqCmdExecHost.StartInfo = procStartInfo;
                seqCmdExecHost.Start();
                seqCmdExecHost.WaitForExit();
                seqCmdExecHost.Close();
            }
它给出了第一行输出。不知道为什么?如果有人对此有任何想法,请解释


谢谢

您是否正在尝试从批处理文件中检索整个输出是。完全是。Util JBoss显示版本信息并退出JVM的时刻。是否没有更直接的方法来检测JBoss的版本?注册表值或EXE/DLL版本?
procStartInfo.UseShellExecute=true;
procStartInfo.RedirectStandardOutput=true