private static void ConvertSymbols(IVsOutputWindowPane outputPane, string monoPath, string pdb2MdbPath, string outputDirectory, string filePath) { var startInfo = new ProcessStartInfo { Arguments = "\"" + pdb2MdbPath + "\" \"" + filePath + "\"", WorkingDirectory = outputDirectory, CreateNoWindow = true, FileName = monoPath, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; var process = new Process { StartInfo = startInfo }; process.OutputDataReceived += (sender, args) => { if (!string.IsNullOrWhiteSpace(args.Data)) outputPane.Log($"pdb2mdb> {args.Data}"); }; process.ErrorDataReceived += (sender, args) => { if (!string.IsNullOrWhiteSpace(args.Data)) outputPane.Log($"pdb2mdb> ERROR: {args.Data}"); }; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); }
public static int RunCommand(this SshClient ssh, string commandText, IVsOutputWindowPane outputPane, string project) { var command = ssh.CreateCommand(commandText); var asyncResult = command.BeginExecute(null); using (var reader = new StreamReader(command.OutputStream)) { var s = reader.ReadToEnd(); var atWarnings = false; var atErrors = false; foreach (var line in s.Split('\n')) { if (line == "Warnings:") { atWarnings = true; } if (line == "Errors:") { atErrors = true; } var errorMatch = errorRegex.Match(line); var locationlessErrorMatch = locationlessErrorRegex.Match(line); var match = errorMatch.Success ? errorMatch : locationlessErrorMatch; if ((atWarnings || atErrors) && match.Success) { var file = match.Groups[1].Value.Trim(); var lineNumber = 1; var column = 0; string message; if (errorMatch.Success) { lineNumber = int.Parse(errorMatch.Groups[2].Value); column = int.Parse(errorMatch.Groups[3].Value); message = errorMatch.Groups[4].Value.Trim(); } else { message = locationlessErrorMatch.Groups[2].Value.Trim(); } VsLogSeverity severity = message.StartsWith("error") ? VsLogSeverity.Error : message.StartsWith("warning") ? VsLogSeverity.Warning : VsLogSeverity.Message; int firstSpace = message.IndexOf(' '); message = message.Substring(firstSpace + 1).TrimStart(' ', ':'); outputPane.Log(severity, project, file, line, message, lineNumber - 1, column); } else { outputPane.Log(line); } } } command.EndExecute(asyncResult); return(command.ExitStatus); }
public void Flush(IVsOutputWindowPane outputPane) { while (_buffer.Any()) { var entry = _buffer.Dequeue(); outputPane.Log(entry.Severity, entry.Project, entry.File, entry.LogMessage, entry.ItemMessage, entry.Line, entry.Column, entry.ErrorCode); } }
private static SshCommand BeginCommand(this SshClient ssh, string commandText, IVsOutputWindowPane outputPane, AsyncCallback callback, out IAsyncResult asyncResult) { var command = ssh.CreateCommand(commandText); var isRunning = true; asyncResult = command.BeginExecute(ar => { isRunning = false; callback?.Invoke(ar); }); var asyncHandle = asyncResult; Task.Run(() => { using (var reader = new StreamReader(command.OutputStream)) { // This is so convoluted because strangely reader.ReadLine() will return null even when the program // is still running. do { for (var line = reader.ReadLine(); line != null; line = reader.ReadLine()) { outputPane.Log(line); } Thread.Sleep(10); }while (isRunning); var s = command.EndExecute(asyncHandle); if (!string.IsNullOrEmpty(s)) { outputPane.Log(s); } } }); return(command); }
public int StartBuild(IVsOutputWindowPane outputPane, uint dwOptions) { var buildHost = this[MonoPropertyPage.BuildHostProperty]; var dteProject = GetDTEProject(project); var projectFolder = Path.GetDirectoryName(dteProject.FullName); outputPane.Log($"Starting build of {projectFolder}..."); // If using Windows Bash... if (string.IsNullOrEmpty(buildHost)) { var bash = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Sysnative", "bash.exe"); if (!File.Exists(bash)) { // outputPane.LogError(dteProject.FullName, $"Error: You must set up a build server on the 'Mono' project property page."); outputPane.Log(VsLogSeverity.Error, dteProject.UniqueName, dteProject.FullName, "Error: You must set up a build server on the 'Mono' project property page."); UpdateBuildStatus(0); return(VSConstants.S_FALSE); } var bashProjectFolder = ConvertToUnixPath(projectFolder); var outputFile = Path.GetTempFileName(); var script = $@"cd ""{bashProjectFolder}"" xbuild > ""{ConvertToUnixPath(outputFile)}"" exit ".Replace("\r\n", "\n"); var scriptFile = Path.GetTempFileName(); var arguments = $"/C {bash} --init-file {ConvertToUnixPath(scriptFile)}"; File.WriteAllText(scriptFile, script); var process = new System.Diagnostics.Process { StartInfo = new ProcessStartInfo("CMD", arguments) { WindowStyle = ProcessWindowStyle.Hidden } }; process.Start(); process.WaitForExit(); outputPane.Log(File.ReadAllText(outputFile)); try { File.Delete(scriptFile); File.Delete(outputFile); } catch (Exception e) { outputPane.Log(e.ToString()); } } else { outputPane.Log("Uploading project to the build server..."); var buildUsername = this[MonoPropertyPage.BuildUsernameProperty]; var buildPassword = this[MonoPropertyPage.BuildPasswordProperty]; var buildFolder = this[MonoPropertyPage.BuildFolderProperty]; using (var client = new SftpClient(buildHost, buildUsername, buildPassword)) { client.Connect(); client.CreateFullDirectory(buildFolder); client.ChangeDirectory(buildFolder); outputPane.Log($"Clearing out the contents of the build folder: {buildFolder}"); client.Clear(); // Upload project var createdDirectories = new HashSet <string>(); var projectFile = Path.GetFileName(dteProject.FullName); client.Upload(projectFolder, projectFile, createdDirectories); outputPane.Log($"Uploaded {projectFile}"); var projectItems = new Queue <ProjectItem>(dteProject.ProjectItems.Cast <ProjectItem>()); while (projectItems.Any()) { var projectItem = projectItems.Dequeue(); for (short i = 1; i <= projectItem.FileCount; i++) { var fileName = projectItem.FileNames[i]; if (File.Exists(fileName)) { fileName = FileUtils.ToRelativePath(projectFolder, fileName); client.Upload(projectFolder, fileName, createdDirectories); outputPane.Log($"Uploaded {fileName}"); } } foreach (ProjectItem childItem in projectItem.ProjectItems) { projectItems.Enqueue(childItem); } } using (var ssh = new SshClient(buildHost, buildUsername, buildPassword)) { outputPane.Log("Starting xbuild to build the project"); ssh.Connect(); var exitCode = ssh.RunCommand($@"cd {buildFolder}; xbuild /p:Configuration={dteProject.ConfigurationManager.ActiveConfiguration.ConfigurationName} > xbuild.output; exitcode=$?; cat xbuild.output; rm xbuild.output; exit ""$exitcode""", outputPane, dteProject.UniqueName); if (exitCode != 0) { UpdateBuildStatus(0); return(VSConstants.S_FALSE); } } var projectConfiguration = dteProject.ConfigurationManager.ActiveConfiguration; var outputFolder = Path.GetDirectoryName(Path.Combine(projectFolder, projectConfiguration.Properties.Item("OutputPath").Value.ToString())); outputPane.Log($"Copying build artifacts to the output folder: {outputFolder}"); var buildServerOutputPath = buildFolder + "/" + FileUtils.ToRelativePath(projectFolder, outputFolder).Replace("\\", "/"); client.CreateFullDirectory(buildServerOutputPath); client.ChangeDirectory(buildServerOutputPath); foreach (var file in client.ListDirectory(".").Where(x => x.IsRegularFile)) { using (var output = new FileStream(Path.Combine(outputFolder, file.Name), FileMode.Create, FileAccess.Write)) { client.DownloadFile(file.FullName, output); outputPane.Log($"Copied {file.Name}"); } } client.Disconnect(); } } UpdateBuildStatus(1); return(VSConstants.S_OK); }
public static void Log(this IVsOutputWindowPane pane, VsLogSeverity severity, string project, string file, string consoleMessage, int lineNumber = 0, int column = 0) { pane.Log(severity, project, file, consoleMessage, consoleMessage, lineNumber, column); }
private bool ConvertSymbols(IVsOutputWindowPane outputPane) { // Compute some paths var dteProject = GetDteProject(); var activeConfiguration = dteProject.ConfigurationManager.ActiveConfiguration; var projectDirectory = Path.GetDirectoryName(dteProject.FullName); var outputPath = activeConfiguration.Properties.Item("OutputPath").Value.ToString(); var outputDirectory = Path.GetDirectoryName(MakeAbsolutePath(outputPath, projectDirectory)); var monoDirectory = MakeAbsolutePath(this[SampSharpPropertyPage.MonoDirectory], projectDirectory); var monoPath = Path.Combine(monoDirectory, @"bin\mono.exe"); var pdb2MdbPath = Path.Combine(monoDirectory, @"lib\mono\4.5\pdb2mdb.exe"); outputPane.Log($"Mono runtime path: {monoDirectory}."); // Perform some path validity checks. if (string.IsNullOrWhiteSpace(outputDirectory) || !Directory.Exists(outputDirectory)) { outputPane.Log(VsLogSeverity.Error, dteProject.UniqueName, dteProject.FullName, "Missing output directory."); UpdateBuildStatus(false); return false; } if (string.IsNullOrWhiteSpace(monoDirectory) || !Directory.Exists(monoDirectory)) { outputPane.Log(VsLogSeverity.Error, dteProject.UniqueName, dteProject.FullName, "You must set up the mono runtime directory on the 'SampSharp' project property page."); UpdateBuildStatus(false); return false; } if (!File.Exists(monoPath)) { outputPane.Log(VsLogSeverity.Error, dteProject.UniqueName, dteProject.FullName, "mono is missing from the specified mono runtime directory. Are you sure you selected the right directory?"); UpdateBuildStatus(false); return false; } if (!File.Exists(pdb2MdbPath)) { outputPane.Log(VsLogSeverity.Error, dteProject.UniqueName, dteProject.FullName, "Error: pdb2mdb is missing from the specified mono runtime directory. Are you sure you selected the right directory?"); UpdateBuildStatus(false); return false; } foreach (var pdbPath in Directory.GetFiles(outputDirectory, "*.pdb")) { var dllPath = Path.Combine(Path.GetDirectoryName(pdbPath) ?? string.Empty, $"{Path.GetFileNameWithoutExtension(pdbPath)}.dll"); var mdbPath = $"{dllPath}.mdb"; if (!File.Exists(dllPath)) { continue; } var hasBeenModified = !File.Exists(mdbPath); if (!hasBeenModified) { var mdbDate = File.GetLastWriteTime(mdbPath); var pdbDate = File.GetLastWriteTime(pdbPath); hasBeenModified = pdbDate - mdbDate > new TimeSpan(0); } if (!hasBeenModified) continue; outputPane.Log($"pdb2mdb> Converting symbols for {dllPath}"); ConvertSymbols(outputPane, monoPath, pdb2MdbPath, outputDirectory, dllPath); } return true; }
private void Log(string message) { _serverPane?.Log(message); }