Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何确保通过另一个可执行文件打开一个可执行文件?_C#_Windows - Fatal编程技术网

C# 如何确保通过另一个可执行文件打开一个可执行文件?

C# 如何确保通过另一个可执行文件打开一个可执行文件?,c#,windows,C#,Windows,有一个巧妙的小技巧,你可以使用它,让操作系统永远不会锁定.dll的/.exe需要运行的.exe 假设我们的目录如下所示: >opener.exe >actualProgram.exe >dependency.dll private void LaunchApplication() { ProcessStartInfo start = new ProcessStartInfo(); //you could pass in arguments here if you wanted st

有一个巧妙的小技巧,你可以使用它,让操作系统永远不会锁定
.dll
的/
.exe
需要运行的
.exe

假设我们的目录如下所示:

>opener.exe >actualProgram.exe >dependency.dll
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);
}
我们还可以在其中添加更多的逻辑,我们可以使用这些逻辑来实际替换/更新
actualProgram.exe
,尽管进程的实例正在打开。试试看:当通过“opener”加载依赖项和“实际”程序时,您将能够删除/修改/替换依赖项和“实际”程序。显然,这有其好处,即使更新更容易

但在“actual.exe”中,如何确保它是通过另一个可执行文件加载的,并且知道它是在没有对
.exe
进行锁定的情况下加载的?如果有人只是加载“actual.exe”,即不通过“opener”,我希望确保进程立即退出

暗示

  • 将命令行参数传递给
    actualProgram.exe
    ,让它知道它是由启动器启动的。(在oleksii对OP的评论中也提出)
  • 在启动器中设置可由子进程继承的环境变量
  • 使用记录在案的方法之一获取父进程id,并使用该方法获取有关启动进程的信息。(当然,如果父进程终止,Windows可以自由地将PID重新分配给新进程。)
  • 在启动程序中创建一个内存映射文件/命名管道/等,用于将信息传递给子级
  • 在子对象中手动加载和卸载库引用。如果它们是.Net程序集,则可以使用
    AssemblyResolve
    事件,将文件从磁盘加载到字节数组中,并使用
    Assembly.Load(byte[],byte[])
    重载
  • 注意:只要在修改/移动/删除程序集之前手动或在运行时加载所有程序集,就可以了。此外,加载DLL后更改DLL可能对正在运行的进程没有影响。我说可能在这两种情况下都是这样,因为通常在运行时不使用库是一个好主意,特别是在您没有手动加载它们的情况下

    另见:


    在应用程序启动后向其发送自定义消息如何?启动的代码如下:

    >opener.exe >actualProgram.exe >dependency.dll
    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;
    //我们要等多久信号?应在<1秒内到达
    私有int-TimeoutSeconds=1;
    private DateTime appStartTime=DateTime.Now;
    受保护的覆盖无效WndProc(参考消息m)
    {
    基准WndProc(参考m);
    //收到这个特别的信息意味着我们可以活下去。
    如果(!allowedToLive)
    {
    allowedToLive=(m.Msg==99999);
    
    如果(!allowedToLive&&(TimeoutSeconds是一种有趣的方法,以前从未见过。我想如果它不是安全关键的,您可以在
    actualProgram.exe
    中看到一个参数,
    opener.exe
    将提供该参数。如果用户只需单击
    actualProgram.exe
    它应该检查该参数是否存在并退出[在此处插入您的操作]。例如:
    opener=>actualProgram calledByOpener
    actualProgram
    中有一个
    if(args[0]!=“calledByOpener”)exit-1;
    有一些防止偶然误用的保护措施,如oleksii建议的,但您无法保护自己不受某些人的影响,这些人决定强制您的应用程序运行(对于初学者,他们可以分解代码,移除保护措施,然后重新组装)。如果您只是想阻止某人从Explorer或cmd启动
    actual.exe
    ,请将其重命名为类似于
    userdata.dat
    ,并将您的开启器重命名为
    actual.exe
    。该名称不会阻止应用程序域加载它,但会阻止Explorer或cmd打开它。而且会阻止大多数用户使用它如果你选择了正确的名字,你就不会去戳它。