我正在使用C#中的应用程序执行以下操作:
Process.Start()
我现在正在努力确保EXE一旦关闭就会被删除。
最简单的方法是在使用FileOptions.DeleteOnClose
创建EXE时设置File.Create
参数。
但是,这意味着EXE在使用时无法执行。关闭文件句柄后,EXE会立即删除,然后才能执行。
有没有办法保留一个"弱参考"我的应用程序中的EXE没有锁定文件并允许它执行?或者,有没有办法解锁EXE执行文件句柄仍然打开?我还缺少其他明显的解决方案吗?
澄清A:我知道其他删除正在使用的文件的方法,这些方法最终会删除文件(例如重启时)。然而,我正在寻找一种方法,一旦它开始执行就立即删除该文件由操作系统处理(例如,当运行首先执行该文件然后删除它的批处理时,如果批处理作业终止,该文件将保留在磁盘上)。
澄清B:解释大局:应用程序接收并解密可执行文件。解密后,应该执行该文件。但是,我想确保解密版本的EXE不会保留在磁盘上。理想情况下,我还想阻止用户复制解密的EXE。但是,由于解密应用程序作为同一用户运行,因此无法以真正安全的方式实现,因为两者在系统上具有相同的权限。
答案 0 :(得分:8)
您可以使用Process.WaitForExit:
var process = Process.Start(processPath);
process.WaitForExit();
// File.Delete(processPath); // Not strong enough (thanks to Binary Worrier)
DeleteOrDie(processPath); // Will attempts anything to delete the file.
但它可以从您编写的地方复制 exe 。
一个好的解决方案是从内存中运行它。
如果目标 exe 是CLR程序,则可以使用Assembly.Load函数:
// read the file and put data in bin
...
Assembly a = Assembly.Load(bin);
MethodInfo method = a.EntryPoint;
if (method == null) throw new NoEntryPointException();
object o = a.CreateInstance(method.Name);
method.Invoke(o, null);
更多详情here。
如果你想在内存中加载/执行任何 exe ,你可以使用Nebbett’s Shuttle方法但是你需要code it in C/C++并从C#调用它
看起来微软并不喜欢它(安全问题),我认为你不能只用C#来实现它。良好的反病毒可能会检测到它。
答案 1 :(得分:2)
以一种不太好的方式,但一种可以给你你想要的方式,我建议这个解决方案:
(我使用Console Application
为此解决方案提供了一些输入参数)
[1:] 编写一个函数来检查已打开的进程:
/// <summary>
/// Check application is running by the name of its process ("processName").
/// </summary>
static bool IsProcessOpen(string processName)
{
foreach (Processing.Process clsProcess in Processing.Process.GetProcesses())
{
if (clsProcess.ProcessName.ToUpper().Contains(processName.ToUpper()))
return true;
}
return false;
}
[2:] 定义一些变量:
static bool IamRunning = true;
static int checkDuration = 1; // in seconds
[3:] 使用线程运行循环检查:
Thread t = new Thread(delegate() {
DateTime lastCheck = DateTime.MinValue;
while (IamRunning)
{
var now = DateTime.Now;
int dd = (now.Hour - lastCheck.Hour) * 3600 + (now.Minute - lastCheck.Minute) * 60 + now.Second - lastCheck.Second;
if (dd >= checkDuration)
if (!IsProcessOpen("ProcessName"))
{
delApplication(); // You have a function to delete ...
break;
}
}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
[4:] 在程序结束时使用循环:
while (t.ThreadState == ThreadState.Running)
{
// just wait.
}
注意:我的低级计算机中
Console Application
的此解决方案有50%的CPU使用率。