Windows:执行后删除EXE

时间:2015-03-31 07:12:23

标签: c# windows file-handling

我正在使用C#中的应用程序执行以下操作:

  1. 将EXE写入磁盘
  2. 通过Process.Start()
  3. 执行EXE

    我现在正在努力确保EXE一旦关闭就会被删除。 最简单的方法是在使用FileOptions.DeleteOnClose创建EXE时设置File.Create参数。

    但是,这意味着EXE在使用时无法执行。关闭文件句柄后,EXE会立即删除,然后才能执行。

    有没有办法保留一个"弱参考"我的应用程序中的EXE没有锁定文件并允许它执行?或者,有没有办法解锁EXE执行文件句柄仍然打开?我还缺少其他明显的解决方案吗?

    澄清A:我知道其他删除正在使用的文件的方法,这些方法最终会删除文件(例如重启时)。然而,我正在寻找一种方法,一旦它开始执行就立即删除该文件由操作系统处理(例如,当运行首先执行该文件然后删除它的批处理时,如果批处理作业终止,该文件将保留在磁盘上)。

    澄清B:解释大局:应用程序接收并解密可执行文件。解密后,应该执行该文件。但是,我想确保解密版本的EXE不会保留在磁盘上。理想情况下,我还想阻止用户复制解密的EXE。但是,由于解密应用程序作为同一用户运行,因此无法以真正安全的方式实现,因为两者在系统上具有相同的权限。

2 个答案:

答案 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使用率。

相关问题