在上篇博文.Net core 程序Nuget包独立存放(一)中介绍了运行环境中,如何实现将nuget库存放,还有一个问题没有解决:如何将nuget包从publish的程序集中分离。本文就介绍下如何解决这个问题:

首先,我们直接将dll放在additionalProbingPaths的时候,会发现会出现找不到dll的现象。研究下Nuget的缓存包,发现它是这样的一个格式的路径:

  newtonsoft.json\13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll

基本上是由package version path三部分组成。那如何获取这三部分内容呢,研究一下publish的文件就会发现它们是存储在deps.json文件中。

    "targets": {
            "Newtonsoft.Json/13.0.1": {
                "runtime": {
                    "lib/netstandard2.0/Newtonsoft.Json.dll": {
                        "assemblyVersion""13.0.0.0",
                    }
                }
            }

有了这些内容后,我们已经可以将所有dll放在additionalProbingPaths中了。但这有点做过头了,我们仅仅只需要将nuget程序包放进去而已。项目生成的dll还是需要和exe放在一起的。

因此,我们还需要知道另外一部分信息:哪些是nuget程序包引入的dll,哪些是项目生成的dll。这些也可以从deps.json中找到。

    "libraries": {
        "Newtonsoft.Json/13.0.1": {
            "type""package",
            "serviceable"true,
        }
    }

根据type是package的则是nuget程序包。

有了上述基础后,我们就可以写一个程序实现Nuget程序独立存放了。一个简单的示例如下。

 1     static void Main(string[] args)
 2     {
 3         var content = File.ReadAllText(@".\demo.deps.json");
 4 
 5         var targetLibPath = "libs"; // 需要预先设置runtimeconfig.json  "additionalProbingPaths": ["libs"],
 6 
 7         var root = JsonConvert.DeserializeObject(content) as JObject;
 8 
 9 
10         var npkgs = root["libraries"]
11                     .Children<JProperty>()
12                     .Where(i => i.Value["type"]?.Value<string>() == "package")
13                     .Select(i => i.Name)
14                     .ToHashSet();
15 
16         var libs = root.SelectTokens(@"targets.*.*.runtime")
17                        .Cast<JObject>()
18                        .Select(token =>
19                        {
20                            var packageToken = token.Parent.Parent.Parent as JProperty;
21                            var package      = packageToken.Name;
22 
23                            var dlls = token.Properties().Select(i => i.Name).ToArray();
24 
25                            return new { name = package, dlls };
26                        })
27                        .ToArray();
28 
29 
30         var packages = libs.Where(i => npkgs.Contains(i.name))
31                            .ToArray();
32 
33         var projects = libs.Except(packages).ToArray();
34 
35         foreach (var p in packages)
36         {
37             //存在一个包下多个dll的情况
38             foreach (var dllPath in p.dlls)
39             {
40                 var file = Path.GetFileName(dllPath);
41                 if (!File.Exists(file))
42                 {
43                     continue;
44                 }
45 
46                 var fullPath = Path.Combine(targetLibPath, p.name, dllPath);
47                 Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
48                 File.Move(file, fullPath);
49             }
50         }
51     }
View Code

相关文章:

  • 2021-10-14
  • 2021-11-01
  • 2022-12-23
  • 2022-12-23
  • 2021-07-19
  • 2022-01-23
  • 2022-12-23
猜你喜欢
  • 2021-06-29
  • 2021-10-02
  • 2022-12-23
  • 2022-12-23
  • 2021-12-14
  • 2022-02-21
  • 2021-10-11
相关资源
相似解决方案