For C # as type conversion and Assembly. LoadFrom tracking !,

Source: Internet
Author: User
Tags mscorlib

For C # as type conversion and Assembly. LoadFrom tracking !,
Background:

Not long ago, I released a debugging tool: A visual debugging tool that is essential for. NET developers)

The effect is as follows:

Later, a small number of users reported that the tool could not be used (no response or exceptions )~~~

Next, we recommend that you change the computer environment for a small number of users ~~~

Therefore, I assume that Microsoft. VisualStudio. DebuggerVisualizers. dll versions in VS environment are inconsistent.

Therefore, we recommend that you download the source code and rereference it to compile the code !!!

This tool has been installed in the VB. NET section of the CSDN Forum. Due to the large number of attacks, the system had been secretly upgraded several times to solve the problem of throwing exceptions, but it still had not been fundamentally resolved ~~~~

In the past two days, a classmate named zihan found me and hoped that I could help him solve the problem.

I tried to update the new version and sent it to him, all of which gave feedback on the effect of wood.

He had to download the source code and perform remote debugging on his computer.

Last night at half past one, I finally buried the two traps I found !!!

The following describes the two pitfalls:

1: as conversion pit:

Let's take a look at the source code. This is the result of deserialization. convert it to Table and then bind it:

 protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)        {            MDataTable dt = objectProvider.GetObject() as MDataTable;            FormCreate.BindTable(windowService, dt, null);        }

In this Code, the debugging result is as follows:

1: The object obtained by objectProvider. GetObject () is MDataTable, and CYQ. Data. Table. MDataTable is also returned by GetType. 2: as MDataTable returns null?
Why? A big question mark in front of me, the same type, how not to pass?

So I changed the code:

MDataTable dt=(MDataTable)objectProvider.GetObject()

Throwing an exception:

* *************************** System. invalidCastException: [A] CYQ. data. table. the MDataTable cannot be forcibly converted to [B] CYQ. data. table. MDataTable.
Type A is derived from "CYQ. Data, Version = 5.7.5.5, Culture = neutral, PublicKeyToken = null" (in the byte array context "LoadNeither ).
Type B is derived from "CYQ. data, Version = 5.7.5.5, Culture = neutral, PublicKeyToken = null (In the context "LoadFrom", "C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ Common7 \ Packages \ Debugger \ Visualizers \ CYQ. data. dll ). In CYQ. Visualizer. MDataTableVisualizer. Show (windowService, IVisualizerObjectProvider objectProvider) in Microsoft. VisualStudio. Examples. Examples. ManagedShim. DelegatedHost. CreateViewer (IntPtr hwnd, HostServicesHelper hsh, guest proxy)

What is this exception? Let's talk about it first:

1: as type conversion: Only checks whether the types in the context are consistent (or implicit conversion exists). If the conversion fails, null is returned. No exception is thrown. 2: Forced type conversion: type conversion is attempted. If the conversion fails, an exception is thrown.

Okay, the first pitfall, the same type, no exception, buried deep enough !!!

AS is called: this pitfall cannot blame me. If you want to blame Assembly. LoadFrom, who asked you to separate us in different contexts.

2: pit of Assembly. LoadFrom

Here I will post a detailed exception message:

Mscorlib assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. NET/Framework/v4.0.30319/mscorlib. dll ---------------------------------------- Microsoft. visual Studio. platform. appDomainManager assembly version: 12.0.0.0 Win32 version: 12.0.21005.1 basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/Microsoft. visual Studio. platform. appDomainManager/v4.0 _ 12.0.0.0 _ b03f5f7f11d50a3a/Microsoft. visual Studio. platform. appDomainManager. dll -------------------------------------- System assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/System/v4.0 _ 4.0.0.0 _ b77a5c561934e089/System. dll ---------------------------------------- System. xml assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/System. xml/v4.0 _ 4.0.0.0 _ b77a5c561934e089/System. xml. dll ---------------------------------------- System. configuration assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/System. configuration/v4.0 _ 4.0.0.0 _ b03f5f7f11d50a3a/System. configuration. dll ---------------------------------------- System. windows. forms assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/System. windows. forms/v4.0 _ 4.0.0.0 _ b77a5c561934e089/System. windows. forms. dll ---------------------------------------- System. drawing assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/System. drawing/v4.0 _ 4.0.0.0 _ b03f5f7f11d50a3a/System. drawing. dll ---------------------------------------- Microsoft. visual Studio. debuggerVisualizers assembly version: 12.0.0.0 Win32 version: 12.0.21005.1 basic code: file: // C:/Windows/assembly/GAC_MSIL/Microsoft. visual Studio. debuggerVisualizers/12.0.0.0 _ b03f5f7f11d50a3a/Microsoft. visual Studio. debuggerVisualizers. dll ---------------------------------------- CYQ. visualizer assembly version: 2.0.0.5 Win32 version: 2.0.0.5 basic code: file: // C:/Program % 20 Files % 20 (x86) /Microsoft % 20 Visual % 20 Studio % 2012.0/Common7/Packages/Debugger/Visualizers/CYQ. visualizer. dll ---------------------------------------- CYQ. data assembly version: 5.7.5.5 Win32 version: 5.7.5.5 basic code: file: // C:/Program % 20 Files % 20 (x86) /Microsoft % 20 Visual % 20 Studio % 2012.0/Common7/Packages/Debugger/Visualizers/CYQ. data. DLL ---------------------------------------- System. data assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_32/System. data/v4.0 _ 4.0.0.0 _ b77a5c561934e089/System. data. dll ---------------------------------------- System. core Assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/System. core/v4.0 _ 4.0.0.0 _ b77a5c561934e089/System. core. dll ---------------------------------------- CYQ. data assembly version: 5.7.5.5 Win32 version: 12.0.21005.1 basic code: file: // C:/Windows/assembly/GAC_MSIL/Microsoft. visual Studio. debuggerVisualizers/12.0.0.0 _ b03f5f7f11d50a3a/Microsoft. visual Studio. debuggerVisualizers. dll ---------------------------------------- System. numerics assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/System. numerics/v4.0 _ 4.0.0.0 _ b77a5c561934e089/System. numerics. dll ---------------------------------------- System. transactions assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_32/System. transactions/v4.0 _ 4.0.0.0 _ b77a5c561934e089/System. transactions. dll ---------------------------------------- System. enterpriseServices assembly version: 4.0.0.0 Win32 version: 4.0.30319.36373 built by: FX452RTMLDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_32/System. enterpriseServices/v4.0 _ 4.0.0.0 _ b03f5f7f11d50a3a/System. enterpriseServices. dll ---------------------------------------- System. windows. forms. resources assembly version: 4.0.0.0 Win32 version: 4.0.30319.34209 built by: FX452RTMGDR basic code: file: // C:/Windows/Microsoft. net/assembly/GAC_MSIL/System. windows. forms. resources/v4.0 _ 4.0.0.0 _ zh-Hans_b77a5c561934e089/System. windows. forms. resources. dll ----------------------------------------**************

Two core sections of the exception:

CYQ. visualizer assembly version: 2.0.0.5 Win32 version: 2.0.0.5 basic code: file: // C:/Program % 20 Files % 20 (x86) /Microsoft % 20 Visual % 20 Studio % 2012.0/Common7/Packages/Debugger/Visualizers/CYQ. visualizer. dll ---------------------------------------- CYQ. data assembly version: 5.7.5.5 Win32 version: 5.7.5.5 basic code: file: // C:/Program % 20 Files % 20 (x86) /Microsoft % 20 Visual % 20 Studio % 2012.0/Common7/Packages/Debugger/Visualizers/CYQ. data. DLLCYQ. data assembly version: 5.7.5.5 Win32 version: 12.0.21005.1 basic code: file: // C:/Windows/assembly/GAC_MSIL/Microsoft. visual Studio. debuggerVisualizers/12.0.0.0 _ b03f5f7f11d50a3a/Microsoft. visual Studio. debuggerVisualizers. dll

From the Exception error message above, the first sight is B. After all, it is not surprising ~~~~

It took about 8 minutes to finally respond. After careful consideration, we can find that:

1: CYQ. Data is loaded by CYQ. Visualizer. dll in the same directory. 2: It is loaded by Microsoft. VisualStudio. DebuggerVisualizers. dll (In the context "LoadNeither", the ghost knows what this LoadNeither is ).

As a result, the same dll is loaded into two different paths, resulting in different context environments, rather than mutual conversion ~~~~

Why are most of them normal and a small part of the environment doing this? I don't know yet. Microsoft is also an easy-to-use tool ~~~

Okay, now you know about the pitfalls. The next step is how to bury them: 1. Thinking 1: Test Assembly. Load, Assembly. LoadFile, Assembly. LoadFrom

I wrote several test codes:

 string filePath = AppDomain.CurrentDomain.BaseDirectory + "cyq\\CYQ.Data.dll";            byte[] bytes = File.ReadAllBytes(filePath);            Assembly ass = Assembly.Load(bytes);            object o = ass.CreateInstance("CYQ.Data.Table.MDataTable"); MDataTable dt = (MDataTable)o;

Failed!

String filePath = AppDomain. currentDomain. baseDirectory + "cyq \ CYQ. data. dll "; Assembly ass = Assembly. loadFrom (filePath); Assembly. loadFile (filePath );... omitted...

All failed !!

To test these three methods, we mainly want to see if there are any differences in nature, especially after the combination of strong signatures ~~~

Try adding a strong signature to the dll ~~~

Still failed ~~~~

It seems that I think too much about it. It is impossible to convert objects loaded in different dll paths ~~~~

2: Trap thinking 2: Strong signature DLL, and registered to GAC

Theoretically, this method is 100% feasible. After all, the path references are consistent.

The method is also simple: adding a registration command through the code is not difficult ~~~~

Think about other more concise methods!

3: Trap thinking 3: finding a stable intermediary

Since the problem occurs in the pre-serialization MDataTable and post-deserialization MDataTable dll in different contexts.

Find a third-party intermediary: MDataTable => intermediary (serialization) = "intermediary (deserialization) => MDataTable

You can think of two types of data: json or able.

Then the code starts:

DataTable is used for serialization.

During deserialization:

After finishing the job, re-compile the job and send it to the user for testing. The job passes normally ~

Tools:

Http://www.cnblogs.com/cyq1162/p/6027051.html

Summary:

1: for the first time in so many years, it may have been unexpected to plant a pitfall on the as conversion.

2: The same dll types loaded by different paths cannot be transferred to each other. After so many years, we have finally met each other, which means that the mountains will still be the same.

But since the version number and signature are consistent and the signature cannot be forged, why not?

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.