SQL Server: “CREATE ASSEMBLY for assembly 'Test' failed because assembly 'Test' is malformed or not a pure .NET assembly.”

人走茶凉 提交于 2019-12-18 06:58:05

问题


I get this error when I attempt to load a mixed mode C++/CLI assembly into SQL Server 2012:

CREATE ASSEMBLY [Test]
AUTHORIZATION [dbo]
from 'H:\test.dll'
WITH PERMISSION_SET = SAFE

Msg 6544, Level 16, State 1, Line 1 CREATE ASSEMBLY for assembly 'Test' failed because assembly 'Test.dll' is malformed or not a pure .NET assembly. Unverifiable PE Header/native stub.


回答1:


Mixed-mode Assemblies are not allowed in SQLCLR Assemblies; only pure MSIL Assemblies are allowed. This is implied in the MSDN documentation for CREATE ASSEMBLY in the Remarks section:

Assembly Validation
SQL Server performs checks on the assembly binaries uploaded by the CREATE ASSEMBLY statement to guarantee the following:

  • The assembly binary is well formed with valid metadata and code segments, and the code segments have valid Microsoft Intermediate language (MSIL) instructions.

Please see the following answer (also here on Stack Overflow) for more details:

SQL Server custom CLR fails with error "Could not load file or assembly or one of its dependencies. The system cannot find the file specified."

especially the link to the Microsoft KB article Support policy for untested .NET Framework assemblies in the SQL Server CLR-hosted environment which states this restriction.

One possible reason why only managed code is allowed is that allowing unmanaged code would probably prevent SQL Server from enforcing certain restrictions (i.e. Host Protection Attributes, etc) for SAFE and EXTERNAL_ACCESS levels, as well as prevent verification.

And while setting an Assembly to UNSAFE lifts most of the restrictions, this one is still enforced:

Runtime Checks

At runtime, the code assembly is checked for the following conditions. If any of these conditions are found, the managed code will not be allowed to run and an exception will be thrown.

UNSAFE

Loading an assembly—either explicitly by calling the System.Reflection.Assembly.Load() method from a byte array, or implicitly through the use of Reflection.Emit namespace—is not permitted.

The quote above was taken from the following MSDN page: CLR Integration Programming Model Restrictions.

More info found at: CLR Hosted Environment.




回答2:


It is impossible to load a mixed mode C++/CLI assembly into SQL Server.

You can only load a "pure" C++/CLI assembly:

However, there may be a way around this. Use P/Invoke in your C# file. This is equivalent to writing a mixed mode C++/CLI assembly wrapper, because when CLR code calls native code in your assembly, it performs an implicit P/Invoke (let me know if this works for you).

Why does SQL server prevent mixed mode assemblies from being loaded?

This is my theory:

If we go back to 2005, things were different. When they released the first version of SQL Server to support the CLR, mixed mode assemblies would sometimes deadlock on a load. See Microsoft - Mixed DLL Loading Problem. Even after they fixed this issue, there was still arguments centered around security and stability which tipped the scales against allowing loading of mixed mode C++/CLI assemblies into the core of SQL server.

If anyone on the original Microsoft design team can fill in the blanks, I'd be very curious!



来源:https://stackoverflow.com/questions/36653838/sql-server-create-assembly-for-assembly-test-failed-because-assembly-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!