C# How to get full path of network file? - c#

This program is ran from the context menu after right clicking on a pdf file, it simply adds "\ CALL OFF" to the selected file, locally the program works fine, even with spaces. When ran on a file on my nas in which the path contains spaces the output from GetCommandLineArgs stops at the first space.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] args = System.Environment.GetCommandLineArgs();
textBox1.Text = args[1];
}
private void button2_Click(object sender, EventArgs e)
{
ProcessStartInfo start = new ProcessStartInfo();
start.Arguments = "-add-text \"/ CALL OFF\" -font \"Helvetica-Bold\" -font-size 14 -pos-left \"194 776\" " + textBox1.Text + " -o out.pdf";
start.FileName = "cpdf";
Process.Start(start);
}
}

String Join all the command line arguments back together, using space as separator, into one string and use that as the argument. You'll also need to add double-quotes around the textBox1.Text when used in start.Arguments to ensure it is received as one:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] args = System.Environment.GetCommandLineArgs().Skip(1).ToArray();
textBox1.Text = String.Join(" ", args);
}
private void button2_Click(object sender, EventArgs e)
{
ProcessStartInfo start = new ProcessStartInfo();
start.Arguments = "-add-text \"/ CALL OFF\" -font \"Helvetica-Bold\" -font-size 14 -pos-left \"194 776\" "
+ "\"" + textBox1.Text + "\"" + " -o out.pdf";
start.FileName = "cpdf";
Process.Start(start);
}
}

You need to enclose the path name in quotes, you add \":
string quoted = "\"" + textBox1.Text + "\"";
to get:
start.Arguments = "-add-text \"/ CALL OFF\" -font \"Helvetica-Bold\" -font-size 14 -pos-left \"194 776\" \"" + textBox1.Text + "\" -o out.pdf";
If you are passing it as a command line argument to the program then you need to quote it there as well:
myExe -file "Long path with spaces\file.pdf"

Related

Create a 7zip file for every subdirectory to a output path from input path in winforms

I have an input path that contains an unknown number of
subdirectories.
I want to use 7zip to zip each of them and the zip file will be in the selected output path.
Below is the concept of this program.
Below is the 7zip code I try to achieve the result, but no idea how to do.
string source = textBoxInput.Text + "\\*";
string target = Path.Combine(tBoxOutput.Text, source + DateTime.Now.ToString());
foreach (var folder in Directory.GetDirectories(source))
{
_sevenZip.CreateZipFile(folder, target);
}
Below is the 7z in command line I use to this program.
try
{
ProcessStartInfo zipProcess = new ProcessStartInfo();
zipProcess.FileName = #"E:\Program Files\7-Zip\7z.exe";
zipProcess.Arguments = "a -t7z \"" + targetName + "\" \"" + sourceName + "\" -mx=9";
zipProcess.WindowStyle = ProcessWindowStyle.Minimized;
Process zip = Process.Start(zipProcess);
zip.WaitForExit();
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
I remember helping you once with that question , i guess my answer was not to your satisfaction,
I've tried better this time:
this is the window:
these are the folders I used, just like in your example:
'choose source' and 'choose target' button opens a folder dialog
you were in the right direction, a for loop that runs over the subdirectories. i guess the hard part was getting the correct names. you just need to make sure that the target name would have a ".7z" extension.
and the code is fairly simple:
string zipProgramPath = #"C:\Program Files\7-Zip\7z.exe";
public Form1()
{
InitializeComponent();
}
public void CreateZipFile(string sourceName, string targetName)
{
try
{
ProcessStartInfo zipProcess = new ProcessStartInfo();
zipProcess.FileName = zipProgramPath; // select the 7zip program to start
zipProcess.Arguments = "a -t7z \"" + targetName + "\" \"" + sourceName + "\" -mx=9";
zipProcess.WindowStyle = ProcessWindowStyle.Minimized;
zipProcess.UseShellExecute = true;
Process zip = Process.Start(zipProcess);
zip.WaitForExit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void btnBrowseSource_Click(object sender, EventArgs e)
{
using (var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
lblSource.Text = fbd.SelectedPath; //label next to the button
}
}
}
private void btnBrowseTarget_Click(object sender, EventArgs e)
{
using (var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
lblTarget.Text = fbd.SelectedPath.ToString(); //label next to the button
}
}
}
private void btnExecute_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(lblSource.Text) || string.IsNullOrEmpty(lblTarget.Text))
{
MessageBox.Show("Choose input directory and output directory");
}
else
{
foreach (var folder in Directory.GetDirectories(lblSource.Text))
{
string folderName= Path.GetFileName(folder);
string targetName = Path.Combine(lblTarget.Text, folderName+ ".7z" );
CreateZipFile(folder, targetName);
}
}
}
so after choosing the right directories, and pressing execute
the result is as required :
Here is the PowerShell script will do the same. SourceFolders will have your test, test1, test2 folders. Compressed files will gets stored into C:\DestinationFolder. You just have run this script from PowerShell command prompt.
Import-Module Microsoft.PowerShell.Management
$sourcefolders = Get-ChildItem "C:\SourceFolders"
$outputfolder = "C:\DestinationFolder"
for ($i=0; $i -lt $sourcefolders.Count; $i++) {
$folderPathToCompress = $sourcefolders[$i].FullName
$compressFileName = $sourcefolders[$i].Name
"Compressing folder ="+$folderPathToCompress;
.\7z a -t7z $outputfolder\$compressFileName".7z" $folderPathToCompress
}

Running batch file

I have been working on a manager application for a Minecraft server, when I run my program, the console shows and disappears, if I run it manually, it runs without and problems. My code:
Process process = new Process
{
StartInfo =
{
FileName = textBox2.Text,
//Arguments = textBox3.Text,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false,
}
};
process.OutputDataReceived += new DataReceivedEventHandler(server_outputDataReceived);
server = process;
process.Start();
Batch file code (idk what language are batch files, so I used default one - Select Language):
java -Xmx1024M -jar craftbukkit-1.7.2-R0.3.jar -o false
BTW. Can you start processes without creating files ? (ex. Start process "java -jar example", without creating file) ?
#Edit Answer to the third question: Answer to the third question
My full code (MessageBoxes are in Polish, becouse im from Poland, but later i will add support for other languages):
using System;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Process server;
private Boolean runServer()
{
if (!File.Exists(textBox2.Text))
{
MessageBox.Show("Brak określonej ścieżki dostępu! (" + textBox2.Text + ")", "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
Process process = new Process
{
StartInfo =
{
FileName = textBox2.Text,
//Arguments = textBox3.Text,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false,
}
};
process.OutputDataReceived += new DataReceivedEventHandler(server_outputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(server_outputDataReceived);
server = process;
if (process.Start())
return true;
else
{
MessageBox.Show("Nie można włączyć serwera!", "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
private String ReadFile(String filename, int line)
{
StreamReader reader = new StreamReader(filename);
for (int i = 0; i < line; i++)
{
reader.ReadLine();
}
return reader.ReadLine();
}
private void ReloadOPs()
{
if (!File.Exists(textBox1.Text))
{
MessageBox.Show("Sciezka dostępu do pliku z listą graczy posiadających OP nie istnieje! (" + textBox1.Text + ")", "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
tabControl1.SelectedTab = tabPageOptions;
textBox1.SelectAll();
return;
}
String line = ReadFile(textBox1.Text, 0);
comboBox1.Items.Clear();
for (int i = 1; i < File.ReadAllLines(textBox1.Text).Length; i++)
{
if (!String.IsNullOrWhiteSpace(ReadFile(textBox1.Text, i)))
{
comboBox1.Items.Add(line);
line = ReadFile(textBox1.Text, i);
}
}
MessageBox.Show("Lista graczy z OP, została odświeżona.");
}
// OPs combobox (OPs)
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
groupBox1.Text = comboBox1.SelectedItem.ToString();
groupBox1.Visible = true;
}
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = Application.StartupPath.ToString() + #"\ops.txt";
ReloadOPs();
}
// Reload OPs button (OPs)
private void button1_Click(object sender, EventArgs e)
{
ReloadOPs();
}
// Save button (Options)
private void button4_Click(object sender, EventArgs e)
{
}
private void server_outputDataReceived(object sender, DataReceivedEventArgs e)
{
addConsoleMessage(e.Data.ToString(), true);
}
// Run server button (Menu)
private void button5_Click(object sender, EventArgs e)
{
if (!runServer())
return;
server.BeginOutputReadLine();
button6.Enabled = true;
}
// Stop server button (Menu)
private void button6_Click(object sender, EventArgs e)
{
if(!server.HasExited)
server.Kill();
button6.Enabled = false;
}
private void addConsoleMessage(String message, Boolean refresh)
{
listBox1.Items.Add(message);
if (refresh)
listBox1.Refresh();
}
}
}
Works now, but after second message that batch file returned (?), program crashes becouse InvaildOperationException was unhandled.
Ok. Let's clarify some points. I assume you have a Batch file named filename.bat with this content:
java -Xmx1024M -jar craftbukkit-1.7.2-R0.3.jar -o false
and with "run it manually" you mean you open a command-line window and enter: filename. Ok? However, you have NOT indicated how do you run your Batch file when NOT run it manually! If you double-click on it from the file browser, then your Batch file missing to change current directory to the one where the Batch file is:
cd "%~P0"
java -Xmx1024M -jar craftbukkit-1.7.2-R0.3.jar -o false
PS - Your Batch file should NOT be named start.bat because start is the name of an internal cmd.exe command!

How to run new process after the old process finish, without hang the application

I working on Visual Studio 2010, C# (.Net 4).
I have an application that contain a DataGridView with two columns. Each column contain argument for the program I want to run.
Now I want to run from my C# application another application with parameters from the data grid view.
In additional, I want to wait 3 seconds before running new process.
I try the follow code, but the process runs parallelly and not one after one:
private static Mutex mut = new Mutex();
public void runProgram(string executablePath, string argu1, string argu2)
{
mut.WaitOne();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = Path.GetDirectoryName(executablePath);
startInfo.FileName = "CMD.exe";
startInfo.Arguments = "/C " + set.ExecutablePath + " "
+ argu1 + " " + argu2;
try
{
Process p = Process.Start(startInfo);
//p.WaitForExit(); // don't start the next process until the first finish -> not good, stuck the app
}
catch
{
MessageBox.Show("ERROR: unsuccess to run the applicition");
}
mut.ReleaseMutex();
}
private void bu_RunProgram_Click(object sender, EventArgs e)
{
if (!File.Exists(set.ExecutablePath))
{
MessageBox.Show("The executable file doesn't exist\nPlease select right executable file in the settings form", "Error");
return;
}
int progRow;
foreach (DataGridViewRow dgvr in dg_ParametersToRun.Rows)
{
progRow = dgvr.Index;
string argu1 = dg_ParametersToRun.Rows[progRow].Cells[0].FormattedValue.ToString();
string argu2 = dg_ParametersToRun.Rows[progRow].Cells[1].FormattedValue.ToString();
Thread threadProgRun= new Thread(() => runProgram(set.ExecutablePath, argu1, argu2));
threadProgRun.Start();
Thread.Sleep(3000); // Need to come to this line only when the previous thread finish...
}
}
To be honest, I've never worked with threads..
Thank you!
UPDATE CODE (According the suggestion):
// Aid variable
int paramRowIndex;
public void runNextParameters(object sender, EventArgs e)
{
paramRowIndex++;
if (paramRowIndex > dg_RunListTests.Rows.Count) return; finish run all parameters
//run the test
string argu1 = dg_RunListTests.Rows[paramRowIndex].Cells[0].FormattedValue.ToString();
string argu2 = dg_RunListTests.Rows[paramRowIndex].Cells[1].FormattedValue.ToString();
runParameters(set.ExecutablePath, componenet, test);
}
public void runParameters(string executablePath, string argu1, string argu2)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = Path.GetDirectoryName(executablePath);
startInfo.FileName = "CMD.exe";
startInfo.Arguments = "/C " + set.ExecutablePath + " "
+ argu1 + " " + argu2;
try
{
Process p = Process.Start(startInfo);
p.Exited += runNextParameters;
}
catch
{
MessageBox.Show("Unsuccess to run the test again");
}
}
private void bu_RunParameters_Click(object sender, EventArgs e)
{
if (!File.Exists(set.ExecutablePath))
{
MessageBox.Show("The executable file doesn't exist\nPlease select right executable file in the settings form", Error);
return;
}
paramRowIndex = 0;
runNextParameters(sender, e);
}
Possible fast solution: start a .bat file that starts the two(three) programs. You have to create another program that waits 3 seconds to call in between.

Expected behaviour with white space in the command line

I wrote a program that compiles my .cs files using csc.exe:
namespace myCompiler
{
public partial class Form1 : Form
{
string compilerFolder;
string outputFolder;
string projectFile;
string output = #" /out:";
public Form1()
{
InitializeComponent();
}
private void startCompile_Click(object sender, EventArgs e)
{
Compile();
}
public void findCompile_Click(object sender, EventArgs e)
{
DialogResult result1 = folderBrowserDialog1.ShowDialog();
compilerFolder = folderBrowserDialog1.SelectedPath;
MessageBox.Show(compilerFolder);
cscLabel.Text = compilerFolder;
}
private void outputCompile_Click(object sender, EventArgs e)
{
DialogResult result2 = folderBrowserDialog2.ShowDialog();
outputFolder = folderBrowserDialog2.SelectedPath;
outputLabel.Text = (outputFolder);
MessageBox.Show(outputFolder);
}
private void findProject_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
projectFile = openFileDialog1.FileName;
projectLabel.Text = (projectFile);
MessageBox.Show(projectFile);
}
}
public void Compile()
{
try
{
Process compile = new Process();
string outputExe = fileName.Text;
string compiler = compilerFolder + #"\csc.exe";
string arGs = output + outputFolder + #"\" + outputExe + " " + projectFile;
compile.StartInfo.FileName = (compiler);
compile.StartInfo.Arguments = (arGs);
compile.StartInfo.RedirectStandardOutput = true;
compile.StartInfo.UseShellExecute = false;
compile.Start();
string stdOutput = "";
while (!compile.HasExited)
{
stdOutput += compile.StandardOutput.ReadToEnd();
MessageBox.Show(stdOutput);
}
}
catch (Exception errorMsg)
{
MessageBox.Show(errorMsg.Message);
}
}
private void testButton_Click(object sender, EventArgs e)
{
MessageBox.Show(projectFile);
MessageBox.Show(compilerFolder);
}
}
}
The compile instruction runs but produces no results, just a quick flash of a black console screen.
Basically what seems to be happening, is when all the strings are parsed in the commandline as arguments for the process, the .cs project source directory is broken up by each white space ie c:\users\%username%\Documents\Visual Studio 2010\ is broken up as c:\users\%username%\Documents\Visual then Studio then 2010\Projects\Myproject\myproj.cs
and subsequently the compilation fails.
You need double quotes around a filepath with spaces in it.
See my edit to your code below.
public void Compile()
{
try
{
Process compile = new Process();
string outputExe = fileName.Text;
string compiler = compilerFolder + "\csc.exe";
// add double quotes around path with spaces in it.
string arGs = output + "\"" + outputFolder + "\"" + #"\" + outputExe + " " + projectFile;
compile.StartInfo.FileName = compiler;
compile.StartInfo.Arguments = arGs;
compile.StartInfo.RedirectStandardOutput = true;
compile.StartInfo.UseShellExecute = false;
compile.Start();
string stdOutput = "";
while (!compile.HasExited)
{
stdOutput += compile.StandardOutput.ReadToEnd();
MessageBox.Show(stdOutput);
}
}
catch (Exception errorMsg)
{
MessageBox.Show(errorMsg.Message);
}
}

c# taking multiple lines in a texbox and separating them

Hello i'm trying to write a program that takes 3 user inputs: file path, username, and computer name and then create a batch file for each computer name in the list. I have not written the create batch file part yet but I am having trouble taking the multiple computers from the computer text box and creating separate lines of code out of them.
So if there are 3 computer names inside the computer textbox, id like to when the user hits the button, output each computer name on a different line.
if the computer name textbox contained the following computer names: M22-LIBRL74258S, M22-LIBRL74257S, and M22-LIBRL74256S
the output would be :
XCOPY "C:\Documents and Settings\Administrator\Desktop\file.exe" "\M22-LIBRL74258S\c$\Users\username\desktop"
XCOPY "C:\Documents and Settings\Administrator\Desktop\file.exe" "\M22-LIBRL74257S\c$\Users\username\desktop"
XCOPY "C:\Documents and Settings\Administrator\Desktop\file.exe" "\M22-LIBRL74256S\c$\Users\username\desktop"
Thanks!
WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void browsebtn_Click(object sender, EventArgs e)
{
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Title = "Select a File to Send";
// Show the Dialog.
// If the user clicked OK in the dialog and
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
{
string strfilename = openFileDialog1.InitialDirectory + openFileDialog1.FileName;
pathtxt.Text = strfilename.ToString();
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void createbtn_Click(object sender, EventArgs e)
{
string filepath = pathtxt.Text.ToString();
string username = usertxtbox.Text.ToString();
string computer = computerstxtbox.Text;
string[] split = computer.Split(new char[] { '\n' });
foreach (string l in split)
{
var strIP = "XCOPY \"" + pathtxt.Text + '"' + ' ' + '"' + "\\" + "\\" + l + "\\" + "c$" + "\\" + "Users" + "\\" + username + "\\" + "desktop" + '"';
//This is to see it
MessageBox.Show(strIP);
}
Try and replace the line
string[] split = computer.Split(new char[] { '\n' });
with this instead
string[] split = computer.Split(new String[] {"\r\n"}, StringSplitOptions.None);
Also if your computer names are seperated by commas, you must also specify them in the split. e.g. new String[] {"\r\n", ","}

Categories

Resources