locked
Troubles with invoking EntryPoint of Assembly RRS feed

  • Question

  • Hi all.
    I have to launch any exe-assembly, stored as byte[]. This array have not to be saved to disk, so only way is 

    Code Block
    byte[] b;
    ////
    Assembly a = Assembly.Load(b);
    a.EntryPoint.Invoke(null, null);

     


    With this method assebly after executing throws an exception "Application.SetCompatibleTextRenderingDefault must be called before the first IWin32Window object is created". But normally this assembly works perfectly.

    This code:

    Code Block
    AppDomain ad = AppDomain.CreateDomain("testDomain");
    ad.ExecuteAssembly(fileName);

     

     

    launches assembly perfectly! But it loads it from disk, what, as I sad, is forbidden.

    Is any way to launch assembly via Assembly class? Or via AppDomain, but from byte[]?

    Monday, October 15, 2007 5:59 PM

Answers

  • Hi wdk,

    For Windows forms applicaiton, change the code like this should solve this issue

    Code Block

    String asmPath = @"D:\Working\FromsTest.exe";

    Byte[] asmData = File.ReadAllBytes(asmPath);

    Assembly asm = Assembly.Load(asmData);

    Object[] Args = new Object[0];

    asm.EntryPoint.Invoke(null, Args);

                                                          

    Hope this helps!

    Thanks!

    Wednesday, October 17, 2007 8:01 AM
  • Hi wdk,

    I tested your project, and I found the root cause of this issue, for the code I posted, you can’t run it in a windows forms application to invoke another windows forms application for the following reasons:

    For the Application.SetCompatibleTextRenderingDefault Method invoked in the winforms’ main method, you should never call this method if your Windows Forms code is hosted in another application, such as Internet Explorer. Only call this method in stand-alone Windows Forms applications.

    However, even if you comment this method, you can’t run Application.Run(new Form1()) in a already running winforms application, because in windows you cannot start more than one message loop in a single thread.

    For an alternative, I suggest you can Process.Start method to start another winforms application in an already running winforms application. Or you can just use the code I provided in a console application.

    Thanks!

    Friday, October 19, 2007 2:49 AM

All replies

  • The framework is trying to display a dialog, named TrustManagerPromptUI.  That fails because you already created one or more windows.  Not exactly sure what that dialog is trying to do, I'd guess it is trying to warn you that there is an issue with trust.
    Tuesday, October 16, 2007 12:17 AM
  • So, what I have to do? AppDomain.ExecuteAssemlby works, after all, what is it doing to make it work?
    Tuesday, October 16, 2007 9:31 AM
  • Up Sad
    Tuesday, October 16, 2007 7:50 PM
  • Hi wdk,

    I did a test on your code, and I’ve figure out this issue, please refer to the following code example, and note the comments.

        1 String asmPath = @"D:\Working\ExTest.exe";

        2 Byte[] asmData = File.ReadAllBytes(asmPath);

        3 

        4 Assembly asm = Assembly.Load(asmData);

        5 

        6 Object[] args = new Object[1]; // Like common C# application, ExText's Main method need a argument which is a String[]

        7 args[0] = new String[0];       // You can change it according to your need.

        8 

        9 asm.EntryPoint.Invoke(null, args);

     

    This runs ok on my machine!

    Hope this helps!

    Thanks!

    Wednesday, October 17, 2007 4:37 AM
  • Can you post here your test application's Main method?
    Is it Windows Forms application?
    Wednesday, October 17, 2007 6:59 AM
  • Hi wdk,

    By default, an application created by Visual Studio has the same entrypoint function method signature, no matter console application or windows forms application:

    Code Block

    // in Program.cs:

    Main(String[] args)

     

    Have you tried the code I provided?

    Thanks!

    Wednesday, October 17, 2007 7:06 AM
  • In WinForms Application by default Main has no arguments, and your code throws an "Wrong arguments number" exception in loaded assembly.
    After modifying Main to take argumets I have an exception about IWin32Window like in my first post.
    Wednesday, October 17, 2007 7:52 AM
  • Hi wdk,

    For Windows forms applicaiton, change the code like this should solve this issue

    Code Block

    String asmPath = @"D:\Working\FromsTest.exe";

    Byte[] asmData = File.ReadAllBytes(asmPath);

    Assembly asm = Assembly.Load(asmData);

    Object[] Args = new Object[0];

    asm.EntryPoint.Invoke(null, Args);

                                                          

    Hope this helps!

    Thanks!

    Wednesday, October 17, 2007 8:01 AM
  • Yes, it works to pass needed number of parameters. But trouble isn't here, Exception about IWin32Window still appears. If your test application is WinForms and your code launches it successfully, can you post your Main here? Maybe it will help to find the reason of this exception and way to solve.
    Wednesday, October 17, 2007 1:02 PM
  • Hi wdk,

    What happens if you run your winforms application alone?

    Since you came across an exception, could you please cover it in more details? You can post its stack trace, and inner exception here.

    And till now, you have not told us anything about your environment, I don’t think we can help you without the necessary information to reproduce this issue. And I tested my code on a winforms application, the result is fine. My machine is Windows XP sp2 with Visual Studio 2005 SP1.

    And I suggest that you can write a very simple winforms application and try again. This can separate this issue and help finding the root cause.

    Thanks!

    Thursday, October 18, 2007 3:10 AM
  • Ok, my OS is WinXP Pro SP2 and IDE is VS2005 without any SP's.

    Here, I created two small and very simple projects to demonstrate the trouble.

    testForm is application to launch, with just one Form.

    appLauncher is application with three functions launching testForm from different ways.

    I uploaded it here: http://www.sendspace.com/file/lsj4r7

    Please, see this...

    Thursday, October 18, 2007 4:24 PM
  • Hi wdk,

    I tested your project, and I found the root cause of this issue, for the code I posted, you can’t run it in a windows forms application to invoke another windows forms application for the following reasons:

    For the Application.SetCompatibleTextRenderingDefault Method invoked in the winforms’ main method, you should never call this method if your Windows Forms code is hosted in another application, such as Internet Explorer. Only call this method in stand-alone Windows Forms applications.

    However, even if you comment this method, you can’t run Application.Run(new Form1()) in a already running winforms application, because in windows you cannot start more than one message loop in a single thread.

    For an alternative, I suggest you can Process.Start method to start another winforms application in an already running winforms application. Or you can just use the code I provided in a console application.

    Thanks!

    Friday, October 19, 2007 2:49 AM
  • Yes, this is it! Trouble was in Message Loop! Great thanks!

     

    I used another solution to keep ability to load assebly from byte[] in WinForm application, and it's very simple. You can just start app in new thread!

     

    This is modification for my test application:

     

    System.Threading.Thread th;

     

    private void button3_Click(object sender, EventArgs e)

    {

    th = new System.Threading.Thread(new System.Threading.ThreadStart(launcher));

    th.Start();

    }

    private void launcher()

    {

    byte[] b = System.IO.File.ReadAllBytes("testForm.exe");

    System.Reflection.Assembly asm = System.Reflection.Assembly.Load(b);

    asm.EntryPoint.Invoke(null, new object[0]);

    }

     

     

    Thanks again!
    Friday, October 19, 2007 1:07 PM