I have create a program that delete a folder.
Like this :
if (Directory.Exists((System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "My Dir Name"))))
{
Directory.Delete(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "My Dir Name"), true);
}
this is alright . But a file that name is "Delete.exe" is in directory of "My Dir Name" [Like my code ] ! It gave an error, because "Delete.exe" is running and can't delete .
What can I do to delete, "Delete.exe"?
You're trying to delete the folder in which your running application is in and therefore delete the program itself? Well, you have a few options. It is interesting to note as well that batch files can delete themselves. So, that also leaves you a few more options:
have your C# program copy itself to a temp directory before deleting the folder, and run from there.
use a batch file entirely instead of C# - having it do whatever and then delete itself afterwards.
have your C# program generate and execute a batch file and then quit - leaving the batch file to clean up after the C# program exits.
run a CLI command to delete your program after a specified time:
Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + Application.ExecutablePath);
you can use MovFileEx to specify to have your program deleted on next start up.
Most of these answers imply that the running EXE is your own appliation. if it is not, though - #5 will still work. you can schedule it to be deleted the next time the computer starts.
Related
I am trying to silently read and write to a .cmd file from a C# console application. The .cmd file looks like this :
ECHO OFF
set Input=""
set /p IsCustom="Do you want to create a custom deploy package ? (Y/N)"
set /p Input="Enter product name (press enter for none):"
ECHO ON
cd .\DeployScript
IF /I "%IsCustom%" == "Y" (
nant -buildfile:Deploy.build -D:environment=Disk Deploy.LocalRelease -D:productname=%Input%
cd ..
GOTO END
)
nant -buildfile:Deploy.build -D:environment=Disk Deploy.NewLocalRelease -D:productname=%Input%
cd ..
:END
This is where I want to insert the values :
set /p IsCustom="Do you want to create a custom deploy package ? (Y/N)"
set /p Input="Enter product name (press enter for none):"
Here is what I tried in C# console application, but I am not able to read the above two questions and write to them:
private static void ExecuteCmdFile()
{
Process process = new Process();
process.EnableRaisingEvents = true;
process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived);
process.Exited += new System.EventHandler(process_Exited);
process.StartInfo.FileName = Path + #"\createPackage.cmd";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
}
static void process_Exited(object sender, EventArgs e)
{
Console.WriteLine(string.Format("process exited with code {0}\n", ""));
}
static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
//Console.WriteLine(e.Data + "\n");
}
I am unable to read the questions at process_OutputDataReceived() and have no clues on inserting values. Just wanted to know if I am reading/writing to the .cmd file from C# application correctly ? Am I missing something here or is there any other approach ?
The Windows Command Processor cmd.exe processing a batch file is not designed for communication with other processes. It is designed for executing commands and executables one after the other and supports simple IF conditions and GOTO to control the sequence of command/program executions and FOR for doing something repeated in a loop. That´s it.
I suggest modifying the batch file to this code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IsCustom=%~1"
if defined IsCustom goto CheckInput
%SystemRoot%\System32\choice.exe /C NY /N /M "Do you want to create a custom deploy package (Y/N)?"
if errorlevel 2 (set "IsCustom=Y") else set "IsCustom=N"
:CheckInput
set "Input=%~2"
if not defined Input goto InputPrompt
if /I "%Input%" == "/N" set "Input="
goto ProcessData
:InputPrompt
set /P "Input=Enter product name (press enter for none): "
if not defined Input goto ProcessData
set "Input=%Input:"=%"
:ProcessData
cd /D "%~dp0DeployScript"
if /I "%IsCustom%" == "Y" (
nant -buildfile:Deploy.build -D:environment=Disk Deploy.LocalRelease -D:productname="%Input%"
goto END
)
nant -buildfile:Deploy.build -D:environment=Disk Deploy.NewLocalRelease -D:productname="%Input%"
:END
endlocal
Now the batch file can be executed without any argument in which case the user is prompted twice with evaluation of the input in a safe and secure manner.
But it is also possible to run the batch file with one or two arguments from another executable like a program coded in C# or from within a command prompt window or called by another batch file.
The first argument is assigned to the environment variable IsCustom which is explicitly undefined on batch file executed without any argument or with "" as first argument. The IF condition used later with referencing the string value of the environment variable IsCustom just checks if the string value is Y or y to do the custom action. Any other argument string passed as first argument to the batch file results in running the standard action.
The second argument is assigned to the environment variable Input which is also explicitly undefined on batch file executed without any argument or with "" as second argument. If the second argument is case-insensitive equal /N, then the batch file interprets this as explicit request to use no product name.
The Yes/No prompt is done using command CHOICE which is highly recommended for such choice prompts if the batch file is called without any argument or with "" as first argument.
The second prompt is done using set /P if the batch file is called without a second argument or with just "" as second argument. Double quotes are removed from input string if the user inputs a string at all for safe and secure processing of the input string by the remaining lines.
The directory DeployScript is most likely a subdirectory of the directory containing the batch file and for that reason the command CD is used with option /D to change if needed also the current drive and makes explicitly the subdirectory DeployScript the current directory independent on which directory is the current directory on starting the execution of the batch file.
nant should be referenced with file extension and if possible with full path if the full path is well known because of being relative to batch file path or is fixed making it possible to use the fully qualified file name in the batch file as it is done for external command CHOICE.
The command ENDLOCAL results in making the initial current directory again the current directory. SETLOCAL pushes the current directory path on stack. ENDLOCAL pops that path from stack and makes this directory again the current directory (if not deleted in the meantime which is not possible here). For that reason the execution of cd .. is not needed at all.
Now the C# coded application can run cmd.exe with the options /D and /C and the batch file name with its full path with the two arguments Y or N and product name or /N. There is no need anymore to communicate with cmd.exe processing the batch file or passing the arguments via standard input stream to the internal command SET of cmd.exe.
Note:
I do not really understand why the C# Process class is used being a C# wrapper class for the Windows kernel function CreateProcess called with using the STARTUPINFO structure to run cmd.exe to process a batch file. It would be also possible to use the Process class to run nant directly by the C# coded program and of course also any other executable which the batch file perhaps runs additionally. A C# coded application has direct access to all Windows library functions used by cmd.exe on processing a batch file. So there is really no need in my opinion to use a batch file at all for the task according to the provided information about the task.
For understanding the used commands in the batch file and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains batch file argument referencing
choice /?
cmd /?
echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?
I am running a test to check if there are files of type *.exe in a certain folder.
I am sending the commands from one computer to another (if that's matter..)
my condition in the code is:
if (string.Contains("File Not Found"))
test PASS
else
test FAIL
(don't mind the syntax PASS\FAIL it's just the idea)
(when files not found with DIR command then this string will appear at the end of search)
the command sent is:
"dir " + PATH + " *.exe /s"
the problem is, in results I get all the subfiles in the wanted directory, but also the command runs on the current folder (which can be anything, I can't change that and it can change from time to time and obviously I don't want this folder to effect on the result of the PATH I searched in).
the code written in C#, the commands themselves run on cmd.
what can be the problem?
the results look like this:
Directory of C:\Windows\Temp //PATH = C:\Windows\Temp
12/26/2019 04:26 PM <DIR> .
12/26/2019 04:26 PM <DIR> ..
0 File(s) 0 bytes
Directory of C:\Program Files (x86)\.............
09/03/2019 08:11 PM 8,704 NAME.exe
.
.
.
18 File(s) 2,141,696 bytes
so my test fails when it shouldn't.
how can I resolve that?
"dir " + PATH + " *.exe /s"
^--- this space is your problem.
You execute dir with two parameters, so it lists all files matching the first string (PATH), then all files matching the second string (*.exe from the current working folder). You can verify in the command prompt with dir c:\windows *.* vs. dir c:\windows\*.* So remove the space.
Note: it's safer to also put quotes around the string (in case there are intended spaces (like in Program Files): dir "c:\program files\*". (I don't know how to do that in C#, but if you know about C#, it should be easy)
You can use multiple commands on the same line
"cd " + PATH + " && dir *.exe /s /b"
For some reason, I can't seem to launch and run a .cmd file with c#. An example of a line of the cmd file is:
"C:\Windows\system32\ffmpeg64.exe" -v verbose -y -i "S:\TEMP\A.ts" -c:v copy -c:a copy -ss 00:00:00.000 -t 2 "S:\TEMP\A_SHORT.ts"
I've tried several different ways to launch this file from within C#, such as (where curDirectory is for example "S:\TEMP")
Process p = Process.Start(curDirectory + "\\ffmpeg.cmd");
I've also tried
string path = curDirectory + "\\ffmpeg.cmd";
Process p = Process.Start("cmd.exe", #"/c " + path); //I've also tried /k
But what happens is the cmd prompt will show up and say "C:\Windows\System32\ffmpeg64.exe" is not recognized ..." even though the file is there. What am I doing wrong?
If your system is running the Windows 6.1 kernel or later, System32 is actually comprised of other directories based on the application you're running (depending on whether it is a 32-bit or 64-bit application).
I assume that ffmpeg64.exe is a 64-bit application, and when you execute the .cmd file manually, it should default to a 64-bit command prompt - Also ensure that your application is targeting "x64" or "Any CPU". Alternatively, you could place a 32-bit version of ffmpeg in the WoW64 directory.
Also, I know you've stated in comments that you don't want to read the .cmd file and modify it, but you could compose your ProcessStartInfo with Environment.SystemDirectory instead of the hard-coded path.
As a last option, you could place the ffmpeg exe somewhere static (as you stated in the comments, in c:\ works), or just in your application's working directory.
I am trying to run xxx.exe file using command prompt with silent mode. i saw this link in Google: http://www.powerware.com/Software/lansafe_help/LSHelp424.htm.
when i run this command : C:>"D:\xxx.exe" -r -f1"D:\Test.iss"
am getting error : "xxx.exe" is not recognized as an internal or external command operable program or batch file.
Can any body give the idea where i am doing mistake.
As others said, make sure your path to your exe file is correct. You can change directory where exe is before execution or write out the full path.
By silent mode if you mean to run exe without any output on screen, then simply redirect the output to a file.
E.g. if your exe is in D:\myprog\myprog.exe, then following command will make your program run in "silent" mode:
c:>"D:\myprog\myprog.exe" > "D:\myprog\output.txt"
Above example will dump output into output.txt file.
you have to run your command in which location EXE file is located. can you check whether its residing in d:?
You may switch over to the D:\ drive before running your command, but it shouldn't matter. Double check it actually exists in that location
I have a shared path (like //servername/c$/batches/) where all my batch files are located now I am writing an web application in C# to run .bat files from that application. I know way to do it when I have a physical path.
But here I dont have a physical path. Is it possible to do it.
EDIT# 1
I execute my bat files just by double clicking on them or open the cmd progam on the physical server and then navigate to the drive and execute the bat file.
EDIT #2
when I put UNC path the get the following error
I getting an error myprogram.exe is not recognized as an internal or external command operable program or batch file. 9009
Batch files don't support UNC paths as their "current directory". There's a hackish work around of doing:
pushd "%~dp0"
your batch stuff
popd
%~dp0 expands to the current (d)rive/(p)ath/(0)batchfilename
example:
ok. a Simple batch file:
pushd %~dp0
echo "Hello from batch land"
echo %~dp0
popd
put that on a server somewhere, and try to run it via a unc path:
C:\> \\server\share\test.bat
You'll get as output:
C:\>pushd \\server\share\
Z:\>echo Hello from batch land
Hello from batch land
Z:\>echo \\server\share\
\\server\share\
Z:\>popd
C:\>
Weird, but it works.
That's called a UNC path.
You can use it just like any other path.
However, the user that your ASP.Net code is running as must have read access to the network share.
Apparently, you do have a current-directory issue.
The .bat file is trying to run myprogram.exe from the current directory.
You can make a wrapper batch file on your local machine that maps the network share:
pushd \\server\c$\dir
call filename.bat
popd
You can put this wrapper file anywhere, then call it from your code.