diff --git a/src/Tasks.UnitTests/Exec_Tests.cs b/src/Tasks.UnitTests/Exec_Tests.cs
index 87fc5dc829c..40bc1521676 100644
--- a/src/Tasks.UnitTests/Exec_Tests.cs
+++ b/src/Tasks.UnitTests/Exec_Tests.cs
@@ -1068,6 +1068,116 @@ public void ConsoleOutputDoesNotTrimLeadingWhitespace()
exec.ConsoleOutput[0].ItemSpec.ShouldBe(lineWithLeadingWhitespace);
}
}
+
+ ///
+ /// Runs an Exec task that lists directory contents and asserts expected/unexpected files in the output.
+ ///
+ /// The TaskEnvironment to configure on the Exec task.
+ /// The WorkingDirectory to set, or null to use the default.
+ /// A filename that must appear in the output.
+ /// A filename that must NOT appear in the output, or null to skip.
+ private void ExecuteListCommandInDirectory(
+ TaskEnvironment taskEnvironment,
+ string workingDirectory,
+ string expectedFile,
+ string notExpectedFile = null)
+ {
+ Exec exec = new Exec();
+ exec.TaskEnvironment = taskEnvironment;
+ exec.BuildEngine = new MockEngine(_output);
+ exec.Command = NativeMethodsShared.IsWindows ? "dir /b" : "ls";
+ exec.ConsoleToMSBuild = true;
+
+ if (workingDirectory != null)
+ {
+ exec.WorkingDirectory = workingDirectory;
+ }
+
+ bool result = exec.Execute();
+
+ result.ShouldBeTrue();
+ string[] outputLines = exec.ConsoleOutput.Select(item => item.ItemSpec).ToArray();
+ outputLines.ShouldContain(expectedFile);
+ if (notExpectedFile != null)
+ {
+ outputLines.ShouldNotContain(notExpectedFile);
+ }
+ }
+
+ [Fact]
+ public void ExecUsesProjectDirectoryAsDefaultWorkingDirectory()
+ {
+ using (var testEnv = TestEnvironment.Create(_output))
+ {
+ var projectDir = testEnv.CreateFolder();
+ File.WriteAllText(Path.Combine(projectDir.Path, "projectfile.txt"), "project content");
+
+ var differentCwd = testEnv.CreateFolder();
+ File.WriteAllText(Path.Combine(differentCwd.Path, "decoyfile.txt"), "decoy content");
+
+ string originalDirectory = Directory.GetCurrentDirectory();
+ TaskEnvironment taskEnvironment = null;
+ try
+ {
+ Directory.SetCurrentDirectory(differentCwd.Path);
+
+ taskEnvironment = TaskEnvironment.CreateWithProjectDirectoryAndEnvironment(projectDir.Path);
+ ExecuteListCommandInDirectory(
+ taskEnvironment,
+ workingDirectory: null,
+ expectedFile: "projectfile.txt",
+ notExpectedFile: "decoyfile.txt");
+ }
+ finally
+ {
+ taskEnvironment?.Dispose();
+ Directory.SetCurrentDirectory(originalDirectory);
+ }
+ }
+ }
+
+ [Fact]
+ public void InvalidRelativeWorkingDirectory_LogsOriginalPathNotAbsolutized()
+ {
+ using var testEnv = TestEnvironment.Create(_output);
+ var projectDir = testEnv.CreateFolder();
+ const string relativeDir = "testDir";
+ string absolutePath = Path.Combine(projectDir.Path, relativeDir);
+
+ var exec = new Exec
+ {
+ BuildEngine = new MockEngine(_output),
+ Command = "echo hi",
+ WorkingDirectory = relativeDir,
+ TaskEnvironment = TaskEnvironment.CreateWithProjectDirectoryAndEnvironment(projectDir.Path),
+ };
+
+ exec.Execute().ShouldBeFalse();
+
+ var engine = (MockEngine)exec.BuildEngine;
+ engine.AssertLogContains("MSB6003");
+ engine.AssertLogContains(relativeDir);
+ engine.AssertLogDoesntContain(absolutePath);
+ }
+
+ [Fact]
+ public void Exec_RelativeWorkingDirectory_ResolvedAgainstProjectDirectory()
+ {
+ using var testEnv = TestEnvironment.Create(_output);
+ var projectDir = testEnv.CreateFolder();
+ Directory.CreateDirectory(Path.Combine(projectDir.Path, "builddir"));
+
+ var exec = new Exec
+ {
+ BuildEngine = new MockEngine(_output),
+ Command = "echo hi",
+ WorkingDirectory = "builddir",
+ TaskEnvironment = TaskEnvironment.CreateWithProjectDirectoryAndEnvironment(projectDir.Path),
+ };
+
+ exec.ValidateParametersAccessor().ShouldBeTrue();
+ exec.GetWorkingDirectoryAccessor().ShouldBe(Path.Combine(projectDir.Path, "builddir"));
+ }
}
internal sealed class ExecWrapper : Exec
diff --git a/src/Tasks/Exec.cs b/src/Tasks/Exec.cs
index d59c05f4d04..b34d6d61bf7 100644
--- a/src/Tasks/Exec.cs
+++ b/src/Tasks/Exec.cs
@@ -21,6 +21,7 @@ namespace Microsoft.Build.Tasks
/// for it to complete, and then returns True if the process completed successfully, and False if an error occurred.
///
// UNDONE: ToolTask has a "UseCommandProcessor" flag that duplicates much of the code in this class. Remove the duplication.
+ [MSBuildMultiThreadableTask]
public class Exec : ToolTaskExtension
{
#region Constructors
@@ -46,7 +47,7 @@ public Exec()
// Are the encodings for StdErr and StdOut streams valid
private bool _encodingParametersValid = true;
- private string _workingDirectory;
+ private AbsolutePath _workingDirectory;
private ITaskItem[] _outputs;
internal bool workingDirectoryIsUNC; // internal for unit testing
private string _batchFile;
@@ -196,7 +197,7 @@ public ITaskItem[] Outputs
///
private void CreateTemporaryBatchFile()
{
- var encoding = EncodingUtilities.BatchFileEncoding(Command + WorkingDirectory, UseUtf8Encoding);
+ var encoding = EncodingUtilities.BatchFileEncoding(Command + _workingDirectory.Value, UseUtf8Encoding);
// Temporary file with the extension .Exec.bat
_batchFile = FileUtilities.GetTemporaryFileName(".exec.cmd");
@@ -244,7 +245,7 @@ private void CreateTemporaryBatchFile()
// https://support.microsoft.com/en-us/kb/156276
if (workingDirectoryIsUNC)
{
- sw.WriteLine("pushd " + _workingDirectory);
+ sw.WriteLine("pushd " + _workingDirectory.Value);
}
}
else
@@ -458,10 +459,10 @@ protected override bool ValidateParameters()
}
// determine what the working directory for the exec command is going to be -- if the user specified a working
- // directory use that, otherwise it's the current directory
+ // directory use that, otherwise default to the project directory (TaskEnvironment.ProjectDirectory).
_workingDirectory = !string.IsNullOrEmpty(WorkingDirectory)
- ? WorkingDirectory
- : Directory.GetCurrentDirectory();
+ ? TaskEnvironment.GetAbsolutePath(WorkingDirectory)
+ : TaskEnvironment.ProjectDirectory;
// check if the working directory we're going to use for the exec command is a UNC path
workingDirectoryIsUNC = FileUtilitiesRegex.StartsWithUncPattern(_workingDirectory);
@@ -470,7 +471,10 @@ protected override bool ValidateParameters()
// will not be able to auto-map to the UNC path
if (workingDirectoryIsUNC && NativeMethods.AllDrivesMapped())
{
- Log.LogErrorWithCodeFromResources("Exec.AllDriveLettersMappedError", _workingDirectory);
+ Log.LogErrorWithCodeFromResources(
+ "Exec.AllDriveLettersMappedError",
+ _workingDirectory.OriginalValue,
+ _workingDirectory.Value);
return false;
}
@@ -508,7 +512,9 @@ protected override string GenerateFullPathToTool()
// a bad path being returned above on Nano Server SKUs of Windows.
if (!FileSystems.Default.FileExists(systemCmd))
{
+#pragma warning disable MSBuildTask0002 // We do not support changing of ComSpec during execution
return Environment.GetEnvironmentVariable("ComSpec");
+#pragma warning restore MSBuildTask0002
}
#endif
@@ -533,7 +539,7 @@ protected override string GetWorkingDirectory()
// So verify it's valid here.
if (!FileSystems.Default.DirectoryExists(_workingDirectory))
{
- throw new DirectoryNotFoundException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("Exec.InvalidWorkingDirectory", _workingDirectory));
+ throw new DirectoryNotFoundException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("Exec.InvalidWorkingDirectory", _workingDirectory.OriginalValue));
}
if (workingDirectoryIsUNC)
diff --git a/src/Tasks/Resources/Strings.resx b/src/Tasks/Resources/Strings.resx
index 9058e59073e..940e9aec7f5 100644
--- a/src/Tasks/Resources/Strings.resx
+++ b/src/Tasks/Resources/Strings.resx
@@ -394,7 +394,7 @@
If this bucket overflows, pls. contact 'vsppbdev'.
-->
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.cs.xlf b/src/Tasks/Resources/xlf/Strings.cs.xlf
index 641b7a045dc..3f72df6343a 100644
--- a/src/Tasks/Resources/xlf/Strings.cs.xlf
+++ b/src/Tasks/Resources/xlf/Strings.cs.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: Všechna písmena jednotek od A: po Z: jsou aktuálně použita. Protože pracovní adresář {0} je cesta UNC, potřebuje úloha Exec volné písmeno jednotky pro namapování cesty UNC. Odpojením některých sdílených prostředků uvolněte písmena jednotek. Můžete také zadat místní pracovní adresář. Potom spusťte příkaz znovu.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.de.xlf b/src/Tasks/Resources/xlf/Strings.de.xlf
index b8fab0f6fa9..2f266709ba3 100644
--- a/src/Tasks/Resources/xlf/Strings.de.xlf
+++ b/src/Tasks/Resources/xlf/Strings.de.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: Alle Laufwerkbuchstaben von A: bis Z: werden zurzeit verwendet. Da das Arbeitsverzeichnis "{0}" ein UNC-Pfad ist, ist für die Exec-Aufgabe ein freier Laufwerkbuchstabe für die Zuordnung des UNC-Pfads erforderlich. Trennen Sie die Verbindung mindestens einer freigegebenen Ressource, um Laufwerkbuchstaben freizugeben, oder geben Sie ein lokales Arbeitsverzeichnis an, bevor Sie diesen Befehl wiederholen.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.es.xlf b/src/Tasks/Resources/xlf/Strings.es.xlf
index 396d3d1ce66..331dd231a21 100644
--- a/src/Tasks/Resources/xlf/Strings.es.xlf
+++ b/src/Tasks/Resources/xlf/Strings.es.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: En este momento están en uso todas las letras de unidad, de la A: a la Z: Como el directorio de trabajo "{0}" es una ruta de acceso UNC, la tarea "Exec" requiere una letra de unidad libre a la que asignar la ruta de acceso UNC. Desconéctese de uno o varios recursos compartidos para liberar letras de unidad, o bien especifique un directorio de trabajo local antes de intentar ejecutar este comando de nuevo.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.fr.xlf b/src/Tasks/Resources/xlf/Strings.fr.xlf
index 69e6c5dc410..ec4b79919b6 100644
--- a/src/Tasks/Resources/xlf/Strings.fr.xlf
+++ b/src/Tasks/Resources/xlf/Strings.fr.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: Toutes les lettres de lecteur de A: à Z: sont actuellement utilisées. Le répertoire de travail "{0}" étant un chemin UNC, la tâche "Exec" nécessite une lettre de lecteur disponible à laquelle le chemin UNC sera mappé. Déconnectez-vous d'une ou de plusieurs ressources partagées pour libérer des lettres de lecteur ou spécifiez un répertoire de travail local avant de réexécuter cette commande.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.it.xlf b/src/Tasks/Resources/xlf/Strings.it.xlf
index 70ced74ba52..108d4854526 100644
--- a/src/Tasks/Resources/xlf/Strings.it.xlf
+++ b/src/Tasks/Resources/xlf/Strings.it.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: attualmente sono in uso tutte le lettere di unità comprese tra A: e Z:. Poiché la directory di lavoro "{0}" è un percorso UNC, per l'attività "Exec" è necessaria una lettera di unità disponibile a cui mappare il percorso UNC. Eseguire la disconnessione da una o più risorse condivise per rendere disponibili lettere di unità oppure specificare una directory di lavoro locale prima di provare a eseguire nuovamente questo comando.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.ja.xlf b/src/Tasks/Resources/xlf/Strings.ja.xlf
index 535a63d5e98..42db633d25f 100644
--- a/src/Tasks/Resources/xlf/Strings.ja.xlf
+++ b/src/Tasks/Resources/xlf/Strings.ja.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: A: から Z: までのすべてのドライブ文字は使用中です。作業ディレクトリ "{0}" は UNC パスであるため、"Exec" タスクには UNC パスをマップできる使用可能なドライブ文字が必要です。このコマンドを再度試してみる前に、1 つ以上の共有リソースを切断してドライブ文字を解放するか、ローカルの作業ディレクトリを指定してください。
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.ko.xlf b/src/Tasks/Resources/xlf/Strings.ko.xlf
index dba820eb07e..d38ba4a5989 100644
--- a/src/Tasks/Resources/xlf/Strings.ko.xlf
+++ b/src/Tasks/Resources/xlf/Strings.ko.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: A:에서 Z:까지 모든 드라이브 문자가 현재 사용 중입니다. 작업 디렉터리 "{0}"이(가) UNC 경로이므로 "Exec" 작업을 수행하려면 UNC 경로를 매핑하는 데 사용할 수 있는 드라이브 문자가 필요합니다. 하나 이상의 공유 리소스에서 연결을 끊어 사용 가능한 드라이브 문자를 만들거나 로컬 작업 디렉터리를 지정한 다음 이 명령을 다시 실행하세요.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.pl.xlf b/src/Tasks/Resources/xlf/Strings.pl.xlf
index 3b950f4f12b..67f77f3ae4a 100644
--- a/src/Tasks/Resources/xlf/Strings.pl.xlf
+++ b/src/Tasks/Resources/xlf/Strings.pl.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: Wszystkie litery dysków od A: do Z: są obecnie zajęte. Ponieważ katalog roboczy „{0}” jest ścieżką UNC, zadanie „Exec” potrzebuje wolnej litery dysku do zamapowania ścieżki UNC. Odłącz się od co najmniej jednego zasobu udostępnionego, aby zwolnić litery dysków, lub określ lokalny katalog roboczy przed ponownym użyciem tego polecenia.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.pt-BR.xlf b/src/Tasks/Resources/xlf/Strings.pt-BR.xlf
index 4626c0cb203..fc332daaf88 100644
--- a/src/Tasks/Resources/xlf/Strings.pt-BR.xlf
+++ b/src/Tasks/Resources/xlf/Strings.pt-BR.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: Todas as letras de unidade de A: a Z: estão em uso no momento. Como o diretório de trabalho "{0}" é um caminho UNC, a tarefa "Exec" precisa de uma letra da unidade livre na qual mapear o caminho UNC. Desconecte um ou mais recursos compartilhados para liberar algumas letras da unidade ou especifique um diretório de trabalho local antes de tentar usar esse comando novamente.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.ru.xlf b/src/Tasks/Resources/xlf/Strings.ru.xlf
index 0bc67650363..a6928e63a2b 100644
--- a/src/Tasks/Resources/xlf/Strings.ru.xlf
+++ b/src/Tasks/Resources/xlf/Strings.ru.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: все буквы дисков (от A: до Z:) сейчас используются. Поскольку рабочий каталог "{0}" указан в виде UNC-пути, задаче Exec требуется свободная буква диска для сопоставления с этим UNC-путем. Перед повторением этой команды отключитесь от одного или нескольких общих ресурсов, чтобы освободить буквы дисков, или укажите локальный рабочий каталог.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.tr.xlf b/src/Tasks/Resources/xlf/Strings.tr.xlf
index 5550a0c902a..891ee34aa50 100644
--- a/src/Tasks/Resources/xlf/Strings.tr.xlf
+++ b/src/Tasks/Resources/xlf/Strings.tr.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: A: ile Z: arasındaki tüm sürücü harfleri şu anda kullanımda. "{0}" çalışma dizini bir UNC yolu olduğundan, "Exec" görevinin UNC yolunu eşleyeceği serbest bir sürücü harfi gerekiyor. Sürücü harflerini serbest bırakmak üzere bir veya birden çok paylaşılan kaynağın bağlantısını kesin veya bu komutu yeniden denemeden önce yerel bir çalışma dizini belirtin.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.zh-Hans.xlf b/src/Tasks/Resources/xlf/Strings.zh-Hans.xlf
index 68d79cfa21e..3e6992f825f 100644
--- a/src/Tasks/Resources/xlf/Strings.zh-Hans.xlf
+++ b/src/Tasks/Resources/xlf/Strings.zh-Hans.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: 所有驱动器号(从 A: 到 Z:)当前都在使用。由于工作目录“{0}”是 UNC 路径,“Exec”任务需要将 UNC 路径映射到一个空闲的驱动器号。请从一个或多个共享资源断开连接以释放驱动器号,或在再次尝试执行此命令前指定本地工作目录。
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.
diff --git a/src/Tasks/Resources/xlf/Strings.zh-Hant.xlf b/src/Tasks/Resources/xlf/Strings.zh-Hant.xlf
index 88da3b30f3e..084cfb7da52 100644
--- a/src/Tasks/Resources/xlf/Strings.zh-Hant.xlf
+++ b/src/Tasks/Resources/xlf/Strings.zh-Hant.xlf
@@ -490,8 +490,8 @@
{StrBegin="MSB3924: "}
- MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
- MSB3071: 從 A: 到 Z: 的所有磁碟機代號目前都在使用中。由於工作目錄 "{0}" 是 UNC 路徑,因此 "Exec" 工作需要有可用的磁碟機代號以便對應 UNC 路徑。請先中斷一或多個共用資源的連線以釋放磁碟機代號,或指定本機工作目錄,再嘗試重新執行這個命令。
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.
+ MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" (resolved to UNC path "{1}") requires a UNC mapping, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again.{StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized.