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();
 }
예제 #2
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
 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);
 }