有一个巧妙的小技巧,你可以用来永远不让操作系统锁定.dll
/ .exe
的{{1需要运行。
让我们说我们的目录如下:
>opener.exe >actualProgram.exe >dependency.dll
作为一个基本的例子,我们可以这样做:
.exe
我们还可以在其中添加更多逻辑,尽管正在打开该进程的实例,但我们可以使用它来实际替换/更新namespace Opener
{
class Program
{
static void Main(string[] args)
{
AppDomain domain = AppDomain.CurrentDomain;
AppDomain newDomain = AppDomain.CreateDomain(
domain.FriendlyName,
domain.Evidence,
domain.BaseDirectory,
domain.RelativeSearchPath,
true, // "shadow copy" files: copy rather than lock
domain.SetupInformation.AppDomainInitializer,
domain.SetupInformation.AppDomainInitializerArguments
);
string assembly =
System.Reflection.Assembly.GetExecutingAssembly().Location
+ "\\..\\actualProgram.exe";
newDomain.ExecuteAssembly(assembly, args);
}
}
}
。试一试:你将能够删除/修改/替换依赖项和"实际的"通过"开启者"加载程序。显然这有其好处,即更新更容易。
但是在你的" actual.exe"中,你怎么能确定它是通过另一个可执行文件加载的,并且知道它是在actualProgram.exe
没有锁定的情况下加载的?如果有人要加载" actual.exe",即不是通过"开启者",我想确保该过程立即退出。
提示?
答案 0 :(得分:2)
actualProgram.exe
,让它知道它是由启动器启动的。 (在Oleksii的评论中也提出了建议)AssemblyResolve
事件,将文件从磁盘加载到字节数组中并使用Assembly.Load(byte[], byte[])
重载。注意:只要在修改/移动/删除它们之前手动或由运行时加载所有程序集,您可能就可以了。此外,在加载DLL后更改DLL 可能对正在运行的进程没有影响。我可能在两种情况下都说过,因为在运行时将库单独保留通常是个好主意,特别是如果你没有手动加载它们。
另见:
答案 1 :(得分:0)
如何在启动后向应用程序发送自定义消息? 启动的代码将是这样的:
private void LaunchApplication()
{
ProcessStartInfo start = new ProcessStartInfo();
//you could pass in arguments here if you wanted
start.Arguments = string.Empty;
//your EXE name
start.FileName = @"c:\your_program.exe";
start.WindowStyle = ProcessWindowStyle.Normal;
start.CreateNoWindow = true;
Process p = Process.Start(start);
while (0 == (int)p.MainWindowHandle)
{
System.Threading.Thread.Sleep(100);
}
processHandle = p.MainWindowHandle;
label1.Text = processHandle.ToString();
//the launched program will receive this message as a signal that it can continue
SendNotifyMessage(processHandle, 99999, UIntPtr.Zero, IntPtr.Zero);
}
并且您正在运行的应用程序需要一个简短的自定义Windows消息处理程序来注意"保持活着"信号。
private bool allowedToLive = false;
//how long will we wait for the signal? should arrive in < 1 second
private int TimeoutSeconds = 1;
private DateTime appStartTime = DateTime.Now;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
//receiving the special message means we are allowed to live.
if(!allowedToLive)
{
allowedToLive = (m.Msg == 99999);
if (!allowedToLive && (TimeoutSeconds <= DateTime.Now.Subtract(appStartTime).Seconds))
{
//times up. quit.
Application.Exit();
}
}
}
如果您不想依赖Windows消息的时间,您可以更改目标程序以启动,但实际上在收到自定义消息之前不会开始执行任何操作。