我正在安装一个带有可执行文件的nuget包.要在项目文件(更具体地说是在mvc控制器)中的解决方案中引用可执行文件,目前我需要对文件夹路径进行硬编码,这尤其是因为它中有版本号.因此,当我更新nuget包时,我需要更改所有这些引用.
这看起来很傻
我仍然是微软堆栈的新手,但是有没有办法只是请求一个nuget依赖的路径?
当使用NuGet进行包管理时,添加新包时会发生什么,NuGet从存储库中提取依赖项,将文件添加到特定包目录(其位置取决于解决方案本地NuGet配置中的值)和添加包'lib'文件夹中的所有文件作为项目的引用.其他目录中的文件(例如工具,src等)用于其他目的,但不会将它们添加为引用(除非在install.ps1脚本中手动完成).
在构建二进制文件时,与node.js等解释性语言的区别之一变得非常重要.在构建过程中,编译器将引用复制到输出目录.这意味着当您执行实际代码时,包的位置大多无关紧要,因为此代码位于不同位置的二进制文件中(通常,您只将二进制文件而不是整个解决方案文件夹复制到服务器).
因此,根据所需的可执行文件在包中的位置,有几种情况:
如果可执行文件是包'lib'文件夹,那么它应该由ASP.MVC项目引用.在这种情况下,可执行文件将被复制到输出目录.在这种情况下,您可以通过执行以下代码来获取可执行文件路径:
// This returns the URI of the assembly containing the 'MyClass' type,
// e.g.: file:///C:\temp\myassembly.dll
var codeBase = typeof(MyClass).Assembly.CodeBase;
// This return the file path without any of the URI qualifiers
var location = new Uri(codeBase).LocalPath;
Run Code Online (Sandbox Code Playgroud)如果可执行文件不在包'lib'文件夹中,在这种情况下它不会被引用,因此不会在二进制文件夹中.这意味着您需要将二进制文件复制到二进制文件夹.一种简单的方法是使用构建前或构建后事件.使用它的缺点是每次更新包时都需要更新构建事件,因为文件夹名称包含软件包版本,因此会更改.如果您不想这样做,那么使用一些MsBuild魔法,您可以设置一个系统,允许您处理更改的文件夹名称.
首先,您需要能够找到包含可执行文件的文件夹.以下MsBuild脚本可用于搜索给定文件的包目录(NuGet解包包的目录)(在您的情况下是可执行文件).将此脚本放在可以从项目文件中引用它的位置(例如,在解决方案目录中)
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'
ToolsVersion="4.0">
<!--
Finds the full path for a tool that was installed by NuGet
Define:
- PackagesDir: Directory that contains the 'installed' packages.
- FileToLocate: Name of the executable file for which the path should be located.
- Path: Return variable containing the full path of the executable file.
-->
<UsingTask TaskName="FindToolDirectoryFromPackages"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<PackagesDir ParameterType="System.String" Required="true" />
<FileToLocate ParameterType="System.String" Required="true" />
<Path ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.Linq" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Path = System.IO.Directory.EnumerateFiles(PackagesDir, FileToLocate, SearchOption.AllDirectories)
.OrderBy(k => System.IO.Path.GetDirectoryName(k))
.Select(k => System.IO.Path.GetDirectoryName(k))
.LastOrDefault();
]]>
</Code>
</Task>
</UsingTask>
</Project>
Run Code Online (Sandbox Code Playgroud)接下来,您需要更新ASP.MVC项目文件.如果您将上述MsBuild脚本添加到解决方案文件夹,则首先将以下行添加到PropertyGroup项目文件的第一行
<SolutionDir Condition="'$(SolutionDir)' == '' or '$(SolutionDir)' == '*undefined*'">$(MSBuildProjectDirectory)\..</SolutionDir>
Run Code Online (Sandbox Code Playgroud)在项目文件的底部有两个注释目标,一个名为BeforeBuild,另一个名为AfterBuild.取消注释,哪一个并不重要.然后添加以下代码:
<FindToolDirectoryFromPackages PackagesDir="$(SolutionDir)\..\RELATIVE_PATH_TO_PACKAGE_DIRECTORY"
FileToLocate="FILE_NAME_OF_EXECUTABLE">
<Output TaskParameter="Path" PropertyName="DirMyExecutableFile" />
</FindToolDirectoryFromPackages>
<ItemGroup>
<Files Include="$(DirMyExecutableFile)\**\*.*" />
</ItemGroup>
<!-- OutputPath should be the directory to which the compiler will copy your binaries -->
<MakeDir Directories="$(OutputPath)"
Condition="!Exists('$(OutputPath)')" />
<Copy SourceFiles="@(Files)"
DestinationFolder="$(OutputPath)\%(RecursiveDir)" />
Run Code Online (Sandbox Code Playgroud)完成所有这些,每次构建项目时,应将可执行文件复制到输出目录,然后可以从代码中调用可执行文件.
| 归档时间: |
|
| 查看次数: |
2669 次 |
| 最近记录: |