通过控制台应用程序动态加载的 DLL 中的 Process.Start() 使用 Windows 窗体运行 EXE 时出现问题

问题描述 投票:0回答:1

标题: 通过控制台应用程序动态加载的 DLL 中的 Process.Start() 使用 Windows 窗体运行 EXE 时出现问题(C#、.NET Framework 4.5.2)

描述: 我正在使用 C# (.NET Framework 4.5.2) 开发一个控制台应用程序,它使用反射动态加载 DLL(也是我开发的)。在这个 DLL 中,有一个方法使用

Process.Start()
来运行包含 Windows 窗体界面的 EXE 文件。但是,当我通过反射调用此方法时,EXE 启动,但 Windows 窗体界面没有出现。

控制台程序代码:

// Example of the code that loads the DLL
Assembly assembly = Assembly.LoadFrom("MyDLL.dll");
Type type = assembly.GetType("MyNamespace.MyClass");
MethodInfo method = type.GetMethod("MyMethod");
object instance = Activator.CreateInstance(type);
method.Invoke(instance, null);

DLL代码(相关片段):

public class MyClass
{
    public void MyMethod()
    {
        // Processing before starting the EXE
        var startExe = new ProcessStartInfo();
        startExe.FileName = "PathToMyExecutable.exe";
        startExe.Arguments = "\"arg1\" \"arg2\" \"arg3\"";
        startExe.WindowStyle = ProcessWindowStyle.Hidden;
        startExe.CreateNoWindow = true;
        Process.Start(startExe);
    }
}

问题:

  • DLL代码执行正确(我用日志消息验证),可执行文件启动,但是当控制台程序通过反射调用该方法时,带有Windows窗体界面的EXE窗口没有出现。
  • 我没有收到任何异常或错误,窗口根本不显示。

我尝试过的:

  1. 我研究了几种解决方案,有些提到使用
    ProcessStartInfo
    UseShellExecute
    CreateNoWindow
    选项,但它没有解决问题。
  2. 我测试了在反射场景之外(直接从另一个上下文)调用EXE,EXE的Windows Forms界面正常显示。
  3. 我还测试了从非 .NET 程序(例如 C/C++)加载相同的 DLL,并且 EXE 及其窗口显示正确,因此我怀疑该问题与在控制台应用程序中使用反射有关。

限制:

  • 控制台项目无法直接引用 DLL。 DLL 通过反射动态加载。
  • 控制台应用程序不应事先了解 DLL 或 EXE。

问题: 在通过反射加载的 DLL 中使用

Process.Start()
是否有任何限制或特定配置会阻止 EXE 的 Windows 窗体窗口出现?如何确保EXE正确运行并显示其窗口?

附加信息:

  • .NET框架4.5.2
  • DLL 已加载,其方法执行没有错误,EXE 已启动,但 Windows 窗体窗口未出现。
  • 我已经尝试使用各种选项设置
    ProcessStartInfo
    ,例如
    UseShellExecute = true
    WindowStyle = ProcessWindowStyle.Normal
    ,但没有成功。

预先感谢您的帮助!

c# .net winforms reflection process
1个回答
0
投票

第一个错误是:在 DLL 中使用

global::
(默认)命名空间,而不是
MyNamespace
。如果您只是提供了一个没有命名空间声明的剪切代码示例,那么这是另一个错误,错误的问题报告错误。

第二个错误不可能是问题的根源,但仍然是一个错误。您的课程

MyClass
MyClass.MyMethod
不应公开。反射可以获取类型及其成员并执行实例化(如果它们是非公共的),但不使用公共提供了一个重要的好处:隔离。您的插件(动态)程序集不能直接使用。

MyMethod
的行为在我看来完全不合理。为什么要使用另一级间接并启动单独的进程?它可以是您可以在相同或不同进程中直接反映和使用的另一个 .NET 程序集。为什么需要不同的进程(而不是同一进程的线程)?不管怎样,你没有告诉我们你的最终目标和意图。为了获得更好的答案,您应该。

© www.soinside.com 2019 - 2024. All rights reserved.