im trying to invoke a batch file from java code. I have tried answers from the SO forum.
File ff = new File(".");
String pt = ff.getCanonicalPath()+"\\Selenium APIs";
String pt1 = ff.getCanonicalPath()+"\\Selenium APIs\\Start Selenium Server.bat";
String[] command = {"cmd.exe", "/C", "Start", pt1};`enter code here`
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
when executed a cmd opens with the path name, but content of batch file is not executed.
Try this (set timeout according to your requirements):
...
String[] command = new String[]{"cmd", "/c", pt1};
Process process = Runtime.getRuntime().exec(command);
Timer timer = new Timer();
timer.schedule(new InterruptScheduler(Thread.currentThread()), 60000);
try {
process.waitFor();
} catch (InterruptedException e) {
process.destroy();
throw new TimeoutException("Command not terminated in 60 sec");
} finally {
timer.cancel();
}
Related
After seeing a youtube video I tested this code:
string cmd1 = #"xcopy c:\A\*.* c:\b";
Process ps = new Process();
ps.StartInfo.FileName = "cmd.exe";
ps.StartInfo.CreateNoWindow = true;
ps.StartInfo.RedirectStandardInput = true;
ps.StartInfo.RedirectStandardOutput = true;
ps.StartInfo.UseShellExecute = false;
ps.Start();
ps.StandardInput.WriteLine(cmd1);
ps.StandardInput.Flush();
ps.StandardInput.Close();
ps.WaitForExit();
Console.WriteLine(ps.StandardOutput.ReadToEnd());
The command is executed but i see no output.
What do i need to do to make visible the cmd window and the command output?
Thanks
If you want to execute your command in the cmd.exe window, you can do it like this.
var process = new Process();
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = #"/K xcopy c:\A\*.* c:\b"
};
process.StartInfo = startInfo;
process.Start();
Note that /K keeps the command line window open, replace it with /C to automatically close it after copying.
If you want to start xcopy without showing the console window and collecting the output to show it where you want, use this.
var process = new Process();
var startInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "xcopy",
Arguments = #"c:\A\*.* c:\b",
RedirectStandardOutput = true
};
process.StartInfo = startInfo;
process.Start();
var output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
// Print the output to Standard Out
Console.WriteLine(output);
// Print the ouput to e.g. Visual Studio debug window
Debug.WriteLine(output);
Note that this only works as expected, if your B folder exists folder does not already contain any of your files. Otherwise, the window will stay open, because you are asked, whether the directory should be created and the files should be overwritten. To not overcomplicate this by writing input, you could use the following arguments for xcopy.
Arguments = #"c:\A\*.* c:\b\ /Y /I"
The /Y switch will overwrite files without asking and /I will create a non-existing directory. It is mandatory for this to work to have a trailing backslash on your destination directory path (c:\b\ instead of c:\b).
I have a console application which generating rows line by line:
Data1
Data2
Data3
...
and when its over command line will be cleared, it reapeats infinitelly (the datas can change)
I have to watch the console application's command line with windows aplication real time and work for the lines data (for example save it to list ox line by line)! It is possible?
You basically need to subscribe to the output streams of that console application, to be able to get each line printed on the console.
What you need to do is to create the Windows Forms application (WPF would also work) and start the console application from there.
If you don't want to show your current console application as a visible window, remember to set CreateNoWindow to true.
Here's how to start the console application:
var processStartInfo = new ProcessStartInfo(fileName, arguments);
processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;
processStartInfo.RedirectStandardOutput = true; // We handle the output
processStartInfo.CreateNoWindow = true; // If you want to hide the console application so it only works in the background.
// Create the actual process
currentProcess = new Process();
currentProcess.EnableRaisingEvents = true;
currentProcess.StartInfo = processStartInfo;
// Start the process
bool processDidStart = currentProcess.Start();
We need a BackgroundWorker to read the output from the console application in the background.
outputReader = TextReader.Synchronized(currentProcess.StandardOutput);
outputWorker.RunWorkerAsync();
Now you're able to get all the output from the console application in real time and use it to create a list or whatever you want to.
void outputWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Work until cancelled
while (outputWorker.CancellationPending == false)
{
int count = 0;
char[] buffer = new char[1024];
do
{
StringBuilder builder = new StringBuilder();
// Read the data from the buffer and append to the StringBuilder
count = outputReader.Read(buffer, 0, 1024);
builder.Append(buffer, 0, count);
outputWorker.ReportProgress(0, new OutputEvent() { Output = builder.ToString() });
} while (count > 0);
}
}
The processed data is available through the ProgressChanged event of the BackgroundWorker.
void outputWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.UserState is OutputEvent)
{
var outputEvent = e.UserState as OutputEvent;
/* HERE YOU CAN USE THE OUTPUT LIKE THIS:
* outputEvent.Output
*
* FOR EXAMPLE:
* yourList.Add(outputEvent.Output);
*/
}
}
The above code is taken and modified to your purposes from the following Codeproject.com article in case it ceases to exist in the future: Embedding a Console in a C# Application.
I'm using the following code to download the source code of an HTML page
String search = $"<search url>";
String result = "";
using (WebClient wc = new WebClient())
{
var searchURL = new Uri(search);
wc.DownloadStringCompleted += (s, e) =>
{
result = e.Result;
};
wc.DownloadStringAsync(searchURL);
}
return result.Trim();
This exists in a static method
public static Scrape(String arg)
of a class Scraper.
However, when I do
txtResult.Text = Scraper.Scrape(arg);
in the code behing of a form, nothing appears. Using breakpoints, I see that e.Result indeed contains the expected data, but something happens and the data is "lost" in the way. Anyone has any idea what I'm missing;
Because the download is asynchronous it hasn't updated the value of result before you reach the line return "result.Trim()" as a result you are returning the empty string.
You need to wait for WC to complete, if you use the task method then accessing the result property will cause you to wait for the response.
String search = $"<search url>";
String result = "";
using (WebClient wc = new WebClient())
{
var searchURL = new Uri(search);
result = wc.DownloadStringTaskAsync(searchURL).Result;
}
return result.Trim();
However if you do this in the current method as it stands you will end up hanging your UI as the wait happens on the foreground thread.
You can move the update to the background by changing your call to use a task with a continuation.
Instead of
txtResult.Text = Scraper.Scrape(arg);
Add a using using System.Threading.Tasks;
then you can use the line
Task.Run(() => Scraper.Scrape(arg))
.ContinueWith(t => txtResult.Text = t.Result,
TaskScheduler.FromCurrentSynchronizationContext());
You may also want to precede this with a line txtResult.Text = "Please Wait Fetching....";
I'm using JavaMail Library to parser email mime message.
I'm trying to extract the attached files and save them to the local disk but the saved files are not valid and their size is different from the original. only *.txt file are saved ok but *.PDF or *.xlsx are not.
Can you please help me to fix the code?
My code is:
private static void Test3() {
String email_string = File_Reader.Read_File_To_String("D:\\8.txt");
MimeMessage mm = Email_Parser.Get_MIME_Message_From_Email_String(email_string);
Email_Parser.Save_Email_Attachments_To_Folder(mm,"D:\\TEST");
}
public static String Read_File_To_String(String file_path) {
byte[] encoded = new byte[0];
try {
encoded = Files.readAllBytes(Paths.get(file_path));
} catch (IOException exception) {
Print_To_Console(exception.getMessage(), true,false);
}
return new String(encoded, m_encoding);
}
public static MimeMessage Get_MIME_Message_From_Email_String(String email_string) {
MimeMessage mm = null;
try {
Session s = Session.getDefaultInstance(new Properties());
InputStream is = new ByteArrayInputStream(email_string.getBytes());
mm = new MimeMessage(s, is);
} catch (MessagingException exception) {
Print_To_Console(exception.getMessage(), true, false);
}
return mm;
}
public static void Save_Email_Attachments_To_Folder(MimeMessage mm, String output_folder_path) {
ArrayList<Pair<String, InputStream>> attachments_InputStreams = Get_Attachments_InputStream_From_MimeMessage(mm);
String attachment_filename;
String attachment_filename_save_path;
InputStream attachment_InputStream;
MimeBodyPart mbp;
for (Pair<String, InputStream> attachments_InputStream : attachments_InputStreams) {
attachment_filename = attachments_InputStream.getKey();
attachment_filename = Get_Encoded_String(attachment_filename);
attachment_filename_save_path = String.format("%s\\%s", output_folder_path, attachment_filename);
attachment_InputStream = attachments_InputStream.getValue();
try {
mbp = new MimeBodyPart(attachment_InputStream);
mbp.saveFile(attachment_filename_save_path);
} catch (MessagingException | IOException exception) {
Print_To_Console(exception.getMessage(), true, false);
}
}
}
You're doing something very strange in Save_Email_Attachments_To_Folder. (Not to mention the strange naming convention using both camel case and underscores. :-)) I don't know what the InputStreams are you're collecting, but constructing new MimeBodyParts based on them and then using the new MimeBodyPart to save the attachment to the file is almost certainly not what you want to do.
What exactly is Get_Attachments_InputStream_From_MimeMessage doing? Why iterate over the message to collect a bunch of InputStreams, then iterate over the InputStreams to save them? Why not iterate over the message to find the attachments and save them as you find them using the MimeBodyPart.saveFile method? Have you seen the msgshow.java sample program?
I am trying to get a background worker process working in a wpf application. it creates 2 files then crashes.
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
CreateFile(i.ToString());
};
worker.RunWorkerAsync();
private void CreateFile(string fileName)
{
string path = string.Format(#"{0}\{1}.txt", directory, fileName);
using (StreamWriter sw = new StreamWriter(path))
{
sw.WriteLine(fileName);
}
}
I get this error "
The requested operation cannot be performed on a file with a user-mapped section open." what am I doing wrong?
Any help would be great
Another process has the file open, e.g., an antivirus program or WordPad. You can use Process Monitor to see which process it is.