为了避免有人不得不做我刚刚做的事情并制作这个 - 这只会复制具有不同日期修改时间的文件。我检查并重建您的应用程序只会在几个文件上更改此内容。这使得自加载程序非常快速,然后在新位置启动 exe,并退出执行从旧位置运行的加载的 exe。这可能取决于一些事情,例如运行代码的 DLL 必须与启动它的 EXE 命名相同。
在 .Net 5 中工作:
using System;
using System.Diagnostics;
using System.IO;
namespace NetworkHelper
{
public static class LocalCopier
{
public static void EnsureRunningLocally(string callingAssemblyDotLocation)
{
var assemblyFileFriendlyName = Path.GetFileName(callingAssemblyDotLocation.Replace(".", "-"));
var assemblyDirToCheck = Path.GetDirectoryName(callingAssemblyDotLocation);
var localLocation = Configuration.Tools.AppsLocation + assemblyFileFriendlyName + "\\";
var assemblyFinalExePath = localLocation + assemblyFileFriendlyName.Replace("-dll", ".exe");
// Check what assembly passed in path starts with
var runningFromNetwork = callingAssemblyDotLocation.ToLower().StartsWith(@"\\w2k3nas1\");
if (callingAssemblyDotLocation.ToLower().StartsWith(@"i:\")) runningFromNetwork = true;
if (!runningFromNetwork) return;
// Check if copied to local already
Directory.CreateDirectory(localLocation);
// Foreach file in source dir, recursively
CopyOnlyDifferentFiles(assemblyDirToCheck, localLocation);
Process.Start(assemblyFinalExePath);
Environment.Exit(0);
}
private static void CopyOnlyDifferentFiles(string sourceFolderPath, string destinationFolderPath)
{
string[] originalFiles = Directory.GetFiles(sourceFolderPath, "*", SearchOption.AllDirectories);
Array.ForEach(originalFiles, (originalFileLocation) =>
{
FileInfo originalFile = new FileInfo(originalFileLocation);
FileInfo destFile = new FileInfo(originalFileLocation.Replace(sourceFolderPath, destinationFolderPath));
if (destFile.Exists)
{
if (originalFile.LastWriteTime != destFile.LastWriteTime)
{
originalFile.CopyTo(destFile.FullName, true);
}
}
else
{
Directory.CreateDirectory(destFile.DirectoryName);
originalFile.CopyTo(destFile.FullName, false);
}
});
}
}
}
请注意,“\w2k3nas1”和“i:”是网络位置的示例,如果从这些位置运行,它应该将自身复制到本地目录,我使用应用程序数据/漫游/localApps,然后从新目录。
这都可以放入参考库中,并从任何客户端应用程序调用:
NetworkHelpers.LocalCopier.EnsureRunningLocally(Assembly.GetExecutingAssembly().Location);
(这里,Assembly.GetExecutingAssembly().Location 是从调用应用程序传入的,因为如果您要从参考项目中运行它,您将获得该库的 dll。)