I've got a code to create a backup copy from a query, this query takes the older registers from a year in the past and saves them into a *.sql file. But the problem that I found is when I open the .sql file and it's empty. I've tried the query in command prompt and it works perfectly.
I'm new using mysql and I have read these posts to create my code (and looking for answers):
Backing up Database in MySQL using C#
C# and mysqldump
How to take backup of MySQL Database
try
{
string strBackupFileName = GetBackUpFileName();
StreamWriter strBackupFile = new StreamWriter(strBackupFileName);
ProcessStartInfo psInfo = new ProcessStartInfo();
psInfo.FileName = #"c:\Users\current.user\source\xampp\mysql\bin\mysqldump.exe";
psInfo.RedirectStandardInput = false;
psInfo.RedirectStandardOutput = false;
psInfo.Arguments = "- u root -h localhost --databases --hex-blob -n -t dashboard --tables dashboard.backup --where='updated_at < NOW() - INTERVAL 365 DAY'";
psInfo.UseShellExecute = false;
psInfo.RedirectStandardOutput = true;
Process backup_process = Process.Start(psInfo);
string stdout;
stdout = backup_process.StandardOutput.ReadToEnd();
strBackupFile.WriteLine(stdout);
backup_process.WaitForExit();
strBackupFile.Close();
backup_process.Close();
MessageBox.Show("Backup done at file:" + strBackupFileName);
}
catch (Exception ex)
{
MessageBox.Show("Error during the backup: \n\n" + ex.Message);
}
When I run the program I see that mysqldump doesn't "wait" to do the process (when I do it manually, it takes at least 25-30 seconds), it opens a command prompt window and closes immediately.
The solution was simple, in:
psInfo.Arguments = "- u root -h localhost --databases --hex-blob -n -t dashboard --tables dashboard.backup --where='updated_at < NOW() - INTERVAL 365 DAY'";
only i must to delete the space between "-" and "u".
Related
Plan
The plan is to disable and subsequently enable a device from inside a windows forms application. To test the first building block of my plan, I open cmd with admin privileges and the following works perfectly:
> devcon hwids =ports
> devcon hwids *VID_10C4*
> devcon disable *VID_10C4*
> devcon enable *VID_10C4*
I can see the device being disabled and enabled again in device manager.
I can also achieve all of this by putting the commands into a batch file and running it from cmd with admin privileges. The above tells me that my plan is essentially good.
Application
However, what I actually want to do is achieve the same thing from inside a windows forms application:
I've set the following in the app manifest:
requestedExecutionLevel level="requireAdministrator" uiAccess="false"
For the sake of baby steps, I have checked this, just to ensure that there are no stupid mistakes in paths and whatnot. And it works just fine. The log file shows me the expected output from the dir command.
// Build String
string strCmdText =
"'/c cd " + prodPath +
" && dir " +
" > logs\\logFileEnablePrt.txt \"'";
// Run command
var p = new System.Diagnostics.Process();
var psi = new ProcessStartInfo("CMD.exe", strCmdText);
psi.Verb = "runas"; // admin rights
p.StartInfo = psi;
p.Start();
p.WaitForExit();
However, this does not work. It always returns an empty log file and does not change the device as expected:
// Build String
string strCmdText =
"'/c cd " + prodPath +
" && devcon hwids =ports " +
" > logs\\logFileEnablePrt.txt \"'";
// Run command
var p = new System.Diagnostics.Process();
var psi = new ProcessStartInfo("CMD.exe", strCmdText);
psi.Verb = "runas"; // admin rights
p.StartInfo = psi;
p.Start();
p.WaitForExit();
Error from cmd window is :
'devcon' is not recognized as an internal or external command,
operable program or batch file.
What's going on?
The above has me stumped. I've proved the commands work. I've proved my C# code works. But when I join the 2 together, it doesn't work...
NB: My C# program is running on my D: drive, if that makes any difference...
Updates Based on Comments
#Compo
Using your code, it does exactly the same as with mine. I see an empty log file & no changes made to the device. I've altered the /c to /k so I can see what going on the cmd terminal and I see this:
I've even tried your code C:\\Windows\\System32\\devcon hwids =usb pointing directly at devcon. Also tried \devcon.exe for completeness. The inexplicable error is :
I can see the flipping devcon.exe file sitting right there in the folder! Is there any reason it would not recognise it?
Also, with the command as you wrote it, the log file name is actually named logFileEnablePrt.txt'. I agree that your command looks right, so don't ask me why this happens!
#Panagiotis Kanavos
using your code, I get the following error:
This is at the line p.Start();. I tried putting in devcon.exe, and even the whole path (I checked the folder was in my PATH, and it is). Can't get past this. I actually stumbled on that answer you shared and arrived at this brick wall already.
Here is the code works for me, I don't have ports devices so I change it to usb.
public static void Main()
{
string prodPath = #"c:\devcon\x64";
// Build String
string strCmdText =
"/c \"cd /d " + prodPath +
" && devcon hwids =usb " +
" > log.txt \"";
// Run command
var p = new Process();
var psi = new ProcessStartInfo("CMD.exe", strCmdText);
psi.Verb = "runas"; // admin rights
p.StartInfo = psi;
p.Start();
p.WaitForExit();
}
Worked through a few steps and think I may have an answer...
Just specifying devcon fails as expected...windows cant find the exe as the folder it is in is not in the %PATH% variable in windows..
IF I specify the full path however it works...
It wasnt clear from your original code but if your copy of devcon is sitting in either System32 or Syswow directories you may be hitting an emulation issue as well...see here....
EDIT1:: A way to prove this would be to do Direcory.GetFiles(directory containing devcon) and see if the results line up with what you expect
As for passing arguments through to devcon I'd try something like this as opposed to trying to concatenate one giant cmd line..
A similar example but with netstat:
EDIT 2::Another example but with devcon:
The target platform here for the build was x64
EDIT3::
With my application build set to x86:
After working through the answers and comments above, I seem to have something that reliably works, which obviously I'd like to share back for scrutiny and future use.
So, my function ended up looking like this:
private int enablePort(string action)
{
while (true)
{
// Command Arg
string devconPath = #"c:\Windows\SysNative";
string strCmdText =
"'/c \"cd /d \"" +
devconPath +
"\" && c:\\Windows\\SysNative\\devcon " + action + " *VID_10C4* " +
"> \"" + prodPath + "\\logs\\logFileEnablePrt.txt\"\"";
// Process
var p = new Process();
var psi = new ProcessStartInfo()
{
Arguments = strCmdText,
Verb = "runas",
FileName = "CMD.exe",
UseShellExecute = true
};
p.StartInfo = psi;
p.Start();
p.WaitForExit();
// Grab log output
string logPath = prodPath + "\\logs\\logFileEnablePrt.txt";
Console.WriteLine("logPath = " + logPath);
string tempFile = System.IO.File.ReadAllText(logPath);
System.Console.WriteLine("Contents of WriteText.txt = \n{0}", tempFile);
// Check if it worked
var success = false;
if (tempFile.Contains(action))
{
success = true;
return 0;
}
// Error -> Allow user to try again!
if (MessageBox.Show("Was unable to " + action + " Test Jig COM port. Unlug & Replug USB. Check COM port is enabled if not working.", "COM Port Problem", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
return -1;
}
}
}
And the calling code was:
this.enablePort("disable");
int milliseconds = 3000;
await Task.Delay(milliseconds);
this.enablePort("enable");
As you can see in the code above, I've logged everything to see what was going on... Stepping through with the debugger, I can now see after the disable:
USB\VID_10C4&PID_EA60\0001 : Disabled
1 device(s) disabled.
And then after the enable:
USB\VID_10C4&PID_EA60\0001 : Enabled
1 device(s) are enabled.
The one extra thing I need to stress is that during testing, I thought I could hook a serial peripheral onto the port and determine whether it could disable and enable successfully by checking the connection. THIS DOES NOT WORK. The above code only works when the port is idle. Perhaps someone who understands the underlying software could hazard an explanation of why this is.
I'm writing a program with C# , that can create Users on remote Computers.
Actually it's done and working.
But I have one little problem.
In C# I use PowerShell to run a Script which runs then an Pexec, which executes a Batch file on a remote Computer.
C# :
private void executeScripts()
{
string _dirPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string _sPath = Path.GetDirectoryName(_dirPath) + #"\ExecuteScripts\FileToExecute.ps1";
string _scriptPath = "& '" + _sPath + "'";
using (PowerShellProcessInstance pspi = new PowerShellProcessInstance())
{
string psfn = pspi.Process.StartInfo.FileName;
psfn = psfn.ToLowerInvariant().Replace("\\syswow64\\", "\\sysnative\\");
pspi.Process.StartInfo.FileName = psfn;
using (Runspace r = RunspaceFactory.CreateOutOfProcessRunspace(null, pspi))
{
r.Open();
using (PowerShell ps = PowerShell.Create())
{
ps.Runspace = r;
ps.AddScript(_scriptPath);
ps.Invoke();
}
}
}
}
PS Script :
#
# First there are some Copy-Items to the remote Computer
#
# Execute Above copied Bat File on remote Computer
[string] $IPAddress = "\\" + $XmlFile.ComputerSettings.LastChild.ChildNodes[1].InnerText
$PsTools = "\PsTools"
$PsToolsPath = Join-Path -path $ScriptParent -childpath $PsTools
& $PsToolsPath\PsExec.exe $IPAddress /accepteula -i -s -u $Login -p $LoginPassword Powershell C:\Path\ToBatFile\Execute.bat > log.txt
Exit
I use this PExec 3 other times in my Program, creating a User, updating a User and removing a User, i just execute different files, scripts or batch files.
And it works perfectly.
But with the Script above, the PExec executes everything but doesn't exit. Neiter does it log something.
I tried it also with the -d switch, but that didn't work either. I also put an exit /b in the batch file but no luck.
When running the script manually from Powershell it works, it executes and it exits, but when running it from my Program it doesn't.
After some waiting my C# returns a timed-out Exception end exits.
Anyone seeing what I'm doing wrong ?
Powershell class itself has a method called Stop() which makes it pretty easy to stop this.
If you want to do it asynchronously here is an example of implementation:
using(cancellationToken.Register(() => powershell.Stop())
{
await Task.Run(() => powershell.Invoke(powershellCommand), cancellationToken);
}
I am trying to execute one command through process but it is throwing exception as "The system cannot find the file specified". When i run this command directly on command prompt. It is working fine.
Command: start cmd.exe #cmd /k "NTttcpr.exe -r -m 1,*,192.168.1.2 -a 2 -t 120 -wu 10 -cd 10 >> NTTTCP-1T-TCP-IPV4-Rx-MTU1500-Support-port-1-Rx-AMD-10-GBE-RJ45-ITR-1.log"
This command executes perfectly if i run on command prompt.
This is how i written code:
string tool = #"NTttcpr.exe";
string command = " -r -m 1,*,192.168.1.2 -a 2 -t 120 -wu 10 -cd 10 >> NTTTCP-1T-TCP-IPV4-Rx-MTU1500-Support-port-1-Rx-AMD-10-GBE-RJ45-ITR-1.log";
private void RunCommand(string tool, string command)
{
try
{
logger.Info($"{MethodBase.GetCurrentMethod()}: {tool} {command}");
Process pro = new Process();
pro.StartInfo.FileName = "start cmd ";
pro.StartInfo.Arguments = "#cmd /k " + '"' + tool + " " + command + '"';
pro.StartInfo.UseShellExecute = false;
pro.StartInfo.RedirectStandardOutput = true;
logger.Info($"{MethodBase.GetCurrentMethod()}: Executing command: {tool} {command}");
pro.StartInfo.Verb = "runas";
pro.Start();
//pro.WaitForExit(MillisecondsTimeout);
//Thread.Sleep(MillisecondsTimeout);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
logger.Error($"{MethodBase.GetCurrentMethod()}: Exception occurred while uni-directional command!!");
logger.Error($"{MethodBase.GetCurrentMethod()}: {ex}");
}
}
Note:
NTttcpr.exe file is already present in current executing directory.
Please help me to solve this.
This should be because you have not set the working directory, add pro.StartInfo.WorkingDirectory = "path to NTttcpr.exe" do not add NTttcpr.exe, just add the location.
Let me know if this works.
cmd.exe is not required for Process class. Try like below.
pro.StartInfo.FileName = "NTttcpr.exe";
pro.StartInfo.Arguments = command
I have an application that dumps a lot of files to a directory. I want to copy these files to a Hadoop cluster using the hadoop command. I use the following code to run the command.
System.Diagnostics.ProcessStartInfo export = new System.Diagnostics.ProcessStartInfo();
export.RedirectStandardOutput = false;
export.RedirectStandardError = false;
export.UseShellExecute = false;
export.WorkingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
export.FileName = "hadoop";
export.Arguments = "fs -copyFromLocal " + Path.Combine(dumpDirectory, "*.txt") + " " + hadoopPath));
Console.WriteLine("Copying data: hadoop " + export.Arguments);
System.Diagnostics.Process proc = System.Diagnostics.Process.Start(export);
proc.WaitForExit();
if (proc.ExitCode == 0)
{
IEnumerable<string> files = Directory.EnumerateFiles(dumpDirectory);
foreach (string file in files)
File.Delete(file);
}
else
Console.WriteLine("Error copying to Hadoop: " + proc.ExitCode);
The program writes the following message:
Copying data: hadoop fs -copyFromLocal local/directory/*.txt /user/remote/directory/
copyFromLocal: `local/directory/*.txt': No such file or directory
Error copying to Hadoop: 1
Interestingly, when I run the command manually, the files copy without error.
Also, if the program runs the command without using *.txt and instead calls the command for each file individually, the command succeeds.
Can anyone shed some light on this?
I partially resolved the problem by creating a bash script containing the given command. I ran the bash script programmatically and it worked.
However, I still do not know why the original did not work.
I am trying to export a database from c# using mysqldump.
When I run it i get this message: Unknown database 'mysqldump' when selecting the database.
I can't find the solution.
public static void mysqlBackup()
{
try
{
//string time = DateTime.Now.ToString("dd-MM-yyyy");
Log.Info("Starting MySQL dump");
Process MySqlDump = new Process();
MySqlDump.StartInfo.FileName = #"mysqldump.exe";
MySqlDump.StartInfo.UseShellExecute = false;
MySqlDump.StartInfo.Arguments =
"mysqldump -uroot -p******** b3 >"+
" C:/Users/Administrator/Documents/temp/backups/backup.sql";
MySqlDump.StartInfo.RedirectStandardInput = false;
MySqlDump.StartInfo.RedirectStandardOutput = false;
MySqlDump.Start();
MySqlDump.WaitForExit();
MySqlDump.Close();
Log.Info("Successfull created");
}
catch (IOException ex)
{
Log.Error("Unable to write the database file" + ex.ToString());
}
}
I tried to remove the mysqldump from the arguments kinda the same problem.
The redirection operator > is not an argument to mysqldump. When you execute it on the command line, it's being interpreted by the command line itself, not by mysqldump. You have two choices here:
Use the --result-file option as others have mentioned
Capture the stdout of the process and do what you like with the output by setting the RedirectStandardOutput property of StartInfo to be true. After this, you can read from the StandardOutput stream of the process.
I think you need to specify the name of the database you want to dump as the first argument. Thanks to nathan it goes after --databases at the end.
MySqlDump.StartInfo.Arguments = "-u root -p *** database_name --result-file [path]\backup.sql";
You don't need to specify mysqldump again in the command either (not that it should make much difference).
The Mysql documentation states there are 3 ways to use the mysqldump command:
shell> mysqldump [options] db_name [tbl_name ...]
shell> mysqldump [options] --databases db_name ...
shell> mysqldump [options] --all-databases
Ensure the command works fine via your command line. If it does that execute that command directly within your code. If that works then start extracting your arguments and replacing them with your own parameters within code.
Basically you want to get as basic as possible and work back up from there.
If the file works on the command line, try this:
using (Process p = new Process())
{
p.StartInfo.FileName = #"mysqldump.exe -u root -p *** --database b3 -r test.sql"; <~~~ note the change here
p.Start();
p.WaitForExit();
}
The file will be dumped to your project folders bin/debug or bin/release folder unless you change that code.
Here is your edited method:
public static void mysqlBackup()
{
try
{
//string time = DateTime.Now.ToString("dd-MM-yyyy");
Log.Info("Starting MySQL dump");
using(Process MySqlDump = new Process()
{
MySqlDump.StartInfo.FileName = #"mysqldump.exe";
MySqlDump.StartInfo.UseShellExecute = false;
MySqlDump.StartInfo.Arguments = "-uroot -p******** b3 --result-file=C:/Users/Administrator/Documents/temp/backups/backup.sql";
MySqlDump.StartInfo.RedirectStandardInput = false;
MySqlDump.StartInfo.RedirectStandardOutput = false; //You can redirect this as mention in other answers
MySqlDump.Start();
MySqlDump.WaitForExit();
MySqlDump.Close();
}
Log.Info("Successfully created");
}
catch (IOException ex)
{
Log.Error("Unable to write the database file" + ex.ToString());
}
}