6

This is what im doing:

byte[] bytes = File.ReadAllBytes(@Application.StartupPath+"/UpdateMainProgaramApp.exe");
Assembly assembly = Assembly.Load(bytes);
// load the assemly

//Assembly assembly = Assembly.LoadFrom(AssemblyName);

// Walk through each type in the assembly looking for our class
MethodInfo method = assembly.EntryPoint;
if (method != null)
{
    // create an istance of the Startup form Main method
    object o = assembly.CreateInstance(method.Name);
    // invoke the application starting point
    try
    {
        method.Invoke(o, null);
    }
    catch (TargetInvocationException e)
    {
        Console.WriteLine(e.ToString());
    }
}

The problem is that it throws that TargetInvocationException - it finds that the method is main, but it throws this exception since on this line:

object o = assembly.CreateInstance(method.Name);

o is remaining null. So I dug a bit into that stacktrace and the actual error is this:

InnerException = {"SetCompatibleTextRenderingDefault should be called before creating firstfirst IWin32Window object in the program"} (this is my translation since it gives me the stacktrace in half hebrew half english since my windows is in hebrew.)

What am i doing wrong?

Justin
  • 84,773
  • 49
  • 224
  • 367
Eli Braginskiy
  • 2,867
  • 5
  • 31
  • 46

3 Answers3

4

The entry point method is static, so it should be invoked using a null value for the "instance" parameter. Try replacing everything after your Assembly.Load line with the following:

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

If the entry point method is not public, you should use the Invoke overload that allows you to specify BindingFlags.

Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49
1

if you check any WinForm application Program.cs file you'll see there always these 2 lines

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

you need to call as well them in your assembly. At least this is what your exception says.

Eugen
  • 2,934
  • 2
  • 26
  • 47
  • @Eugen how can i do this? i am calling the main method which should activate this lines dont it? – Eli Braginskiy Apr 29 '11 at 22:25
  • do you have access to the source code of the assembly? if yes, then create inside a method, say "Init" and place the 2 lines inside it, and before calling Main method call the Init. In case you don't have the source code, then I need to thing :) – Eugen Apr 29 '11 at 22:38
  • btw, you didn't tell anything about your application. what is it? if you call these lines in your application before calling the Main method from that assembly it will help as well. – Eugen Apr 29 '11 at 22:40
  • @Eugen I have the source code, i created this init. now im tryint this: `code`object oo = assembly.CreateInstance("Init");`code` but object "oo" stays null-why? – Eli Braginskiy Apr 29 '11 at 22:46
  • 2
    you can't call CreateInstance on a method. You need to Invoke the method. see this article for a sample http://www.daniweb.com/software-development/csharp/threads/98148 – Eugen Apr 29 '11 at 22:51
  • @Eugen in this line: `code`_Type = assembly.GetType("UpdateMainProgaramApp");`code` should i write the namespace (UpdateMainProgramApp) or since this is my class :`code` public partial class Form1 : Form`code` i should write "Form1"? because i tried with both and _Type stays null... – Eli Braginskiy Apr 29 '11 at 23:07
0

How about calling it in it's own process?

Community
  • 1
  • 1
surfen
  • 4,644
  • 3
  • 34
  • 46
  • I need to load it in memory beacuse i need to delete a dll of it later... so that does`nt help. – Eli Braginskiy Apr 29 '11 at 22:44
  • But calling another process also causes it to be loaded into memory. I don't think that you can delete a dll that has been loaded and it's containing process is still running. See also: [Delete Dll w/o closing application](http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/caba700d-1011-4c48-8a39-e9513c81baad) – surfen Apr 29 '11 at 23:14
  • @surfen exactly -what you see -the first answer is stating: if you load the application into memory then the assembly is unrelated- therfore you can delete it – Eli Braginskiy Apr 29 '11 at 23:17
  • Oh I see... nice trick :) But you're loading exe, so if exe references another dll, then the dll assembly would be related and blocked, wouldn't it? – surfen Apr 29 '11 at 23:22
  • Im not sure but im trying to find out :) – Eli Braginskiy Apr 29 '11 at 23:27
  • @Blue The referenced assembly will also be loaded into memory and locked. If you want to be able to delete an assembly while it is loaded into memory you need to copy the assembly elsewhere so that you can load it from another location (leaving the original unlocked). – Justin Apr 30 '11 at 03:15