我有一个完全正常运行的应用程序,我已转换为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);
}
}
任何人都可以向我解释为什么这不起作用或指向正确的方向吗?我非常困惑,并没有选择这样做(我被老板告知)
答案 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;单击确定。 基本上就是这样。