1 year ago

#338927

test-img

Terry

Automating git commands in C# does not remember Windows Credential Manager credentials

I have a LINQPad script that issues git commands via the cli using C# Process class and performs commands for several repositories at once. The repositories are hosted on a TFS server. Everything works fine in my terminal when doing commands manually. The first command I issued, Windows Credential Manager prompted me and stored the credentials, and now I never get prompted on subsequent commands while in the terminal. You can see the credentials in the git:* item below.

Windows Credential Manager

However, when I use the code below, I would hope...

  1. It would just use the credentials already stored for that 'tfs' domain and just work, or
  2. Only prompt me once and remember it for every command after.

Unfortunately, neither happens. I've tried changing the code so that the Process object is re-used for all commands issued and that didn't help. Is there a way to make this work so I don't have to enter credentials for every single command ran against each repository (which defeats the purpose of my program that processes repos in batch).

Note: The local_os_password passed in, is not intended to be used for git credentials. I needed local credentials for the Process to run correctly.

async Task Main()
{
    await CallGitCommandLineAsync(@"C:\BTR\Evolution\Websites\ESS\ClientA", "pull", "local_os_password");
    await CallGitCommandLineAsync(@"C:\BTR\Evolution\Websites\ESS\ClientB", "pull", "local_os_password");
}

public async Task<string[]> CallGitCommandLineAsync(string repoPath, string command, string localPassword)
{
    var p = new System.Diagnostics.ProcessStartInfo(@"C:\Program Files\Git\bin\git.exe");
    p.Arguments = command;
    p.WorkingDirectory = repoPath;
    p.UseShellExecute = false;
    p.RedirectStandardOutput = true;
    p.RedirectStandardError = true;
    p.WindowStyle = ProcessWindowStyle.Hidden;
    p.CreateNoWindow = true;

    p.UserName = Environment.UserName;
    p.Password = new System.Security.SecureString();

    foreach (var c in localPassword.ToCharArray())
    {
        p.Password.AppendChar(c);
    }

    using (var proc = new System.Diagnostics.Process())
    {
        proc.StartInfo = p;
        proc.Start();
        proc.WaitForExit();

        var output = await proc.StandardOutput.ReadToEndAsync();
        var error = await proc.StandardError.ReadToEndAsync();

        var logRaw = string.IsNullOrEmpty(output) && !string.IsNullOrEmpty(error)
            ? error.Split('\n').ToArray()
            : output.Split('\n').ToArray();

        proc.Close();

        return logRaw;
    }
}

c#

process

linqpad

git-credential-manager

0 Answers

Your Answer

Accepted video resources