c# - Getting the path of a nuget package programmatically -
i'm installing nuget package executable in it. reference executable from within solution in project file (more in mvc controller), @ moment need hardcode folder path, particularly annyoing since has version number in it. when update nuget package, i'd need change these references.
that seems silly
i'm still new microsoft stack, but isn't there way request path of nuget dependency?
when using nuget package manager happens when new package added nuget pulls in dependencies repository, adds files specific package directory (the location of depends on values in solution local nuget configuration) , adds files in package 'lib' folder references project. files in other directories (e.g. tools, src etc.) used other purposes not added references (unless manually done in install.ps1 script).
one of difference interpreted language node.js becomes important when build binaries. during build process compiler copies references output directory. means location of packages irrelevant when execute actual code because code lives in binary in different location (and in general copy binaries , not entire solution folder server).
so depending on desired executable in package there several scenario's:
if executable package 'lib' folder should referenced asp.mvc project. in case executable copied output directory. in case can hold of executable path executing following code:
// returns uri of assembly containing 'myclass' type, // e.g.: file:///c:\temp\myassembly.dll var codebase = typeof(myclass).assembly.codebase; // return file path without of uri qualifiers var location = new uri(codebase).localpath;
if executable not in package 'lib' folder in case not referenced , won't in binary folder. means need copy binaries binary folder. easy way use pre- or post-build events. drawback of using need update build event every time update package because folder name includes package version , change. if don't want use of msbuild magic can set system allows handle changing folder name.
first need able find folder holds executable. following msbuild script can used search package directory (the 1 nuget unpacks packages) given file (in case executable file). put script in location can reference project file (e.g. in solution directory)
<project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' toolsversion="4.0"> <!-- finds full path tool installed nuget define: - packagesdir: directory contains 'installed' packages. - filetolocate: name of executable file path should located. - path: return variable containing full path of 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>
next need update asp.mvc project file. if added above msbuild script solution folder first add following line first
propertygroup
of project file<solutiondir condition="'$(solutiondir)' == '' or '$(solutiondir)' == '*undefined*'">$(msbuildprojectdirectory)\..</solutiondir>
at bottom of project file 2 commented targets, 1 called beforebuild , 1 called afterbuild. uncomment one, doesn't matter one. add following code:
<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 directory compiler copy binaries --> <makedir directories="$(outputpath)" condition="!exists('$(outputpath)')" /> <copy sourcefiles="@(files)" destinationfolder="$(outputpath)\%(recursivedir)" />
with done every time build project executable should copied output directory , can call executable code.
Comments
Post a Comment