Problem in Deserializing...

L

Lucas

Well, here's the situation.. It's pretty simple; just that I can't get
it to work.

I have 2 Executables..

The first one is called CSharp.exe which is a simple WinForm App. I
have a single button on the form which does the following OnClick.

// CSharp.cs
private void button1_Click(object sender, System.EventArgs e)
{
Hope y = new Hope();
BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("C:\\MyFile.bin", FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, y);
stream.Close();
}

Within the same file I have the definition of the class "Hope" as
follows:

// Also in CSharp.cs
[Serializable]
public class Hope
{
private int i;
private string s;
public long l;
public double d;

public Hope()
{
i = 1;
s = "Lucas";
l = 123;
d = 3.1415;
}
}


The code above is pretty straightforward and simply serializes an
instance of the "Hope" object to a file C:\MyFile.bin.
The project compiles (to CSharp.exe) and runs fine.

The second executable is also a Winform App called Another.exe.

The Main form again has a single button which does the following:

// Another.cs
private void button1_Click(object sender, System.EventArgs e)
{
Assembly assm = Assembly.LoadFrom(@"\..\..\..\CSharp\Csharp.exe");
Current.Load(assm.GetName());

BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("C:\\MyFile.bin", FileMode.Open,
FileAccess.Read, FileShare.Read);
Object o = formatter.Deserialize(stream);
stream.Close();
}

Here I'm simply trying to deserialize that "Hope" Object that was
serialized to file. There is no reference to the CSharp.exe (I don't
think that it's even possible). So this program has no idea what the
"Hope" class is..

However, the 'Deserialize' method works fine when the CSharp.exe is in
the same directory as Another.exe. But not if it is elsewhere. (Gives
a "Cannot find the assembly CSharp..." error!)

I tried Loading CSharp.exe into the AppDomain, but it still complains
that it cannot load the "CSharp" assembly when the Deserialize method
is invoked.

I really don't want to have to copy that assembly into the same folder
as Another.exe.

I hope that all that makes some amount of sense...
Any help would be most appreciated..

Thanks,
Lucas.
 
R

Rakesh

Hi Lucas,
The problem you are having is straight forward too.. :)
You have one class that you want to serialize using one assembly and
deserialize in another assembly, right? The easiest way to do this is to
have one common project that has the class you want to serialize. Reference
this assembly in the other 2 projects. Hope this solves ur issue.
Now the assembly not found error... In the button_Click event u r loading
an assembly using Asembly.LoadFrom api. This api looks for the the assembly
first in the local directory and then in the Global assembly cache. Since it
didnot find the asembly it gave the error.

HTH.. Do tell me if u have any problems
Rak

Lucas said:
Well, here's the situation.. It's pretty simple; just that I can't get
it to work.

I have 2 Executables..

The first one is called CSharp.exe which is a simple WinForm App. I
have a single button on the form which does the following OnClick.

// CSharp.cs
private void button1_Click(object sender, System.EventArgs e)
{
Hope y = new Hope();
BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("C:\\MyFile.bin", FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, y);
stream.Close();
}

Within the same file I have the definition of the class "Hope" as
follows:

// Also in CSharp.cs
[Serializable]
public class Hope
{
private int i;
private string s;
public long l;
public double d;

public Hope()
{
i = 1;
s = "Lucas";
l = 123;
d = 3.1415;
}
}


The code above is pretty straightforward and simply serializes an
instance of the "Hope" object to a file C:\MyFile.bin.
The project compiles (to CSharp.exe) and runs fine.

The second executable is also a Winform App called Another.exe.

The Main form again has a single button which does the following:

// Another.cs
private void button1_Click(object sender, System.EventArgs e)
{
Assembly assm = Assembly.LoadFrom(@"\..\..\..\CSharp\Csharp.exe");
Current.Load(assm.GetName());

BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("C:\\MyFile.bin", FileMode.Open,
FileAccess.Read, FileShare.Read);
Object o = formatter.Deserialize(stream);
stream.Close();
}

Here I'm simply trying to deserialize that "Hope" Object that was
serialized to file. There is no reference to the CSharp.exe (I don't
think that it's even possible). So this program has no idea what the
"Hope" class is..

However, the 'Deserialize' method works fine when the CSharp.exe is in
the same directory as Another.exe. But not if it is elsewhere. (Gives
a "Cannot find the assembly CSharp..." error!)

I tried Loading CSharp.exe into the AppDomain, but it still complains
that it cannot load the "CSharp" assembly when the Deserialize method
is invoked.

I really don't want to have to copy that assembly into the same folder
as Another.exe.

I hope that all that makes some amount of sense...
Any help would be most appreciated..

Thanks,
Lucas.
 
L

Luke

Thanks for the answer...

The thing is that I want to have a completely generic Application that
is capable of deserializing any object...

If the application is given :
1. The file that contains the serialized object
2. The path to the assembly where that object is defined

It should be able to deserialize it..

Moving the class into a separate assembly and referencing it in both
projects is as good as copying it local.

.NET allows you to instantiate an object that is defined in a remote
dll, without having to copy it local. So I'm sure that this is scenario
is possible as well..

Lucas.
 
R

Rakesh

Luke,

static void Main(string[] args)
{
BinaryFormatter bFormatter = new BinaryFormatter();
FileStream fStream = File.Open(args[0],FileMode.Open); // first
param - serialized file
Assembly asm = Assembly.LoadFrom(args[1]); // second
param - assembly containing the class def
AppDomain.CurrentDomain.Load(asm.FullName);
object obj = bFormatter.Deserialize(fStream);
}

You can load the assembly into your appdomain and deserialize the
object, fine. But you wont be able to access members of ur class because
that class wont visible at compile time, rt?
Here is one solution..
Create an interface that will generalize the classes ur going to serialize..
The classes u want to serialize will implement the interface..
Serialize this class...
Deserialize and cast it into the interface..
Access the object using interface methods..

Does this solve ur problem?
Rak
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top