【问题标题】:How to add native DLLs to ClickOnce deployment of .NET app如何将本机 DLL 添加到 .NET 应用程序的 ClickOnce 部署
【发布时间】:2022-01-26 18:41:01
【问题描述】:

几天来,我一直在尝试弄清楚如何将我的原生 C++ DLL 依赖项包含在使用 VS2019 构建的 C# WinForms 应用的 ClickOnce 部署中。本机 DLL 不会出现在 .NET 主应用程序的“属性”页面的 Publish -> Application Files 下(尽管 .NET DLL 会出现)。

我已经读了一百遍了:

将本机 DLL 的构建操作设置为“内容”。

...我认为我在解释/做错了。

本机 C++ 项目的输出自然不会“包含”在任何项目中(公开构建操作属性的明显先决条件),因此不会出现在解决方案资源管理器中以允许我将其设置为“内容”。所以我
[Solution Explorer] -> Project -> Add -> Existing Item -> [select native C++ DLL] 将本机 C++ DLL 添加到项目以启用构建操作属性,然后我将其设置为“内容”。 {重要提示:它必须“包含”在项目中,而不仅仅是解决方案才能获得构建操作属性。}

所以我这样做并且它有效,但当然我必须选择本机 DLL 的特定平台和配置(例如,x64 和版本),并且此选择是固定的(不受 VS2019 GUI 中的选择控制当我构建时),更糟糕的是——甚至没有标记项目中“包含”了哪个平台和配置。 {旁注:我如何不必在 Publish -> Application Files 下选择要使用的 .NET DLL 的哪个版本(x86 与 x64)?它只是自动选择正确的?我如何设置一个 x86 版本和一个 x64 版本,我可以在它们之间来回切换并构建每个版本?} 我无法想象这是它应该完成的方式。它易碎且不透明。肯定有更好的方法。我想我错过了其他人都认为“显而易见”的东西。任何其他尝试使用或维护此配置的开发人员都会诅咒我的名字,而且这样做是对的。

使 ClickOnce 部署(通过 VS2019 GUI)在 ClickOnce 部署包中包含我的本机 DLL(同一解决方案中包含的项目)的“正确方法”是什么?

注意,我在本机 C++ 项目的“属性”页面中发现了一个有希望的设置:自定义构建设置 -> 常规 -> 将输出视为内容。不过好像没什么效果。

我会永远感激任何指点。

【问题讨论】:

  • 您好 Jimbo1987,很高兴知道您找到了解决此问题的解决方案!请考虑接受它作为答案以将其状态更改为已回答。它还将帮助其他人解决类似的问题。见can I answer my own question..,只是一个提醒:)
  • 嗨 Jiale Xue,我发现 an 答案(或两个)不太令人满意,因为它们仍然有点脆弱(需要手动编辑父项目文件如果不小心,可能会被覆盖),并且不是非常直观。最后,第一次构建时会引发错误。出于这些原因,我将我的“答案”称为“解决方法”或“黑客”,但我希望存在一个真实且更好的答案。我不认为他们用我召唤来完成它的方式真的是做到这一点的“最佳方式”。希望其他人可以改进这些。

标签: visual-studio dll deployment clickonce


【解决方案1】:

改编自here

  1. 编译您的解决方案。

  2. 右键单击托管项目并选择“添加/现有项目”。不要使用“添加引用”。

  3. 导航到已编译的本机 DLL 并选择它(根据需要调整文件类型以公开它)。

  4. 单击“添加”拆分按钮中的向下箭头并选择“添加为链接”(这使我们不会保留多个 DLL 副本)。

  5. 右键单击新添加的文件并选择“属性”。

  6. 确保“构建操作”为“内容”,并且“复制到输出目录”设置为“不复制”(因为您已经在其他地方自动化了该任务,早在进入开发的部署阶段之前)。

  7. 请注意,在正确清理所有输出文件夹后,您将在初始构建时收到“未找到文件”错误,但无论如何都会创建本机 DLL,在下一次完整构建时抢占该错误。

  8. 在 .NET 应用程序的“属性”页面上,执行 发布 -> 应用程序文件 -> 全部重置 以将本机 DLL 填充到列表中。调整“发布状态”等。人。根据需要。

  9. 发布。

我发现我可以在项目中维护一个“虚拟”文件夹结构来存储本地 DLL 的各种版本(例如,x86 与 x64 以及调试与发布)的链接不会弄乱文件系统,(并确保 DLL 不会过时):通过解决方案资源管理器添加文件夹结构(例如,“.\NativeDLLs\x64\Release”等),并添加 Links 仅(没有真实文件)到文件夹。然后使用 Windows 资源管理器或 shell 命令从文件系统中删除文件夹。从文件系统中删除后,它们将保留在解决方案资源管理器中,因为它们仍然包含链接。

这些虚拟文件夹的层次结构现在仅作为项目组元素中的内容元素(包含链接)存在于项目文件 ([appname.csproj]) 中(这似乎是让它们出现在 ClickOnce 中的关键部署世界)。

一个指针(对我自己)会有所帮助:不要害怕点击 Publish -> Application Files 对话框上的 Reset All 按钮。 p>

【讨论】:

    【解决方案2】:

    在改进了一天左右之后,我发现 VS2019 GUI 无法满足此目的。更好的答案是手动编辑 .NET 项目的 .csproj 文件以包含本机 DLL 作为内容时间>。找到该项目文件中的其他元素并添加本机 DLL,如下所示:

      <ItemGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
        <Content Include="..\bin\MyApp\x64\Release\native1.dll">
        </Content>
        <Content Include="..\bin\MyApp\x64\Release\native2.dll">
        </Content>
      </ItemGroup>
      <ItemGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
        <Content Include="..\bin\MyApp\x86\Release\native1.dll">
        </Content>
        <Content Include="..\bin\MyApp\x86\Release\native2.dll">
        </Content>
      </ItemGroup>
    

    (其中 *..\bin\MyApp{x86|x64}{Debug|Release}* 是您的输出文件夹,其中您的原生 DLL、native1.dllnative2.dll 已被复制、后编译,供您的 .NET 应用程序 MyApp.exe 使用)。当然,x86 文件夹包含 32 位本机 DLL,x64 文件夹包含 64 位本机 DLL,等等 - 你懂的。

    没有令人困惑的额外链接和不会弄乱解决方案/项目的东西,并且 .dll 文件出现在它们应该出现的位置,而不是在单独的子子目录中。

    当然,您可以为其余条件添加其他元素 - 即调试版本,但谁希望 ClickOnce 部署用于调试版本?您可能直接从 Visual Studio 运行这些,对吧?

    【讨论】:

      猜你喜欢
      • 2011-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 2010-09-08
      • 2010-10-20
      相关资源
      最近更新 更多