如何创建含外部exe的Dotnet Tool,无需复制至消费项目Bin目录调用
实现方案:不复制二进制到消费项目bin目录的Dotnet Tool调用方法
当然可以做到不用把二进制文件复制到消费项目的bin目录,核心思路是让二进制文件随Dotnet Tool一起安装到固定的工具目录,然后在Tool代码中通过程序集路径定位这些文件。下面是具体步骤:
1. 修正Tool项目的csproj配置
你当前的配置里PackageCopyToOutput=true会导致二进制文件被复制到消费项目的输出目录,先把这个改成false,同时指定打包后的路径,确保文件安装到Tool的专属目录:
<ItemGroup> <!-- 将二进制文件打包进NuGet包,不复制到消费项目输出 --> <Content Include="binaries/*.*" Pack="true"> <CopyToOutputDirectory>Never</CopyToOutputDirectory> <PackageCopyToOutput>false</PackageCopyToOutput> <!-- 用TargetFramework变量自动适配.NET版本,确保文件放在Tool安装目录的binaries子目录 --> <PackagePath>tools/$(TargetFramework)/binaries/</PackagePath> </Content> </ItemGroup>
2. 在Tool代码中定位二进制文件
Dotnet Tool安装后,主程序集的路径是固定的(全局工具在%USERPROFILE%\.dotnet\tools或~/.dotnet/tools,本地工具在项目的.dotnet/tools),可以通过程序集路径拼接找到二进制文件:
using System.Diagnostics; using System.Reflection; // 获取当前Tool程序集的所在目录 var toolAssemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // 拼接二进制文件的完整路径(对应打包时的binaries子目录) var externalExePath = Path.Combine(toolAssemblyDir, "binaries", "你的外部程序.exe"); // 启动独立进程 var startInfo = new ProcessStartInfo(externalExePath) { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; using var process = Process.Start(startInfo); // 可选:处理程序输出 var output = await process.StandardOutput.ReadToEndAsync(); var error = await process.StandardError.ReadToEndAsync(); process.WaitForExit();
3. 验证和注意事项
- 重新打包Tool:先卸载旧版本的Tool,再执行
dotnet pack和dotnet tool install(全局加--global,本地加--local),确保新配置生效。 - 路径适配:
$(TargetFramework)变量会自动替换成项目的目标框架(比如net6.0、net7.0),不用手动修改路径。 - 本地工具测试:如果是本地安装的Tool,程序集会位于项目根目录的
.dotnet/tools/netX.X/下,代码中的路径逻辑依然适用。
内容的提问来源于stack exchange,提问作者ejones
相关产品推荐
相关产品推荐

