別のマシンで、完了時に自分自身を削除するプロセスを作成しようとしています。CreateFile で DELETE_ON_CLOSE フラグを使用しています。この方法は少し人気がありますが、開いている間は実行できないため、問題が発生しています(予想されますが、一部のソリューションではそうです)。これを回避するために、読み取り権限でファイルを開こうとしました。DELETE_ON_CLOSE フラグは、ファイルへのすべてのポインターがなくなった場合にのみファイルを削除する必要があることを示しています。読み取りでそれへのポインターがあり、書き込みハンドルを閉じると、ファイルが削除され、開いているハンドルが読み取れなくなります。これを回避する他の方法は、喜んでいただければ幸いです。
また、これはリモート ファイル システムであるため、ハンドルに異常が発生している可能性も考えました。
送信する実行可能ファイルのコードを変更することはできないため、自己削除実行可能ファイルは、私がやりたい最後のことです。
サービスをクリーンアップするためにプログラムを待機させると、リモート ボックスのサービスを破棄するのに時間がかかるため、プログラムが許容できないほど長時間ハングします。
//Open remote file for reading and set the delete flag
HANDLE remote_fh = CreateFile(&remote_file_location[0],
GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if(!remote_fh)
{
debug.DebugMessage(Error::GetErrorMessageW(GetLastError()));
RevertToSelf();
return dead_return;
}
//File to read from
HANDLE local_fh = CreateFile(&local_file_location[0],
GENERIC_READ,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(!local_fh)
{
debug.DebugMessage(Error::GetErrorMessageW(GetLastError()));
RevertToSelf();
return dead_return;
}
byte buf[256];
DWORD bytesRead;
DWORD bytesWritten;
//Copy the file
while(ReadFile(local_fh, buf, 256, &bytesRead, NULL) && bytesRead > 0)
{
WriteFile(remote_fh, buf, bytesRead, &bytesWritten, NULL);
}
CloseHandle(local_fh);
//Create a file retainer to hold the pointer so the file doesn't get deleted before the service starts
HANDLE remote_retain_fh = CreateFile(&remote_file_location[0],
GENERIC_READ,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (!remote_retain_fh)
{
debug.DebugMessage(Error::GetErrorMessageW(GetLastError()));
RevertToSelf();
return dead_return;
}
CloseHandle(remote_fh);
//if(!CopyFile(&local_file_location[0], &remote_file_location[0], false))
//{
// debug.DebugMessage(Error::GetErrorMessageW(GetLastError()));
// RevertToSelf();
// return dead_return;
//}
remote_service.Create(Service::GetServiceName().c_str());
//In the words of my daughter: "OH, OH, FILE ALL GONE!"
Pipe pipe(L"\\\\" + *hostname + L"\\pipe\\dbg");
CloseHandle(remote_fh);