Hello All,
I have a problem with serializing structs so I made a small application
here to demonstrate. Hopefully someone can explain this strange
problem.
I have a Windows (Forms) application that calls this function in a
button click event:
---------------------------------------------------------
private void button1_Click(o bject sender, System.EventArg s e)
{
CycleCount1_Str uct test1;
CycleCount1_Str uct test2;
test1.Customer = (uint) 33;
test1.Machine = (uint) 55;
BinaryFormatter bf = new BinaryFormatter ();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms , test1);
ms.Seek(0, SeekOrigin.Begi n);
MessageBox.Show ("Try to Deserialize", "", MessageBoxButto ns.OK);
test2 = (CycleCount1_St ruct)(bf.Deseri alize(ms));
MessageBox.Show ("Deserializ e ok", "", MessageBoxButto ns.OK);
ms.Close();
}
....
// the struct used above
[Serializable]
public struct CycleCount1_Str uct
{
public uint Machine;
public uint Customer;
}
---------------------------------------------------------
This works fine when I execute the application normally.
However, when I start this application (Ver2) from another one (Loader)
by creating a new thread as shown in the code below I get problems. On
the:
test2 = (CycleCount1_St ruct)(bf.Deseri alize(ms));
line I get this exception:
System.Runtime. Serialiation.Se rialiationExcep tion: Cannot find the
assembly Ver2, Version1.1. ....
Note that "Ver2" is the name of the first application.
I get a different problem when I move the "Ver2.exe" into the
"Loader.exe " directory. No it seems to find the assembly, but I now
get casting problems on that same line. I get an InvalidCastExce ption
even though test2 is a CycleCount1_Str uct. I can event change that line
to:
object o1 = bf.Deserialize( ms);
Which works, and I can look at it in the watch window and see that it
is the right type and is valid, but the exception still happens when I
cast the object to the struct. I can even create a second object o2,
set it equal to test1, and then compare it to o1 like this:
bool b1 = o.Equals(o2);
This will evaluate to true or false based on whether the application is
started in a thread of another application. When I look at them in a
watch they look exactly the same.
---------------------------------------------------------------
// This code is form "Loader" application:
private void button1_Click(o bject sender, System.EventArg s e)
{
//ThreadAppPath=" http://172.20.20.63/Visualisation/Ver2.exe";
ThreadAppPath=" ..\\..\\..\\Ver 2\\bin\\Debug\\ Ver2.exe";
//Process.Start(T hreadAppPath); // uses Internet Explorer to load
and start the application
Thread localThread = new Thread(new ThreadStart(Sta rtAssembly));
localThread.Sta rt();
}
private void StartAssembly()
{
string path=ThreadAppP ath;
try
{
Assembly myas=Assembly.L oadFrom(path);
if (myas==null) { MessageBox.Show ("Assembly does not exist!");
return; }
Type mt = myas.GetType("V er2.Form1");
if (mt==null) { MessageBox.Show ("Type does not exist!");
return; }
Object obj = myas.CreateInst ance(mt.FullNam e);
if (obj==null) { MessageBox.Show ("Object does not exist!");
return; }
Form myform=(Form)(o bj);
//method 1
//Application.Run (myform); // does work
//method 2
//myform.Show(); // does not work, because just the function
gets called ad is exiting right away
//method 3
//Application.Run (Activator.Crea teInstance(mt) as
System.Windows. Forms.Form); // does work like method 1
AppDomain newDomain = AppDomain.Creat eDomain("newDom ain");
//method 4
newDomain.Execu teAssembly(path ); // works fine
AppDomain.Unloa d(newDomain);
}
catch (Exception ex)
{
MessageBox.Show ("Could not find and start the Visualisation!\ n"
+ ex.ToString(), "Error!", MessageBoxButto ns.OK, MessageBoxIcon. Error);
}
}
---------------------------------------------
Anyone know what's going on here?
Thanks in advance,
CowPad
I have a problem with serializing structs so I made a small application
here to demonstrate. Hopefully someone can explain this strange
problem.
I have a Windows (Forms) application that calls this function in a
button click event:
---------------------------------------------------------
private void button1_Click(o bject sender, System.EventArg s e)
{
CycleCount1_Str uct test1;
CycleCount1_Str uct test2;
test1.Customer = (uint) 33;
test1.Machine = (uint) 55;
BinaryFormatter bf = new BinaryFormatter ();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms , test1);
ms.Seek(0, SeekOrigin.Begi n);
MessageBox.Show ("Try to Deserialize", "", MessageBoxButto ns.OK);
test2 = (CycleCount1_St ruct)(bf.Deseri alize(ms));
MessageBox.Show ("Deserializ e ok", "", MessageBoxButto ns.OK);
ms.Close();
}
....
// the struct used above
[Serializable]
public struct CycleCount1_Str uct
{
public uint Machine;
public uint Customer;
}
---------------------------------------------------------
This works fine when I execute the application normally.
However, when I start this application (Ver2) from another one (Loader)
by creating a new thread as shown in the code below I get problems. On
the:
test2 = (CycleCount1_St ruct)(bf.Deseri alize(ms));
line I get this exception:
System.Runtime. Serialiation.Se rialiationExcep tion: Cannot find the
assembly Ver2, Version1.1. ....
Note that "Ver2" is the name of the first application.
I get a different problem when I move the "Ver2.exe" into the
"Loader.exe " directory. No it seems to find the assembly, but I now
get casting problems on that same line. I get an InvalidCastExce ption
even though test2 is a CycleCount1_Str uct. I can event change that line
to:
object o1 = bf.Deserialize( ms);
Which works, and I can look at it in the watch window and see that it
is the right type and is valid, but the exception still happens when I
cast the object to the struct. I can even create a second object o2,
set it equal to test1, and then compare it to o1 like this:
bool b1 = o.Equals(o2);
This will evaluate to true or false based on whether the application is
started in a thread of another application. When I look at them in a
watch they look exactly the same.
---------------------------------------------------------------
// This code is form "Loader" application:
private void button1_Click(o bject sender, System.EventArg s e)
{
//ThreadAppPath=" http://172.20.20.63/Visualisation/Ver2.exe";
ThreadAppPath=" ..\\..\\..\\Ver 2\\bin\\Debug\\ Ver2.exe";
//Process.Start(T hreadAppPath); // uses Internet Explorer to load
and start the application
Thread localThread = new Thread(new ThreadStart(Sta rtAssembly));
localThread.Sta rt();
}
private void StartAssembly()
{
string path=ThreadAppP ath;
try
{
Assembly myas=Assembly.L oadFrom(path);
if (myas==null) { MessageBox.Show ("Assembly does not exist!");
return; }
Type mt = myas.GetType("V er2.Form1");
if (mt==null) { MessageBox.Show ("Type does not exist!");
return; }
Object obj = myas.CreateInst ance(mt.FullNam e);
if (obj==null) { MessageBox.Show ("Object does not exist!");
return; }
Form myform=(Form)(o bj);
//method 1
//Application.Run (myform); // does work
//method 2
//myform.Show(); // does not work, because just the function
gets called ad is exiting right away
//method 3
//Application.Run (Activator.Crea teInstance(mt) as
System.Windows. Forms.Form); // does work like method 1
AppDomain newDomain = AppDomain.Creat eDomain("newDom ain");
//method 4
newDomain.Execu teAssembly(path ); // works fine
AppDomain.Unloa d(newDomain);
}
catch (Exception ex)
{
MessageBox.Show ("Could not find and start the Visualisation!\ n"
+ ex.ToString(), "Error!", MessageBoxButto ns.OK, MessageBoxIcon. Error);
}
}
---------------------------------------------
Anyone know what's going on here?
Thanks in advance,
CowPad