簡體   English   中英

以編程方式獲取nuget包的路徑

[英]Getting the path of a nuget package programmatically

我正在安裝一個帶有可執行文件的nuget軟件包。 為了從解決方案中的項目文件(尤其是在MVC控制器中)中引用可執行文件,此刻,我需要對文件夾路徑進行硬編碼,這特別令人討厭,因為其中包含版本號。 因此,當我更新nuget包時,需要更改所有這些引用。

好像很傻

我對Microsoft堆棧還是相當陌生的但是沒有某種方法可以僅請求nuget依賴項的路徑嗎?

當使用NuGet進行軟件包管理時,添加新軟件包時會發生以下情況:NuGet從存儲庫中提取依賴項,將文件添加到特定的軟件包目錄(其位置取決於解決方案本地NuGet配置中的值),並且將軟件包“ lib”文件夾中的所有文件添加為對項目的引用。 其他目錄中的文件(例如工具,src等)用於其他目的,但不會將它們添加為引用(除非在install.ps1腳本中手動完成)。

構建二進制文件時,與諸如node.js之類的解釋語言的區別之一變得很重要。 在構建過程中,編譯器將引用復制到輸出目錄。 這意味着在您執行實際代碼時,包的位置幾乎無關緊要,因為該代碼位於其他位置的二進制文件中(通常,您僅將二進制文件而不是整個解決方案文件夾復制到服務器)。

因此,根據所需可執行文件在軟件包中的位置,有幾種方案:

  • 如果可執行文件是軟件包“ lib”文件夾,則您的ASP.MVC項目應引用該可執行文件。 在這種情況下,可執行文件將被復制到輸出目錄。 在這種情況下,您可以通過執行以下代碼來獲取可執行路徑:

     // This returns the URI of the assembly containing the 'MyClass' type, // eg: 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; 
  • 如果可執行文件不在程序包的“ 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> 
    • 接下來,您需要更新ASP.MVC項目文件。 如果您將上述MsBuild腳本添加到解決方案文件夾,則首先將以下行添加到項目文件的第一個PropertyGroup

       <SolutionDir Condition="'$(SolutionDir)' == '' or '$(SolutionDir)' == '*undefined*'">$(MSBuildProjectDirectory)\\..</SolutionDir> 
    • 在項目文件的底部,有兩個注釋的目標,一個稱為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)" /> 

每次構建項目時都完成了所有這些操作,應將可執行文件復制到輸出目錄,然后可以從代碼中調用可執行文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM