public override bool Execute() { if (string.IsNullOrEmpty(LinkName)) { throw new InvalidOperationException("LinkName was not set"); } if (string.IsNullOrEmpty(TargetName)) { throw new InvalidOperationException("TargetName was not set"); } var exists = SymlinkTargetType == SymlinkTargetType.Directory ? Directory.Exists(LinkName) : File.Exists(LinkName); if (exists) { // if this is already a symlink, check if it points to the same target and if not then delete it var isSymlink = (File.GetAttributes(LinkName) & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint; if (isSymlink) { var querySymlinkTask = new QuerySymlink { LinkName = LinkName, TargetName = TargetName, TargetType = TargetType, BuildEngine = BuildEngine }; if (!querySymlinkTask.Execute()) { return(false); } Log.LogMessage(MessageImportance.Low, $"{SymlinkTargetType} '{LinkName}' is a symlink which points to '{querySymlinkTask.TargetName}'"); if (string.Equals(querySymlinkTask.TargetName, TargetName.TrimEnd('\\'), StringComparison.InvariantCultureIgnoreCase)) { // the symlink's target matches our target return(true); } Log.LogMessage(MessageImportance.Normal, $"Deleting symlink '{LinkName}' because it points to a different target '{querySymlinkTask.TargetName}'"); } else { Log.LogMessage(MessageImportance.Normal, $"{SymlinkTargetType} '{LinkName}' needs to be deleted before converting it to a symlink"); } // if this is reached then delete is needed DeleteDirectoryOrFile(); } var createSymlinkTask = new CreateSymlink { LinkName = LinkName, TargetName = TargetName, TargetType = TargetType, BuildEngine = BuildEngine }; return(createSymlinkTask.Execute()); }
public override bool Execute() { if (string.IsNullOrEmpty(LinkName)) { throw new InvalidOperationException("LinkName was not set"); } if (string.IsNullOrEmpty(TargetName)) { throw new InvalidOperationException("TargetName was not set"); } var linkParentDirectory = Path.GetDirectoryName(LinkName.TrimEnd('\\')); try { if (linkParentDirectory != null && !Directory.Exists(linkParentDirectory)) { Directory.CreateDirectory(linkParentDirectory); } } catch (Exception ex) { Log.LogError($"Error creating symbolic link for {LinkName} <<====>> {TargetName}. Could not create parent directory {linkParentDirectory}: {ex.Message}"); return(false); } var result = NativeMethods.CreateSymbolicLink(LinkName.TrimEnd('\\'), TargetName.TrimEnd('\\'), _targetType); if (!result) { const uint requiredPrivilegeError = 0x80070522; if ((uint)Marshal.GetHRForLastWin32Error() == requiredPrivilegeError) { Log.LogError($"Error creating symbolic link for {LinkName} <<====>> {TargetName}. Try running the build from an elevated process."); return(false); } var exception = Win32Utils.GetExceptionForLastError(); Log.LogError($"Error creating symbolic link for {LinkName} <<====>> {TargetName}: {exception.Message}"); return(false); } Log.LogMessage(MessageImportance.High, $"Symbolic link created for {LinkName} <<====>> {TargetName}"); return(true); }