Copy Files to a Remote Location using Cake
I have recently had the need to copy files from one Windows machine to another
in a Cake build task. A rather easy way to achieve this is to use the net
command line tool, which I have wrapped into a few lines of C#. Here’s how to
use the code:
readonly var target = Argument("target", "Default");
Task("Default")
.Does(() =>
{
using (var session = NetUse("\\\\some-machine", "domain\\user", "password"))
{
// Use Cake's existing IO library
CopyFileToDirectory("myfile.txt", session.ToRemote("C:/"));
}
});
RunTarget(target);
The two most important bits include:
- Opening a session using the
NetUse
method - Using the
session.ToRemote
method to turn a “normal” path into a remote path (e.g.C:\
->\\some-machine\c$\
)
Here’s the actual NetUse
implementation:
public NetUseSession NetUse(string machine, string username, string password)
{
Information($"Connecting to '{machine}'");
var exitCode = StartProcess("net", new ProcessSettings
{
Arguments = new ProcessArgumentBuilder()
.Append("use")
.Append(machine)
.AppendSecret(password)
.Append($"/user:{username}")
});
if (exitCode != 0) {
throw new Exception($"Could not connect to '{machine}'");
}
Func<string, int> closeFunc = (m) =>
{
Information($"Deleting connection to '{m}'");
return StartProcess("net", new ProcessSettings
{
Arguments = new ProcessArgumentBuilder()
.Append("use")
.Append(m)
.Append("/delete"),
});
};
return new NetUseSession(machine, closeFunc);
}
public sealed class NetUseSession : IDisposable
{
private readonly string _machine;
private readonly Func<string, int> _close;
public NetUseSession(string machine, Func<string, int> close)
{
_machine = machine;
_close = close;
}
public DirectoryPath ToRemote(DirectoryPath directory)
{
var remoteDirectory = directory.ToString().Replace(":", "$");
return $"{_machine}/{remoteDirectory}";
}
public void Dispose()
{
var exitCode = _close(_machine);
if (exitCode != 0) {
throw new Exception($"Could not delete connection to '{_machine}'");
}
}
}