运行从另一个exe转换为DLL的exe

时间:2016-09-21 18:28:52

标签: c# .net windows dll

我有一个完全正常运行的应用程序,我已转换为Dll。

我需要能够从exe运行该应用程序(现在是dll)。我添加了dll作为新exe的引用,并试图从dll中使用的命名空间中实例化一个frmMain对象,并像在任何其他应用程序中一样显示它。

但是,我在exe中转换为dll的几个引用中得到了一堆空引用异常。

我也在这里尝试了解决方案Launch Dll using C# program 并尝试跳转到Program.cs Main()函数,此时我得到一个"必须在应用程序中创建第一个IWin32Window对象之前调用SetCompatibleTextRenderingDefault。"错误。

这是dll的program.cs

namespace VTRS
{
    class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>

        [STAThread]
        static void  Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMain());
        }

        //had to add this because exe can't find Main
        public void invokeMain()
        {
            Main();
        }

        //you have to have a constructor for the exe to instantiate this class
        public Program()
        {

        }
    }
}

这是新的应用程序代码

private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                System.Reflection.Assembly dll1 = System.Reflection.Assembly.LoadFile(Application.StartupPath + "\\VTRSTCACodeMaintenance.dll");
                if (dll1 != null)
                {
                    object obj = dll1.CreateInstance("VTRS.Program");
                    if (obj != null)
                    {
                        System.Reflection.MethodInfo mi = obj.GetType().GetMethod("invokeMain");
                        mi.Invoke(obj, new object[0]);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

任何人都可以向我解释为什么这不起作用或指向正确的方向吗?我非常困惑,并没有选择这样做(我被老板告知)

3 个答案:

答案 0 :(得分:1)

您不需要反射,也不需要执行原始.exe文件的Main()方法(实际上,您应该删除它,如果该项目只是一个简单的DLL)

您不需要反思,因为一旦您在新项目中添加了程序集作为参考,所有公共类型和成员都可以在您的新项目中访问。只需确保您已将frmMain声明为public(这是Visual Studio中的默认设置,因此它可能已为public)。然后,您需要做的就是通常用来表示形式的所有反射工具:

frmMain form = new frmMain();

form.Show();

甚至只是:

new frmMain().Show();

您不需要执行Main()方法,因为它所做的只是新项目已经完成的工作:

  • [STAThread]将入口点线程(成为主UI线程)设置为STA公寓模型。但是,由于您的新项目(似乎)是一个Winforms程序,您已经有一个入口点和一个已正确配置的主UI线程。它是引发Click button1事件的线程,因此在调用button1_Click()方法时,您正在该线程中执行。
  • 同样,调用设置视觉样式和文本呈现。您不需要再次调用它们,因为您的新项目在启动时会调用它们。
  • 最后,致电Application.Run(new frmMain())。这个调用有三个效果:它创建一个frmMain()的实例(你可以自己做,如上所述),然后将该实例传递给Application.Run()方法,以便该方法可以调用{{1表单上的方法(同样,你可以自己做),然后Show()方法位于循环调度窗口消息中。您也不需要这样做,因为您已经在Winforms程序中已经调用了Run(),并且已经在调度窗口消息(这是Application.Run()事件的方式首先被提升了。)

因此,请停止尝试调用Click方法,只需确保要使用的表单类为Main(),以便从引用程序集的项目中看到它,然后创建并按照在同一项目中声明它的方式显示public对象。

答案 1 :(得分:0)

我认为这是因为类程序的访问修饰符只是将其更改为公共 另外,如果你不加载一个可更改的dll(动态),为什么你不像以前那样通过其他dll引用它来调用项目,并从程序类中调用main(你仍然需要程序类是公共的)

答案 2 :(得分:0)

在Solution Explorer中,在项目视图中右键单击References - &gt;添加新参考 - &gt;浏览 - &gt;找到VTRSTCACodeMaintenance.dll(它应该在你的\ bin \ debug文件夹中) - &gt;双击它 - &gt;单击确定。 基本上就是这样。