以程序方式调用批处理文件时输出不正确
本文关键字:输出 不正确 批处理文件 调用 程序 方式 | 更新日期: 2023-09-27 18:30:07
我试图为我的产品自动安装服务器补丁,我了解了Wix Toolset。我希望在我的安装程序中获得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);
}
}
我也尝试过其他方法。切换上面函数的注释代码就是其中之一。
从代码级进行输出获取
调用"D:''Servers''VA''XYZ''JBoss-7.1.1-Final''bin''standalone.conf.bat
从cmd 手动运行相同命令时输出
调用D:''Servers''VA''XYZ''JBoss-7.1.1-最终''bin''standalone.conf.bat
======================================================================JBoss引导环境
JBOSS_HOME:D:''Servers''VA''XYZ''JBOSS-7.1.1-最终
JAVA:C:''Program Files''JAVA''jdk1.7.0_67''bin''JAVA
JAVA_OPTS
======================================================================正在侦听地址为8787 的传输dt_socket
19:08:0833 INFO[org.jboss.modules]jboss modules 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();
}
我发现我正在做
procStartInfo.UseShellExecute=true;
procStartInfo.RedirectStandardOutput=true
它给出了第一行输出。不知道为什么?。如果有人对此有任何想法,请解释。
感谢