在自定义存储库中的某些包时,无法在C#中恢复nuget包

时间:2013-12-17 20:22:04

标签: c# nuget

我正在编写一个构建应用程序,这个应用程序可以从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();

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

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是使用我的域帐户运行的。

2 个答案:

答案 0 :(得分:1)

现在您已经确认您的单行假冒伪劣游戏是在正确的帐户下启动的,请验证:

  • 用户个人资料&#39;为应用程序加载(TBO,我不记得如何,但它已经晚了;))
  • %APPDATA%\ NuGet \ NuGet.Config指向它应该在哪里(相关,易于检查)

您的子进程可能会以正确的凭据启动,但没有用户个人资料信息。有时会加快启动速度并限制流程。与用户事物的交互,如桌面布局等。

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

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

  • 的Windows \ system32 \设置\ systemprofile
  • 的Windows \ SysWOW64..uhforgotthepart .. \配置\ systemprofile

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

不幸的是,我不知道/记得如何强制/跳过ProcessStartInfo级别的加载用户个人资料,但我大致记得BlackICE建议的ShellExecute加载了该配置文件,所以它应该工作..但是,一定要检查APPDATA env变量,它可能是由于其他原因。

编辑: -
抱歉是这么混乱。我已经使用构建和nuget的包恢复解决了一个完全不同的问题(但在相同的问题域中),但我几乎无法从内存中收集位。我的目标不同:我想阻止NuGet访问互联网和远程服务器,并仅使用本地缓存。所以,几乎与你想要的相反。但所有归结为NuGet没有得到配置文件。我无法打开&#34;由于CI服务器的某些设置导致的配置文件加载,所以我通过在所有相关工作节点(或32位机器上的system32 \ config \ sysprofile)上将nuget配置放入syswow64 \?\ systemprofile中的appdata来解决它。

答案 1 :(得分:0)

谢谢@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"))

        ...

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

所以,解决方案是

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