C#如何使应用程序在应用程序文件被删除后继续运行

9

4
我的翻译如下:我会这样做:一旦应用程序启动,它会将可执行文件和依赖项复制到临时文件夹中,然后从临时副本重新启动应用程序并杀死第一个实例。 - user4763353
Codeproject上的解决方案似乎是另一种应用程序:从可移动设备启动第二个可执行文件,该文件基于系统驱动器上保留的基本可执行文件。 - user4763353
如果现在移除驱动器会发生什么?我的假设是:要能够运行可执行文件,必须首先加载它。我不知道加载是如何发生的(您可以调查),但我期望只有资源(稍后访问时)才是问题。预加载它们并使用缓存版本=不再需要访问磁盘=没有问题。如果我错了,请纠正我(告诉我现在会发生什么)。 - Sinatr
https://msdn.microsoft.com/en-us/library/w0628bwh.aspx - Hans Passant
但是当我打印路径时,它们都是相同的,这仍然是一个问题吗? - pleasega
显示剩余6条评论
3个回答

2

如果您的控制台应用程序有一些引用的程序集,那么它们可能只有在被使用时才会被加载。

您需要在主方法或引导程序/启动程序的某个地方加载所有相关的程序集:

var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
var loadedPaths = loadedAssemblies.Select(a => a.Location).ToArray();

var referencedPaths = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll");
var toLoad = referencedPaths.Where(r => !loadedPaths.Contains(r, StringComparer.InvariantCultureIgnoreCase)).ToList();
toLoad.ForEach(path => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(path))));

1
从你的角度来看,这篇文章的方法存在问题,需要从另一个应用程序中启动,并且该应用程序的二进制文件必须始终存在,因此无法从同一位置启动该应用程序,或者您还没有解决该问题。
其中一个机制可能是:
1. 用户启动应用程序 2. 应用程序将自身复制到临时文件夹。 3. 应用程序使用Process.Start和/nocopy参数启动临时副本 4. 应用程序关闭自身。 5. 临时应用程序启动,读取/nocopy参数并跳过复制并启动。

你将如何处理/nocopy参数? - pleasega
1
这只是一个自定义的命令行参数,您可以在应用程序中进行管理。就像我的评论所说(“另一种解决方案是使用适当的命令行参数启动应用程序,您可以在应用程序启动时检查它们”)。 - user4763353
在非常简单的术语中,在 void Main(string[] args) 内部,只需测试是否有一个字符串在 args 中是 "/nocopy"。最好进行不区分大小写的检查。 - Richard Matheson

0

ElmoDev001的评论帮助我达成了想要的结果。

虽然有错误,但这是一般的想法:

Program.cs (主类)

class Program    {
    static void Main(string[] args)
    {
        String Temp = System.IO.Path.GetTempPath();
        String tmpDir = Temp + @"tmp\";

        String fileName = String.Concat(Process.GetCurrentProcess().ProcessName, ".exe");
        String filePath = Path.Combine(Extension.AssemblyDirectory, fileName);
        String tempFilePath = Path.Combine(tmpDir, fileName);

        if (!Directory.Exists(tmpDir)) { Directory.CreateDirectory(tmpDir); }

        if (!(string.Equals(filePath, tempFilePath))) // if the application is not running at temp folder
        {
            if (!(File.Exists(tempFilePath))) // if the application does not exist at temp folder
            {
                ext.initFile();
            }
            else if (File.Exists(tempFilePath)) // if the application already exists at temp folder
            {
                File.Delete(tempFilePath);
                ext.initFile();
            }
        }
        else if (string.Equals(filePath, tempFilePath)) // if the application is running at temp folder
        {
                //main code
        }
    }
}

Extension.cs

class Extension
{

    String Temp = System.IO.Path.GetTempPath();
    String tmpDir = Temp + @"tmp\";

    String fileName = String.Concat(Process.GetCurrentProcess().ProcessName, ".exe");
    String filePath = Path.Combine(Extension.AssemblyDirectory, fileName);
    String tempFilePath = Path.Combine(tmpDir, fileName);

    public static string AssemblyDirectory
    {
        get
        {
            string codeBase = Assembly.GetExecutingAssembly().CodeBase;
            UriBuilder uri = new UriBuilder(codeBase);
            string path = Uri.UnescapeDataString(uri.Path);
            return Path.GetDirectoryName(path);
        }
    }

    public static void initFile()
    {
            File.Copy(filePath, tempFilePath);
            Process.Start(tempFilePath);
            System.Environment.Exit(0);
    }
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接