使用 Visual Studio 2017 构建 SSDT 项目时如何将 /unsafe 标志传递给 C# 编译器

How to pass the /unsafe flag to the C# compiler when building an SSDT Project with Visual Studio 2017

前缀: 请不要纠结于 should I do this,也不要纠结于它是否受支持。 Microsoft 正是为此目的提供了 Unsafe 权限集

A CLR assembly created with PERMISSION_SET = UNSAFE may be able to access external system resources, call unmanaged code, and acquire sysadmin privileges.

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-assembly-transact-sql

现在,进入问题:

因此,传统观点认为,当人们希望使用不安全的代码块时,例如

  unsafe {
     fixed (char* passwordChars = password) {
        var securePassword = new SecureString(passwordChars, password.Length);
        securePassword.MakeReadOnly();
        return securePassword;
     }
  }

只需选中 Build 选项中的复选框,然后小跑:

但是,我完全无法理解在构建 SSDT SqlProj 项目时如何做到这一点。这是该项目类型的构建 (SQLCLR 构建) 选项:

那么,除了通常的 "Danger, Danger, Will Robinson" 类型警告之外,这甚至可以用于 SqlProj 项目类型吗?是的,我正在构建不安全的代码,是的,我正在签署代码,使用非对称密钥并使用附加的 Unsafe 权限登录。

除此之外,您到底是如何将其传递到编译器命令行的?另外,如果需要的话,我不反对修改 sqlproj 文件。

想法

如果我 我想我可以创建另一个程序集,在 SqlProj 格式之外使用此代码并将其加载到 Sql 服务器作为我随后引用的程序集。 SqlProj 项目格式明确禁止设置此标志似乎很奇怪。

UI 不会公开该选项,但项目文件仍然支持它(以及您可以传递给编译器的任何其他选项)。

在 VS 中,右键单击项目并选择 "Unload Project",然后再次右键单击并选择 "Edit project"。在主 <PropertyGroup> 块中,添加

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

保存,再次重新加载项目,它现在应该毫无怨言地构建 unsafe 个块。

请注意,PERMISSION_SET = UNSAFE 比 C# 调用的 "unsafe" 更广泛。 PERMISSION_SET = SAFE 禁止甚至在经过验证的托管代码中做一些可能会损害引擎稳定性或吞吐量的事情(如线程)(在代码访问安全性被放弃并使事情变得复杂之前)。