I have a win32 app and I'm starting a robocopy child process for some file transfers. If I terminate the process using TerminateProcess is there a possibility to end with corrupt files? If so how to avoid this?
From TerminateProcess function,
The TerminateProcess function is used to unconditionally cause a
process to exit. The state of global data maintained by dynamic-link
libraries (DLLs) may be compromised if TerminateProcess is used rather
than ExitProcess.
Keep in mind that TerminateProcess does not allow its target to clean up and exit in a valid state.
Try to close the process cleanly, refer the link below,
How To Terminate an Application "Cleanly" in Win32
If the robocopy process is terminated, the file being copied will have a timestamp of (a) 1980-01-01 (b) the same size as the original file.
Then use robocopy to copy files with TimeStamp in command line again.
Refer: How to use Robocopy to copy files with TimeStamp in command line
Related
I have a file opened named "C/Users/Desktop/textfile.txt". How do I close this using a shell script? I have tried taskkill, shutdown, "exec 1>&-" and others. Since I am new to shell, I am unable to figure out how to make it work.
textfile.txt is a non-executable file. That means you can't 'run' it, or 'kill' it. However, you can delete it - that is if some other process is not holding a lock on it.
If you want to release the lock, you have to first find the process that is holding a handle to this file, kill that process, and then the OS will let you delete the file.
From shell (command line), you can use this tool handle (https://learn.microsoft.com/en-us/sysinternals/downloads/handle) to identify which process is holding your handle. Once you get the pid (process id) from that tool, you can use taskkill to terminate that process and release the lock on that file.
c:\Program Files\SysinternalsSuite>handle.exe | findstr /i "c:/users/desktop/textfile.txt"
All said, you want to be careful when you terminate processes abruptly like this. The process won't get a chance to clean up behind itself.
Is there a safe and easy way of executing a subprocess, while not allowing it to have access to the parents file descriptors? Particularly in my case this happens:
The parent process listens to socket 127.0.0.1:8000.
The parent process uses exec to run a sub process. This sub process forks and starts a daemon.
The parent process closes.
The daemon now keeps the file descriptor open (keeps listening to port 8000).
Perhaps there is some command that can close all file descriptors before executing the sub process?
This problem occurs for example if you call the 'service someservice start'' commands from a web server script.
Perhaps there is some command that could run the service script in a "clean" context, something like:
run-detached service someservice start
Which would cause all file descriptors to be closed, environment variables to be unset and so on - so that the context the service runs within is as basic as possible.
You can't close file descriptors from outside the process (for obvious good reasons).
One thing you could do is to create a small shim for the program that is to be run in the subprocess, and convince the parent to exec() that instead (e.g. by putting it in place of the original). This small program can then close file descriptors and then exec the original program.
I am trying to create a script that will "self update" when it detects a new version on a server. Initially the idea I had was, when a new version is detected, download the file, then starts a DOS batch file that simply overwrites the original exe with the new one. I thought, that I could use sytem(start update.bat ) then immediately exit 0; The .bat file waits for a couple seconds, and then tries to delete the old exe. This fails, I guess because even when using system(start ... ), the new "process" is actually the same process, is this correct? Is there any way to launch a completely new process from perl in windows, that would allow me to delete the .exe? Or is there a different approach that would be better?
Thanks,
Eric Seifert
See the documentation on the Windows Restart Manager, an API introduced with Windows Vista that manages restarting applications, for updates, for you.
Ever heard of java WebStart? There is a PAR equivalent, PAR::WebStart
Basically, you configure it, then download code live from a trusted website
so your .exe would just be a frontend to PAR::WebStart, with the real program downloaded off your website
I know this is an old question, but I thought I'd put my solution here since I'm working on the same sort of thing. Your batch idea is the way I went, but the small change I made was to use exec() instead of system() since the former (according to this) "...executes a system command and never returns", which seems to release the running process. This appears to work both when running interpreted Perl files with Strawberry Perl, and when running compiled programs with PAR::Packer.
I've created test.pl, which was ultimately compiled to test.exe, as follows:
#!/usr/bin/perl
use 5.10.0;
use strict;
use warnings;
my $batch_file = <<"BATCH";
rem ### IT IS SAFE TO DELETE THIS FILE ###
\#echo off
ping 127.0.0.1 -n 2 -w 1000 > nul
echo Copying over update file...
copy testfile.exe test.exe
BATCH
open my $fh, '>', 'update.bat';
print $fh $batch_file;
close $fh;
exec( 'update.bat' );
testfile.exe is a standby "upgraded" version of test.exe, just to make sure that I can overwrite test.exe while it's running, and I can. The ping is a way to pause for 2 seconds to make sure the process has had a chance to exit before trying to overwrite the file.
Oddly enough, the created batch file update.bat can't delete itself, even though batch files can normally delete themselves. If I create a batch file with this:
start /b "" cmd /c del %0
It will delete itself without any errors. But if I include that snippet in update.bat, it complains that The process cannot access the file because it is being used by another process. I'm not sure why. Since this isn't particularly important in my application, I haven't pursued this. I just leave update.bat behind and let it be overwritten next time an update occurs. But I do notate in the file that it's safe to delete in case anyone looks at it later.
How would I create a self executing batch file to delete files in a specific folder.
Scenario: I have a folder on a server where all the scannered documents go to once they have been scanned. They want a the scanned documents to be deleted after 1 day. Can a batch file be created to do that everyday?
You can use the built in task scheduler - this can call a batch file, or just about anything.
(I am assuming Windows, since you mention batch files).
This is quite a well known method, and was documented in MSDN some time ago. This technique works on both Windows 95 and Windows NT. It works because MS-DOS batch files are able to delete themselves. To test this technique, create a small batch file containing the single command:
del %0.bat
The batch file, when run, deletes itself and issues an error "The batch file cannot be found". This error is just a simple message, so it can be safely ignored. By itself this isn't too useful, but when modified to delete our executable it solves our problem, albeit in a rather forceful manner. Our executable will create a batch file (called C:\DelUs.bat) with the following content:
:Repeat
del "C:\MYDIR\MYPROG.EXE"
if exist "MYPROG.EXE" goto Repeat
rmdir "C:\MYDIR"
del "\DelUS.bat"
This batch file repeatedly attempts to delete the specified file, and will run continuously consuming CPU until it succeeds. When the execuable has been deleted, the batch file then deletes itself.
The executable needs to spawn off the batch file using CreateProcess, and then should exit immediately. It would be a good idea to give the batch file's thread of execution a low priority so that it doesn't get much execution time until the original executable has terminated.
Read the entire article at http://www.catch22.net/tuts/self-deleting-executables that contains the full code to this technique.
Is there any way that a running process can delete its own executable?
For example, I make a console application (single exe) and after doing some tasks it somehow deletes the exe file.
I have to send a single file to someone. And I want it deleted after it does its intended task.
Is there anyway to do it in Windows
One way to do this is to use the MoveFileEx function with the MOVEFILE_DELAY_UNTIL_REBOOT flag and a NULL destination. According to the documentation, this:
registers the lpExistingFileName file to be deleted when the system restarts. If lpExistingFileName refers to a directory, the system removes the directory at restart only if the directory is empty.
process.start("cmd /c ping localhost -n 3 > nul & del filepath")
exit
Explanation :
ping localhost -n 3
Adds a slight delay before executing del filepath. By the time it's triggered, your program has exited.
Replace process.start with whatever command your programming language uses to start programs with arguments.
Replace filepath with the path to your exe.
Replace exit with the command for terminating your program.
===
10yr anniverary edit, if this doesn't work, you must find a way to perform a "process.start" that starts a separate (external) process, not one subordinate to your original calling program: Python, Bash, C, ...... or search for a different language
Replace the search in the catch all with your programming language and you will likely find a suitable guide for this essential step. Please take care to ignore superfluous information as every question may come with obscure specific details that are unrelated to you.
You can use windows scheduler to schedule a task to delete your program after X seconds.
Command line: http://msdn.microsoft.com/en-us/library/bb736357%28VS.85%29.aspx
Or API: http://msdn.microsoft.com/en-us/library/aa383608%28VS.85%29.aspx
You can run another application, which would wait for parent process to terminate, and then delete its executable.
It's possible to do this on Linux. You'll find that it is generally not possible to delete a running executable on Windows. However, you can have Windows delete the EXE for you on the next reboot: http://www.howtodothings.com/computers/a1402-delete-a-running-exe.html
If you want the file deleted after it's been run, you could simply ask the user to delete it. If the reason you want this is as a security measure, then what you're doing is misguided. The user could circumvent this by simply making a copy of the file first.
While it's not possible to self delete a file when it's running it is possible to launch a detached cmd command from the file, then end the file operation before the command executes.
So, if you want to delete a bat file you can just add at the end of the file the line:
start cmd /c del %0
and the file would self destruct.
The start cmd will start a new cmd window (detached from your main process).
The /c tells the windows to execute whatever comes after the /c in the line.
Then the del will delete the file at the path it is given.
The parameter $0 refers to the first command line argument which is usually the name and path to the file that was executed, which is what we want.
(the $0 parameter is the path to the file, you want to pass that to the del command).
Until that exe is in memory, it will not be able to delete itself. However, it can register with the system a task for deleting itself after a set time period of gap when it would be expected to be completing its execution.
I solved this problem (using Visual Basic) by creating a batchfile that is executed while the process is still running, waits 1sec so the program can close itself and than deletes the program.
You might need to modify it for this will delete every thing in the same folder. After your task just call del() and it should work.
Sub del()
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("del.bat", True)
file.WriteLine("")
file.WriteLine("timeout 1")
file.WriteLine("echo Y | del *.*")
file.Close()
Process.Start("del.bat")
Me.Close()
End Sub
I couldn't find any solutions anywhere else so I'll post my fix here.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
char* process_name = argv[0];
char command[256] = "start /min cmd /c del ";
strcat(command, process_name);
printf("Attempting to delete self...\n");
system(command);
return 0;
}
Normally, trying to use system to call the command prompt to delete an executable would not work because the command prompt that is spawned is a child process that system executes and waits for a return status.
This method calls the system to start a command prompt process on its own thread.
The /min argument starts the process as "hidden".
The /c argument supplies arguments to the spawned command prompt.
I know this is an old thread, but I hopes those that come here in the future.