如何不调试引用的 dll?

How NOT to debug a referenced dll?

我正在使用在其他项目中引用的 dll 的发布版本。这个dll在调试器运行ning时有篡改检测(dll也是我的,我不打算做非法的事情)在调试时给出误报结果。

Visual Studio (2017-1019) 中是否有选项不“调试”引用的 dll,但仍然能够调试正在开发的代码? “调试”意味着我不想介入这个特定的 dll,而只是想从方法中获取数据,就像我在 Release 中获取数据一样。

例如:

//Release dll
int Sum (int a, int b)
{
bool TamperingDetected = CheckForTampering();
if (TamperingDetected)
  return 0;
else
  return a + b;
}

//Other project
MessageBox.Show(dll.Sum(1, 1));

如果我运行这部分代码在Release中我可以轻松得到正确的值。不会检测到任何篡改,如果有人想对这个方法进行逆向工程,在“合法”发布中很容易做到。如果我在 Debug 中 运行,我将始终得到 0。如前所述,我不想在 Sum 方法中进行 Step-In,因此不应在此 dll 中进行调试,但其他所有内容应该像在调试中一样工作。

仅我的代码选项没有任何区别。

背景是一个团队创建了这个带有篡改检测的dll,另一个团队将其用作NuGet。现在他们无法调试他们的代码部分,因为我们正在检测篡改并返回错误值。 其他团队拥有源代码太过分了,因为我们冒着他们在构建过程中在他们不知道的那部分代码上做错事情的风险。

一个选择是为他们提供 Debug 和 Release dll,他们可以像这里解释的那样在它们之间切换:,但是这样我们就失去了共享 NuGet 的简单性,我们仍然有 Debug dll 是复制而不是发布 dll,因此在最终产品中失去了篡改检测。然后 NuGet 始终处于发布状态。

通过切换调试和发布配置来自动切换 NuGets 是不可能的,或者我仍然没有找到方法,但这也是一个不错的选择。仅当使用一些完全不同的项目来下载 Debug 和 Release NuGets,然后使用上述答案时,但我也不喜欢它。

看来你是想在Debug模式下根据某个开关来决定是否调试dll

很明显,你给的方法是有问题的。毕竟是基于项目当前的配置。启用发布模式后,您将无法调试主项目的代码。本质上,你还是想调试代码。

但是,禁用工具下的Enable Just My Code选项-->选项-->Debugging-->General会让你在Release模式下调试代码。但它不是一个完美的 Debug 模式,有时我不能打断点,无法进一步调试,不推荐。

我有两个解决方案:

============================================= ========

技巧一)直接使用Assembly dll而不是nuget

1) 创建一个名为 Debug_NotDLL 的新 Configuration,它继承了 Debug模式。

,制作两个DebugRelease模式的dll.

2)csproj 文件中添加这些:

 <Reference Include="test" Condition="'$(Configuration)'=='Debug'">
      <HintPath>..\test\bin\Debug\xxx\xxx.dll</HintPath>
    </Reference>
    <Reference Include="test" Condition="'$(Configuration)'=='Debug_NotDLL'">
      <HintPath>..\test\bin\Release\xxx\xxx.dll</HintPath>
 </Reference>

然后,你可以切换DebugDebug_NotDLL配置来得到你想要的。

============================================= =======

技巧二)使用nuget

创建新包,在这种情况下,我建议您使用 net standard class 库项目。

我建议你可以为你的 dll 创建两个 nuget 包。

你最好将Release模式下的dll重命名为xxx_Release.dll,Debug模式下xxx_Debug.dll

创建release nuget包,直接在Release模式下的lib项目上右击-->点击Pack。要重命名 nuget 包,您可以使用 PackageId msbuild 属性 将其名称设置为 csproj 文件下的 xxx_Release。检查 this document.

注意如果在本机下创建nuget包,是可以一直进入nuget源码的,因为本机有项目源码的缓存.这是一个特殊的情况。所以你应该在另一台机器上测试 nuget 包。

要创建调试 nuget 包dllpdb 文件还不够,还应该将源文件添加到 nuget 包中.

然后,在Debug模式下打包名为xxx.Debug.x.x.x.nupkg的nuget包。这是关于创建调试 nuget 包的步骤的one link and

完成后,你可以安装这两个nuget包,并将它们添加到主项目下,

<ItemGroup>
    <PackageReference Include="xxx.Debug" Version="1.0.0" Condition="'$(Configuration)'=='Debug'" />
  <PackageReference Include="xxx.Release" Version="1.0.0" Condition="'$(Configuration)'=='Debug_NotDLL'" />
 </ItemGroup>

由于实现我最初想要的结果的可能性非常小,因此次要的解决方案是在 NuGet 之间自动切换,这适用于 Choose-When-Otherwise。 PackageReference 或 ItemGroup 中的条件不起作用(至少在 VisualStudio 中不起作用,根据 )。所以我将创建两个 NuGet,一个是带有篡改检测的 Release,另一个也是 Release 但没有篡改检测(“-debug”后缀添加到这个版本)。然后不会通过 NuGet 管理器安装 NuGet,但只会在 .csproj 中更新 dllVersion:

<PropertyGroup>
  <dllVersion>1.2.3</dllVersion>
</PropertyGroup>
<Choose>
  <When Condition="'$(Configuration)'=='Debug'">
    <ItemGroup>
      <PackageReference Include="dllNuGet" Version=$(dllVersion)-debug/>
    </ItemGroup>
  </When>
  <Otherwise>
    <ItemGroup>
      <PackageReference Include="dllNuGet" Version=$(dllVersion)/>
    </ItemGroup>
  </Otherwise>
</Choose>