【问题标题】:Cannot restore nuget packages in C# when some packages in custom repository当自定义存储库中的某些包时,无法在 C# 中恢复 nuget 包
【发布时间】:2013-12-17 20:22:03
【问题描述】:

我正在编写一个构建应用程序,该应用程序可以从 TFS 获取最新代码,然后将它们构建到 DLL 中。此应用程序托管为 ASP.NET Web 应用程序,应用程序池使用我的域帐户运行。

我们的代码使用NuGet 来管理依赖关系。我们的 Intranet 中有一个本地存储库,一些依赖项ONLY 在这个本地存储库中。

如果我在 CMD 中运行以下命令,

D:\MyApplication\nuget.exe restore

结果是:

Installing 'My_Dependency_Only_In_Local_1 1.0.0'.
Installing 'My_Dependency_Only_In_Local_2 2.0.0'.
Successfully installed 'My_Dependency_Only_In_Local_1 1.0.0'.
Successfully installed 'My_Dependency_Only_In_Local_2 2.0.0'.
All packages listed in packages.config are already installed.

所有依赖都可以正确下载。但在我的 C# 代码中

var processInfo = new ProcessStartInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nuget.exe"), "restore " + localProjectPath)
{
    WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
    UseShellExecute = false,
    RedirectStandardError =  true,
    CreateNoWindow = true,
    //Password = mypassword,
    //UserName = myusername,
    //Domain = mydomainname
};

var process = Process.Start(processInfo);
process.WaitForExit();

string errorText = process.StandardError.ReadToEnd();

除非我取消注释Password、UserName、Domain,否则明确设置用户信息,我会收到以下错误:

Unable to find version '1.0.0' of package 'My_Dependency_Only_In_Local_1'.
Unable to find version '2.0.0' of package 'My_Dependency_Only_In_Local_2'.

我不知道为什么会这样?这个应用程序是我的账号运行的,我启动的Process也可能是我的账号运行的,这个命令在CMD下是可以运行的,为什么在我的C#代码中不行呢?

你会帮我吗?提前谢谢你。

PS:nuget配置如下:

%APPDATA%\NuGet\NuGet.Config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageRestore>
    <add key="enabled" value="True" />
    <add key="automatic" value="True" />
  </packageRestore>
  <packageSources>
    <add key="intranet repository" value="http://our/local/nuget/repository" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  </packageSources>
  <disabledPackageSources>
    <add key="local cache" value="true" />
  </disabledPackageSources>
  <activePackageSource>
    <add key="All" value="(Aggregate source)" />
  </activePackageSource>
</configuration>

--

更新:

我编写了一个控制台应用程序,将其重命名为 nuget.exe,并覆盖了真实的。

private static void Main(string[] args)
{
    File.WriteAllText("D:\\temp\\user.txt", System.Security.Principal.WindowsIdentity.GetCurrent().Name);
}

它显示,nuget.exe 是使用我的域帐户运行的。

【问题讨论】:

标签: c# nuget


【解决方案1】:

既然您已确认您的单行假nuget 是在正确的帐户下启动的,请验证:

  • 为应用程序加载了“用户配置文件”(TBO,我不记得怎么做了,但已经很晚了;))
  • %APPDATA%\NuGet\NuGet.Config 指向应该的位置(相关,易于检查)

您的子进程可能会使用正确的凭据启动,但没有用户配置文件信息。有时这样做是为了加快启动速度并限制进程与桌面布局等用户事物的交互。

我想如果以某种方式跳过了用户配置文件,那么 %APPDATA% 可能不会指向您放置 nuget 配置的位置。

我经常看到服务和工作人员使用

  • Windows\System32\config\systemprofile
  • Windows\SysWOW64..uhforgotthepart..\config\systemprofile

路径作为它们的临时主目录。在这种情况下,您的进程的 APPDATA 将指向那里,并且查找 nuget 配置将失败。

不幸的是,我不知道/记得如何在 ProcessStartInfo 级别强制/跳过加载用户配置文件,但我大致记得 BlackICE 建议的 ShellExecute 确实加载了配置文件,所以它应该已经工作了.. 不过,请务必检查 APPDATA 环境变量,它可能是出于其他原因。

编辑:--
抱歉这么乱。我已经通过构建和 nuget 的包还原解决了一个完全不同的问题(但在同一个问题域中),但我几乎无法从内存中收集位。我的目标不同:我想阻止 NuGet 访问 Internet 和远程服务器,并且只使用本地缓存。所以,几乎与你想要的相反。但一切都归结为 NuGet 没有获取配置文件。由于 CI 服务器的特定设置,我无法“打开”配置文件加载,因此我通过将 nuget 配置放入所有相关工作节点(或 system32\ config\sysprofile 在 32 位机器上)。

【讨论】:

    【解决方案2】:

    感谢@quetzalcoatl 的answer

    private static void Main(string[] args)
    {
        File.WriteAllText("D:\\temp\\path.txt", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
    }
    

    输出为C:\Windows\system32\config\systemprofile\AppData\Roaming
    这意味着我的配置没有加载。

    看了NuGet源码,找到了解决办法。

    /// <summary>
    /// Loads the machine wide settings.
    /// </summary>
    /// <remarks>
    /// For example, if <paramref name="paths"/> is {"IDE", "Version", "SKU" }, then
    /// the files loaded are (in the order that they are loaded):
    ///     %programdata%\NuGet\Config\IDE\Version\SKU\*.config
    ///     %programdata%\NuGet\Config\IDE\Version\*.config
    ///     %programdata%\NuGet\Config\IDE\*.config
    ///     %programdata%\NuGet\Config\*.config
    /// </remarks>
    /// <param name="fileSystem">The file system in which the settings files are read.</param>
    /// <param name="paths">The additional paths under which to look for settings files.</param>
    /// <returns>The list of settings read.</returns>
    public static IEnumerable<Settings> LoadMachineWideSettings(
        IFileSystem fileSystem,
        params string[] paths)
    {
        List<Settings> settingFiles = new List<Settings>();
        string basePath = @"NuGet\Config";
        string combinedPath = Path.Combine(paths);
    
        while (true)
        {   
            string directory = Path.Combine(basePath, combinedPath);
    
            // load setting files in directory
            foreach (var file in fileSystem.GetFiles(directory, "*.config"))
    
            ...
    

    我们可以从 cmets 获取机器范围的配置文件加载路径。

    所以,解决办法是

    将配置文件从%APPDATA%\NuGet\NuGet.Config复制到C:\ProgramData\NuGet\Config\NuGet.Config

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 2020-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多