Deserialize causes exception "Unable to find assembly"

S

sippyuconn

Hi

Trying to copy a complex data structure with this code
public object Clone()
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, this);
ms.Position = 0;
object obj = bf.Deserialize(ms);
ms.Close();
return obj;

}


I have a text exe that works where the EXE and dll assemblies are all in
same directory. When I move the code to production I get the above exception.
The only thing I can see is difference is that the product install of files
is different

C:/Company/EXEDir
C:/Company/AssembleyDir


The EXE is executing in one directory and all the assemblies that are called
are in another dir. I scanned the web but didn't find much but there was a
reference to the fact that all the Deserializd Classes need to be in the same
dir which they are. I also added code to set dir to where the assemblies are

Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
Environment.CurrentDirectory =
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);


Not sure what else to look at ???

Thanks
 
F

Family Tree Mike

sippyuconn said:
Hi

Trying to copy a complex data structure with this code
public object Clone()
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, this);
ms.Position = 0;
object obj = bf.Deserialize(ms);
ms.Close();
return obj;

}


I have a text exe that works where the EXE and dll assemblies are all in
same directory. When I move the code to production I get the above
exception.
The only thing I can see is difference is that the product install of
files
is different

C:/Company/EXEDir
C:/Company/AssembleyDir


The EXE is executing in one directory and all the assemblies that are
called
are in another dir. I scanned the web but didn't find much but there was a
reference to the fact that all the Deserializd Classes need to be in the
same
dir which they are. I also added code to set dir to where the assemblies
are

Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
Environment.CurrentDirectory =
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);


Not sure what else to look at ???

Thanks

Here is an MS link, but basically, I think you will find it easier just to
move the dlls to the same folder as the executable.

http://msdn.microsoft.com/en-us/library/yx7xezcf.aspx
 
H

Hongye Sun [MSFT]

Thanks Mike. The link you provided is very helpful to this issue.

Hi Sippyuconn,

Thanks for your post.

This issue looks weird to me because if the Clone method is called, that
means the type of the method and its dependency types have already been
loaded into current AppDomain.

We can verify it by adding following test code before deserializing.
// --Test Code --
Assembly.Load(this.GetType().Assembly.FullName.ToString());
Console.WriteLine(this.GetType().Assembly.FullName.ToString() + "had been
loaded");
// ---------------

If this code is passed, that means the assembly and its dependencies have
already loaded into memory but Deserialize does not find them.

In order to solve such kind of problem, there are many options other than
putting EXE and DLL into same folder:

1. Strong name DLL and register it into GAC
During runtime locates assemblies, GAC is one of the place to search. It is
documented at http://msdn.microsoft.com/en-us/library/4a9t8a9a.aspx.

2. Strong name DLL and set codebase in configuration file
As described at http://msdn.microsoft.com/en-us/library/15hyw9x3.aspx
"Referenced assemblies outside the application's root directory must have
strong names and must either be installed in the global assembly cache or
specified using the <codeBase> element."
Here is an example of using codebase in app.config:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<codeBase version="2.0.0.0"
href="../AssembleyDir/myAssembly.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

3. Handle AppDomain.CurrentDomain.AssemblyResolve event
This option only works if the assembly has already been loaded into current
AppDomain (Passing the Test Code above).
Here is the sample code:
public object Clone()
{
try
{
AppDomain.CurrentDomain.AssemblyResolve += new
ResolveEventHandler(CurrentDomain_AssemblyResolve);

MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, this);
ms.Position = 0;
object obj = bf.Deserialize(ms);
ms.Close();
return obj;
}
finally
{
AppDomain.CurrentDomain.AssemblyResolve -= new
ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
}

private Assembly CurrentDomain_AssemblyResolve(object sender,
ResolveEventArgs args)
{
Assembly ayResult = null;
string sShortAssemblyName = args.Name.Split(',')[0];
Assembly[] ayAssemblies =
AppDomain.CurrentDomain.GetAssemblies();

foreach (Assembly ayAssembly in ayAssemblies)
{
if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0])
{
ayResult = ayAssembly;
break;
}
}
return ayResult;
}
The idea comes from
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/e5f0c371-b900-
41d8-9a5b-1052739f2521/

Please have a try of options above and let me know if they work for you.
Thanks.

Regards,
Hongye Sun ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
H

Hongye Sun [MSFT]

Hi Sippyuconn,

I have not heard from you for several days. I am writing to follow up this
issue and check if the issue has been well resolved. Do you mind leting us
know the current status of the issue. We will be more than happy to further
help you on that. Thanks.

Regards,
Hongye Sun ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).
 
This posting is provided "AS IS" with no warranties, and confers no rights.
 

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