├── .gitignore ├── FASTBuildMonitorVSIX ├── FASTBuildMonitor │ ├── Code │ │ ├── FASTBuildMonitorControl.xaml │ │ ├── FASTBuildMonitorControl.xaml.cs │ │ ├── GifImage.cs │ │ ├── SystemPerformanceGraphsCanvas.cs │ │ ├── TextUtils.cs │ │ └── Timebar.cs │ ├── FASTBuildMonitor.csproj │ ├── Key.snk │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Resources │ │ ├── BuildStatusErrors.png │ │ ├── BuildStatusOK.png │ │ ├── BuildStatusWarnings.png │ │ ├── Failed.png │ │ ├── HeartBeat.gif │ │ ├── Images.Designer.cs │ │ ├── Images.png │ │ ├── Images.resx │ │ ├── LODBlock.png │ │ ├── ProgressBar.gif │ │ ├── Running.png │ │ ├── SettingsTabIcon.png │ │ ├── Spinner.gif │ │ ├── Success-cached.png │ │ ├── Success-code.png │ │ ├── Success-noncode.png │ │ ├── Success-preprocessed.png │ │ ├── TextOutputTabIcon.png │ │ ├── Themes │ │ ├── DarkTheme.xaml │ │ └── DefaultTheme.xaml │ │ ├── TimeLineTabIcon.png │ │ ├── Timeout.png │ │ ├── Warning.png │ │ ├── box.gif │ │ ├── race_flag.png │ │ ├── race_flag_lost.png │ │ └── race_flag_win.png ├── FASTBuildMonitorStandalone │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── FASTBuildMonitorStandalone.csproj │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ └── Resources │ │ └── green.ico ├── FASTBuildMonitorVSIX.sln ├── FASTBuildMonitorVSIX │ ├── Code │ │ ├── FASTBuildMonitorCommand.cs │ │ ├── FASTBuildMonitorPackage.cs │ │ └── FASTBuildMonitorPane.cs │ ├── FASTBuildMonitorPackage.cs │ ├── FASTBuildMonitorPackage.vsct │ ├── FASTBuildMonitorVSIX.csproj │ ├── Key.snk │ ├── Manifests │ │ ├── Legacy │ │ │ ├── source.extension.cs │ │ │ └── source.extension.vsixmanifest │ │ ├── source.extension.cs │ │ └── source.extension.vsixmanifest │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── FASTBuildMonitorCommand.png │ │ ├── FASTBuildMonitorPackage.ico │ │ └── Images.png │ ├── VSPackage.resx │ ├── stylesheet.css │ └── vsix │ │ └── FASTBuildMonitorVSIX.vsix └── nuget.config ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /FASTBuildMonitorVSIX/FASTBuildMonitor/bin 6 | /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/bin 7 | /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/bin 8 | /FASTBuildMonitorVSIX/.vs 9 | /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/lib 10 | /FASTBuildMonitorVSIX/FASTBuildMonitor/obj 11 | /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/obj 12 | /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/obj 13 | 14 | # Ignore .user files 15 | *.user 16 | 17 | # Ignore .lock.json file(Visual Studio nuget local state file that must NOT be in source control) 18 | *.lock.json 19 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Code/FASTBuildMonitorControl.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | http://www.knownshippable.com 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | https://github.com/yass007/FASTBuildMonitor 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Code/GifImage.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright 2017 Yassine Riahi and Liam Flookes. 3 | // Provided under a MIT License, see license file on github. 4 | //------------------------------------------------------------------------------ 5 | 6 | using System; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Media.Animation; 10 | using System.Windows.Media.Imaging; 11 | 12 | namespace FASTBuildMonitor 13 | { 14 | class GifImage : Image 15 | { 16 | private bool _isInitialized; 17 | private GifBitmapDecoder _gifDecoder; 18 | private Int32Animation _animation; 19 | 20 | public int FrameIndex 21 | { 22 | get { return (int)GetValue(FrameIndexProperty); } 23 | set { SetValue(FrameIndexProperty, value); } 24 | } 25 | 26 | private void Initialize() 27 | { 28 | _gifDecoder = FASTBuildMonitorControl.GetGifBitmapDecoder(GifSource); 29 | _animation = new Int32Animation(0, _gifDecoder.Frames.Count - 1, new Duration(new TimeSpan(0, 0, 0, _gifDecoder.Frames.Count / 10, (int)((_gifDecoder.Frames.Count / 10.0 - _gifDecoder.Frames.Count / 10) * 1000)))); 30 | _animation.RepeatBehavior = RepeatBehavior.Forever; 31 | this.Source = _gifDecoder.Frames[0]; 32 | 33 | _isInitialized = true; 34 | } 35 | 36 | static GifImage() 37 | { 38 | VisibilityProperty.OverrideMetadata(typeof(GifImage), 39 | new FrameworkPropertyMetadata(VisibilityPropertyChanged)); 40 | } 41 | 42 | private static void VisibilityPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 43 | { 44 | if ((Visibility)e.NewValue == Visibility.Visible) 45 | { 46 | ((GifImage)sender).StartAnimation(); 47 | } 48 | else 49 | { 50 | ((GifImage)sender).StopAnimation(); 51 | } 52 | } 53 | 54 | public static readonly DependencyProperty FrameIndexProperty = 55 | DependencyProperty.Register("FrameIndex", typeof(int), typeof(GifImage), new UIPropertyMetadata(0, new PropertyChangedCallback(ChangingFrameIndex))); 56 | 57 | static void ChangingFrameIndex(DependencyObject obj, DependencyPropertyChangedEventArgs ev) 58 | { 59 | var gifImage = obj as GifImage; 60 | gifImage.Source = gifImage._gifDecoder.Frames[(int)ev.NewValue]; 61 | } 62 | 63 | /// 64 | /// Defines whether the animation starts on it's own 65 | /// 66 | public bool AutoStart 67 | { 68 | get { return (bool)GetValue(AutoStartProperty); } 69 | set { SetValue(AutoStartProperty, value); } 70 | } 71 | 72 | public static readonly DependencyProperty AutoStartProperty = 73 | DependencyProperty.Register("AutoStart", typeof(bool), typeof(GifImage), new UIPropertyMetadata(false, AutoStartPropertyChanged)); 74 | 75 | private static void AutoStartPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 76 | { 77 | if ((bool)e.NewValue) 78 | (sender as GifImage).StartAnimation(); 79 | } 80 | 81 | public string GifSource 82 | { 83 | get { return (string)GetValue(GifSourceProperty); } 84 | set { SetValue(GifSourceProperty, value); } 85 | } 86 | 87 | public static readonly DependencyProperty GifSourceProperty = 88 | DependencyProperty.Register("GifSource", typeof(string), typeof(GifImage), new UIPropertyMetadata(string.Empty, GifSourcePropertyChanged)); 89 | 90 | private static void GifSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 91 | { 92 | (sender as GifImage).Initialize(); 93 | } 94 | 95 | /// 96 | /// Starts the animation 97 | /// 98 | public void StartAnimation() 99 | { 100 | if (!_isInitialized) 101 | this.Initialize(); 102 | 103 | BeginAnimation(FrameIndexProperty, _animation); 104 | } 105 | 106 | /// 107 | /// Stops the animation 108 | /// 109 | public void StopAnimation() 110 | { 111 | BeginAnimation(FrameIndexProperty, null); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Code/SystemPerformanceGraphsCanvas.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright 2017 Yassine Riahi and Liam Flookes. 3 | // Provided under a MIT License, see license file on github. 4 | //------------------------------------------------------------------------------ 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Diagnostics; 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Shapes; 14 | 15 | namespace FASTBuildMonitor 16 | { 17 | public class SystemPerformanceGraphsCanvas : Canvas 18 | { 19 | public SystemPerformanceGraphsCanvas(Canvas parentCanvas) 20 | { 21 | _parentCanvas = parentCanvas; 22 | 23 | this.Width = _parentCanvas.Width; 24 | this.Height = cSystemGraphsHeight; 25 | 26 | _parentCanvas.Children.Add(this); 27 | 28 | //RenderOptions.SetEdgeMode(this, EdgeMode.Aliased); 29 | 30 | SetVisibility((bool)FASTBuildMonitorControl._StaticWindow.SettingsGraphsCheckBox.IsChecked); 31 | } 32 | 33 | public class Sample 34 | { 35 | public Int64 _time = 0; 36 | public float _value = 0.0f; 37 | 38 | public Sample(Int64 time, float value) 39 | { 40 | _time = time; 41 | _value = value; 42 | } 43 | } 44 | 45 | public class PerformanceCountersGroup 46 | { 47 | public enum PerformanceCounterType 48 | { 49 | RAM_Used = 0, 50 | CPU_Time, 51 | DISK_Read, 52 | DISK_Write, 53 | NET_Received, 54 | NET_Sent, 55 | Custom, 56 | Max 57 | } 58 | 59 | public class BasicPerformanceCounter 60 | { 61 | public static SolidColorBrush[] _sColors = new SolidColorBrush[] { Brushes.Blue, 62 | Brushes.Red, 63 | Brushes.Orange, 64 | Brushes.Aquamarine, 65 | Brushes.Black, 66 | Brushes.Chocolate, 67 | Brushes.Yellow, 68 | Brushes.Green, 69 | Brushes.Gray, 70 | Brushes.Fuchsia, 71 | Brushes.DarkGreen, 72 | Brushes.MediumVioletRed, 73 | Brushes.Cyan, 74 | Brushes.Maroon, 75 | Brushes.Salmon, 76 | Brushes.DarkViolet, 77 | Brushes.Brown, 78 | Brushes.DarkGray 79 | }; 80 | 81 | public static int _sColorsIndex = 0; 82 | 83 | // attributes 84 | public TreeViewItem _treeViewItem; 85 | public CheckBox _checkBox; 86 | public SolidColorBrush _colorBrush; 87 | 88 | public PerformanceCounterType _type; 89 | 90 | private PerformanceCounter _systemPerfCounter; 91 | 92 | protected bool _bInitialized = false; 93 | 94 | public List _samples = new List(); 95 | 96 | public string _description; 97 | public string _unitTag; 98 | 99 | public float _valueDivider = 1.0f; 100 | 101 | public BasicPerformanceCounter(PerformanceCounterType type, bool bEnabled) 102 | { 103 | _type = type; 104 | 105 | _enabled = bEnabled; 106 | } 107 | 108 | protected void InitializeTreeViewItem() 109 | { 110 | _treeViewItem = new TreeViewItem(); 111 | 112 | StackPanel stackPanel = new StackPanel(); 113 | stackPanel.Orientation = Orientation.Horizontal; 114 | _treeViewItem.Header = stackPanel; 115 | 116 | _checkBox = new CheckBox(); 117 | _checkBox.IsChecked = _enabled; 118 | stackPanel.Children.Add(_checkBox); 119 | 120 | Canvas canvas = new Canvas() { Height = 10, Width = 10 }; 121 | 122 | if (_sColorsIndex < _sColors.Length) 123 | { 124 | _colorBrush = _sColors[_sColorsIndex++]; 125 | } 126 | else 127 | { 128 | _colorBrush = Brushes.Navy; 129 | } 130 | 131 | Line line = new Line() { Stroke = _colorBrush, StrokeThickness = 4, X1 = 0, Y1 = 5, X2 = 10, Y2 = 5 }; 132 | canvas.Children.Add(line); 133 | 134 | stackPanel.Children.Add(canvas); 135 | 136 | TextBlock textBlock = new TextBlock() { Text = _description }; 137 | stackPanel.Children.Add(textBlock); 138 | } 139 | 140 | public virtual void Initialize(System.Diagnostics.Process targetProcess, string description = "", string unitTag = "") 141 | { 142 | _description = description; 143 | _unitTag = unitTag; 144 | 145 | switch (_type) 146 | { 147 | case PerformanceCounterType.CPU_Time: 148 | 149 | _description = "Processor Time"; 150 | _unitTag = "% CPU"; 151 | 152 | if (targetProcess != null) 153 | { 154 | _systemPerfCounter = new PerformanceCounter("Process", "% Processor Time", targetProcess.ProcessName); 155 | } 156 | else 157 | { 158 | _systemPerfCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); 159 | } 160 | 161 | _bInitialized = true; 162 | break; 163 | case PerformanceCounterType.RAM_Used: 164 | 165 | _description = "Memory Used"; 166 | _unitTag = "MB"; 167 | 168 | _valueDivider = 1024.0f * 1024.0f; 169 | 170 | if (targetProcess != null) 171 | { 172 | _systemPerfCounter = new PerformanceCounter("Process", "Working Set", targetProcess.ProcessName); 173 | } 174 | else 175 | { 176 | _systemPerfCounter = new PerformanceCounter("Memory", "Committed Bytes", null); 177 | } 178 | 179 | _bInitialized = true; 180 | break; 181 | case PerformanceCounterType.DISK_Read: 182 | 183 | _description = "Disk IO Read"; 184 | _unitTag = "MB/s"; 185 | 186 | _valueDivider = 1024.0f * 1024.0f; 187 | 188 | if (targetProcess != null) 189 | { 190 | _systemPerfCounter = new PerformanceCounter("Process", "IO Read Bytes/sec", targetProcess.ProcessName); 191 | } 192 | else 193 | { 194 | _systemPerfCounter = new PerformanceCounter("PhysicalDisk", "Disk Read Bytes/sec", "_Total"); 195 | } 196 | 197 | _bInitialized = true; 198 | break; 199 | case PerformanceCounterType.DISK_Write: 200 | 201 | _description = "Disk IO Write"; 202 | _unitTag = "MB/s"; 203 | 204 | _valueDivider = 1024.0f * 1024.0f; 205 | 206 | if (targetProcess != null) 207 | { 208 | _systemPerfCounter = new PerformanceCounter("Process", "IO Write Bytes/sec", targetProcess.ProcessName); 209 | } 210 | else 211 | { 212 | _systemPerfCounter = new PerformanceCounter("PhysicalDisk", "Disk Write Bytes/sec", "_Total"); 213 | } 214 | 215 | _bInitialized = true; 216 | break; 217 | case PerformanceCounterType.Custom: 218 | _bInitialized = true; 219 | break; 220 | 221 | default: 222 | Console.WriteLine("BasicPerformanceCounter was not able to handle PerformanceCounterType: " + (int)_type); 223 | break; 224 | } 225 | 226 | InitializeTreeViewItem(); 227 | } 228 | 229 | 230 | public bool HandleLogEvent(Int64 eventTimeMS, float value) 231 | { 232 | bool bSuccess = false; 233 | 234 | if (_bInitialized) 235 | { 236 | Sample newSample = new Sample(eventTimeMS, value); 237 | 238 | _samples.Add(newSample); 239 | 240 | //Console.WriteLine("{0}: (time: {1} - value: {2} {3}", _description, newSample._time, newSample._value, _unitTag); 241 | 242 | UpdateMaxValue(value); 243 | 244 | bSuccess = true; 245 | } 246 | 247 | return bSuccess; 248 | } 249 | 250 | 251 | protected float _maxValue = 0.0f; 252 | 253 | protected void UpdateMaxValue(float newValue) 254 | { 255 | if (newValue > _maxValue) 256 | { 257 | _maxValue = newValue; 258 | } 259 | } 260 | 261 | public virtual bool CaptureNewSample() 262 | { 263 | bool bSuccess = false; 264 | 265 | if (_bInitialized) 266 | { 267 | Debug.Assert(_systemPerfCounter != null); 268 | 269 | try 270 | { 271 | float newValue = (float)(Math.Round((double)_systemPerfCounter.NextValue(), 1)) / _valueDivider; 272 | 273 | Sample newSample = new Sample(FASTBuildMonitorControl.GetCurrentBuildTimeMS(), newValue); 274 | 275 | _samples.Add(newSample); 276 | 277 | //Console.WriteLine("{0}: (time: {1} - value: {2} {3}", _description, newSample._time, newSample._value, _unitTag); 278 | 279 | UpdateMaxValue(newValue); 280 | 281 | bSuccess = true; 282 | } 283 | catch (System.Exception ex) 284 | { 285 | Console.WriteLine("Exception during perf counters sampling" + ex.ToString()); 286 | } 287 | } 288 | 289 | return bSuccess; 290 | } 291 | 292 | // enabled state 293 | public bool _enabled = false; 294 | 295 | private int _lastSamplesCount = 0; 296 | 297 | private Point _lastMousePos = new Point(-1.0f, -1.0f); 298 | 299 | private GraphPoint _selectedGraphPoint = null; 300 | 301 | private bool IsGraphSelected(Point newMousePos) 302 | { 303 | bool bSelected = false; 304 | 305 | if (_points.Count >= 2) 306 | { 307 | for (int i = 0; i + 1 < _points.Count; ++i) 308 | { 309 | GraphPoint P1 = _points[i]; 310 | GraphPoint P2 = _points[i + 1]; 311 | 312 | GraphPoint selectedGraphPoint = IsMousePosWithinSegment(newMousePos, P1, P2); 313 | 314 | if (selectedGraphPoint != null) 315 | { 316 | bSelected = true; 317 | break; 318 | } 319 | 320 | } 321 | } 322 | 323 | return bSelected; 324 | } 325 | 326 | // returns if the state has changed and we need to update the geometry 327 | private bool UpdateIntenalState(Point newMousePos) 328 | { 329 | bool bNeedsUpdateGeometry = false; 330 | 331 | bool bNewEnabledState = (bool)_checkBox.IsChecked; 332 | bool bNewSelectedState = false; 333 | 334 | if (bNewEnabledState != _enabled || _samples.Count != _lastSamplesCount) 335 | { 336 | bNeedsUpdateGeometry = true; 337 | } 338 | else if( _enabled ) 339 | { 340 | bool lastSelectedState = _selectedGraphPoint != null; 341 | 342 | if (newMousePos != new Point(-1.0f, -1.0f)) 343 | { 344 | bNewSelectedState = IsGraphSelected(newMousePos); 345 | } 346 | 347 | if (bNewSelectedState != lastSelectedState || (lastSelectedState && newMousePos != _lastMousePos)) 348 | { 349 | bNeedsUpdateGeometry = true; 350 | } 351 | } 352 | 353 | // refresh our internal state 354 | _enabled = (bool)_checkBox.IsChecked; 355 | 356 | _lastSamplesCount = _samples.Count; 357 | 358 | _lastMousePos = newMousePos; 359 | 360 | return bNeedsUpdateGeometry; 361 | } 362 | 363 | 364 | class GraphPoint 365 | { 366 | public Point _coordinates; 367 | public float _value; 368 | 369 | public GraphPoint(Point coordinates, float value) 370 | { 371 | _coordinates = coordinates; 372 | _value = value; 373 | } 374 | } 375 | 376 | List _points = new List(); 377 | 378 | private enum GraphMode 379 | { 380 | AverageValues, 381 | MaxValues, 382 | MinValues 383 | } 384 | 385 | private void CalculateGraphPoints(GraphMode mode, double X, double Y, double zoomFactor, Int64 timeStepMS) 386 | { 387 | _points.Clear(); 388 | 389 | Int64 totalTimeMS = 0; 390 | 391 | Int64 numSteps = FASTBuildMonitorControl.GetCurrentBuildTimeMS() / ((Int64)timeStepMS); 392 | Int64 remainder = FASTBuildMonitorControl.GetCurrentBuildTimeMS() % ((Int64)timeStepMS); 393 | 394 | numSteps += remainder > 0 ? 2 : 1; 395 | 396 | Int64 timeLimitMS = numSteps * (Int64)timeStepMS; 397 | 398 | float verticalPixPerUnit = cSystemGraphsHeight / Math.Max(_maxValue, 0.00001f); 399 | 400 | int samplesIndex = 0; 401 | 402 | // Sort the samples as sometimes fastbuild will write out of orders samples(writes are multithreaded) 403 | _samples.Sort((a, b) => a._time.CompareTo(b._time)); 404 | 405 | while (totalTimeMS <= timeLimitMS && samplesIndex < _samples.Count) 406 | { 407 | int subStepSamplesCount = 0; 408 | float subStepAvgValue = 0.0f; 409 | 410 | while (samplesIndex < _samples.Count && _samples[samplesIndex]._time <= (totalTimeMS + timeStepMS)) 411 | { 412 | subStepAvgValue += _samples[samplesIndex]._value; 413 | samplesIndex++; 414 | subStepSamplesCount++; 415 | 416 | // validation code to make sure times are monotonic 417 | if (samplesIndex + 1 < _samples.Count) 418 | { 419 | Debug.Assert(_samples[samplesIndex + 1]._time >= _samples[samplesIndex]._time); 420 | } 421 | } 422 | 423 | if (subStepSamplesCount > 0) 424 | { 425 | subStepAvgValue = subStepAvgValue / (float)subStepSamplesCount; 426 | 427 | double x = X + zoomFactor * FASTBuildMonitorControl.pix_per_second * (totalTimeMS + timeStepMS) / 1000.0f; 428 | double y = cSystemGraphsHeight - (subStepAvgValue * verticalPixPerUnit); 429 | 430 | y = Math.Max(0.0f, y); 431 | 432 | _points.Add(new GraphPoint(new Point(x, y), subStepAvgValue)); 433 | } 434 | 435 | totalTimeMS += timeStepMS; 436 | } 437 | } 438 | 439 | private void DrawFilledSquare(StreamGeometryContext ctx, Point centerPoint, float size) 440 | { 441 | Point p1 = new Point(centerPoint.X - size / 2.0f, centerPoint.Y - size/2.0f); 442 | Point p2 = new Point(centerPoint.X + size / 2.0f, centerPoint.Y - size / 2.0f); 443 | Point p3 = new Point(centerPoint.X + size / 2.0f, centerPoint.Y + size / 2.0f); 444 | Point p4 = new Point(centerPoint.X - size / 2.0f, centerPoint.Y + size / 2.0f); 445 | 446 | ctx.BeginFigure(p1, true, false); 447 | ctx.LineTo(p2, false, false); 448 | ctx.LineTo(p3, false, false); 449 | ctx.LineTo(p4, false, false); 450 | ctx.LineTo(p1, false, false); 451 | } 452 | 453 | public bool UpdateGeometry(double X, double Y, Point mousePos, double zoomFactor, bool bForceUpdate, Int64 timeStepMS) 454 | { 455 | bool bUpdatedGeometry = false; 456 | 457 | if (UpdateIntenalState(mousePos) || bForceUpdate) 458 | { 459 | bUpdatedGeometry = true; 460 | 461 | if (_enabled && _samples.Count > 0) 462 | { 463 | CalculateGraphPoints(GraphMode.AverageValues, X, Y, zoomFactor, timeStepMS); 464 | 465 | if (_points.Count >= 2) 466 | { 467 | // Clear old geometry 468 | _geometry.Clear(); 469 | 470 | _selectedGraphPoint = null; 471 | 472 | using (StreamGeometryContext ctx = _geometry.Open()) 473 | { 474 | for (int i = 0; i + 1 < _points.Count; ++i) 475 | { 476 | GraphPoint P1 = _points[i]; 477 | GraphPoint P2 = _points[i + 1]; 478 | if (IsPointVisible(P1._coordinates) || IsPointVisible(P2._coordinates)) 479 | { 480 | GraphPoint selectedGraphPoint = IsMousePosWithinSegment(mousePos, P1, P2); 481 | 482 | if (selectedGraphPoint != null && SystemPerformanceGraphsCanvas._hasSelectedGraphPoint == false) 483 | { 484 | _selectedGraphPoint = selectedGraphPoint; 485 | 486 | DrawFilledSquare(ctx, _selectedGraphPoint._coordinates, 10); 487 | 488 | SystemPerformanceGraphsCanvas._hasSelectedGraphPoint = true; 489 | } 490 | 491 | ctx.BeginFigure(P1._coordinates, true /* is filled */, false /* is closed */); 492 | 493 | ctx.LineTo(P2._coordinates, true /* is stroked */, false /* is smooth join */); 494 | } 495 | } 496 | } 497 | 498 | 499 | if (_selectedGraphPoint != null) 500 | { 501 | using (StreamGeometryContext ctx = _selectionLinesGeometry.Open()) 502 | { 503 | ctx.BeginFigure(new Point(SystemPerformanceGraphsCanvas._savedHorizontalViewport.X, _selectedGraphPoint._coordinates.Y), false /* is filled */, false /* is closed */); 504 | 505 | ctx.LineTo(new Point(_selectedGraphPoint._coordinates.X, _selectedGraphPoint._coordinates.Y), true/* is stroked */, false /* is smooth join */); 506 | 507 | ctx.LineTo(new Point(_selectedGraphPoint._coordinates.X, SystemPerformanceGraphsCanvas.cSystemGraphsHeight), true /* is stroked */, false /* is smooth join */); 508 | } 509 | } 510 | else 511 | { 512 | _selectionLinesGeometry.Clear(); 513 | } 514 | } 515 | } 516 | else 517 | { 518 | // Clear old geometry 519 | _geometry.Clear(); 520 | } 521 | } 522 | 523 | return bUpdatedGeometry; 524 | } 525 | 526 | 527 | private GraphPoint IsMousePosWithinSegment(Point mousePos, GraphPoint p1, GraphPoint p2) 528 | { 529 | GraphPoint result = null; 530 | 531 | if (mousePos.X >= p1._coordinates.X && mousePos.X <= p2._coordinates.X) 532 | { 533 | double aCoefCoords = (p1._coordinates.Y - p2._coordinates.Y) / (p1._coordinates.X - p2._coordinates.X); 534 | double bCoefCoords = p2._coordinates.Y - (aCoefCoords * p2._coordinates.X); 535 | 536 | double expectedY = aCoefCoords * mousePos.X + bCoefCoords; 537 | 538 | 539 | double fError = Math.Abs(expectedY - mousePos.Y); 540 | 541 | const double cCurveSelectionTolerance = 10.0f; 542 | 543 | if (fError <= cCurveSelectionTolerance) 544 | { 545 | double aCoefValue = (p2._value - p1._value) / (p2._coordinates.X - p1._coordinates.X); 546 | 547 | double value = aCoefValue * (mousePos.X - p1._coordinates.X) + p1._value; 548 | 549 | result = new GraphPoint(new Point(mousePos.X, expectedY), (float)value); 550 | 551 | //Console.WriteLine("Selected Curve ({0} - Error({1:00} pixels), time range: {2}s - {3}s, value: {4}{5}", _description, fError,p1._coordinates.X / FASTBuildMonitorControl.pix_per_second, p2._coordinates.X / FASTBuildMonitorControl.pix_per_second, value, _unitTag); 552 | } 553 | } 554 | 555 | return result; 556 | } 557 | 558 | private bool IsPointVisible(Point p) 559 | { 560 | return (p.X >= SystemPerformanceGraphsCanvas._savedHorizontalViewport.X && p.X <= SystemPerformanceGraphsCanvas._savedHorizontalViewport.Y); 561 | } 562 | 563 | StreamGeometry _geometry = new StreamGeometry(); 564 | 565 | StreamGeometry _selectionLinesGeometry = new StreamGeometry(); 566 | 567 | public void OnRender(DrawingContext dc) 568 | { 569 | if (_enabled) 570 | { 571 | double thickness = _selectedGraphPoint != null ? 3.0f : 1.0f; 572 | dc.DrawGeometry(_colorBrush, new Pen(_colorBrush, thickness), _geometry); 573 | 574 | if (_selectedGraphPoint != null) 575 | { 576 | TextUtils.DrawText(dc, string.Format("{0}: {1:0.00}{2}", _description, _selectedGraphPoint._value, _unitTag), SystemPerformanceGraphsCanvas._savedHorizontalViewport.X, _selectedGraphPoint._coordinates.Y, 200, false, Brushes.Black); 577 | 578 | dc.DrawGeometry(Brushes.Gray, new Pen(Brushes.Gray, 1), _selectionLinesGeometry); 579 | } 580 | } 581 | } 582 | } 583 | 584 | 585 | public class NetworkPerformanceCounter : BasicPerformanceCounter 586 | { 587 | public PerformanceCounter[] _counters; 588 | 589 | 590 | public NetworkPerformanceCounter(PerformanceCounterType type, bool bEnabled) : base(type, bEnabled) 591 | { 592 | } 593 | 594 | public override void Initialize(System.Diagnostics.Process targetProcess, string description = "", string unitTag = "") 595 | { 596 | PerformanceCounterCategory performanceNetCounterCategory = new PerformanceCounterCategory("Network Interface"); 597 | string[] interfaces = null; 598 | 599 | interfaces = performanceNetCounterCategory.GetInstanceNames(); 600 | 601 | int length = interfaces.Length; 602 | 603 | if (length > 0) 604 | { 605 | _counters = new PerformanceCounter[length]; 606 | 607 | for (int i = 0; i < length; i++) 608 | { 609 | //Console.WriteLine("Name netInterface: {0}", performanceNetCounterCategory.GetInstanceNames()[i]); 610 | } 611 | 612 | _valueDivider = 1024.0f * 1024.0f; 613 | 614 | switch (_type) 615 | { 616 | case PerformanceCounterType.NET_Received: 617 | 618 | _description = "Network Traffic Received"; 619 | _unitTag = "MB/s"; 620 | 621 | for (int i = 0; i < length; i++) 622 | { 623 | _counters[i] = new PerformanceCounter("Network Interface", "Bytes Received/sec", interfaces[i]); 624 | } 625 | 626 | _bInitialized = true; 627 | break; 628 | case PerformanceCounterType.NET_Sent: 629 | 630 | _description = "Network Traffic Sent"; 631 | _unitTag = "MB/s"; 632 | 633 | for (int i = 0; i < length; i++) 634 | { 635 | _counters[i] = new PerformanceCounter("Network Interface", "Bytes Sent/sec", interfaces[i]); 636 | } 637 | 638 | _bInitialized = true; 639 | break; 640 | default: 641 | Console.WriteLine("NetworkPerformanceCounter was not able to handle PerformanceCounterType: " + (int)_type); 642 | break; 643 | } 644 | } 645 | 646 | InitializeTreeViewItem(); 647 | } 648 | 649 | public override bool CaptureNewSample() 650 | { 651 | bool bSuccess = false; 652 | 653 | if (_bInitialized) 654 | { 655 | Debug.Assert(_counters != null); 656 | 657 | float newValue = 0.0f; 658 | 659 | foreach (var counter in _counters) 660 | { 661 | newValue += (float)(Math.Round((double)counter.NextValue(), 1)); 662 | } 663 | 664 | newValue = (newValue / _valueDivider) / (float)_counters.Length; 665 | 666 | Sample newSample = new Sample(FASTBuildMonitorControl.GetCurrentBuildTimeMS(), newValue); 667 | 668 | _samples.Add(newSample); 669 | 670 | //Console.WriteLine("{0}: (time: {1} - value: {2} {3}", _description, newSample._time, newSample._value, _unitTag); 671 | 672 | UpdateMaxValue(newValue); 673 | 674 | bSuccess = true; 675 | } 676 | 677 | return bSuccess; 678 | } 679 | } 680 | 681 | // attributes 682 | public List _counters = new List(); 683 | 684 | public PerformanceCountersGroupsType _groupType = PerformanceCountersGroupsType.Custom; 685 | 686 | public string _groupName; 687 | 688 | public TreeViewItem _treeViewItem; 689 | 690 | public CheckBox _checkBox; 691 | 692 | private BasicPerformanceCounter CreatePerformanceCounter(PerformanceCounterType type) 693 | { 694 | BasicPerformanceCounter counter = null; 695 | 696 | switch (type) 697 | { 698 | case PerformanceCounterType.CPU_Time: 699 | case PerformanceCounterType.RAM_Used: 700 | case PerformanceCounterType.DISK_Read: 701 | case PerformanceCounterType.DISK_Write: 702 | case PerformanceCounterType.Custom: 703 | counter = new BasicPerformanceCounter(type, _enabled); 704 | break; 705 | case PerformanceCounterType.NET_Received: 706 | case PerformanceCounterType.NET_Sent: 707 | counter = new NetworkPerformanceCounter(type, _enabled); 708 | break; 709 | } 710 | 711 | Debug.Assert(counter != null); 712 | 713 | _counters.Add(counter); 714 | 715 | return counter; 716 | } 717 | 718 | public PerformanceCountersGroup(string groupName, bool bEnabled, TreeView parentTreeView, PerformanceCountersGroupsType groupType, PerformanceCounterType[] counterTypes, int targetProcessID) 719 | { 720 | Debug.Assert(!(groupType == PerformanceCountersGroupsType.Custom && counterTypes != null), "Pre-defined PerformanceCounterTypes cannot be used with a custom PerformanceCountersGroupsType"); 721 | 722 | _groupType = groupType; 723 | 724 | _groupName = groupName; 725 | 726 | _enabled = bEnabled; 727 | 728 | System.Diagnostics.Process targetProcess = null; 729 | 730 | bool bCreateGroup = true; 731 | 732 | // first find our target process 733 | if (targetProcessID != 0) 734 | { 735 | System.Diagnostics.Process[] processlist = System.Diagnostics.Process.GetProcesses(); 736 | foreach (System.Diagnostics.Process proc in processlist) 737 | { 738 | if (proc.Id == targetProcessID) 739 | { 740 | targetProcess = proc; 741 | break; 742 | } 743 | } 744 | 745 | if (targetProcess != null) 746 | { 747 | _groupName += string.Format("({0}.exe)", targetProcess.ProcessName); 748 | } 749 | else 750 | { 751 | bCreateGroup = false; 752 | 753 | _enabled = false; 754 | } 755 | } 756 | 757 | if (bCreateGroup) 758 | { 759 | _treeViewItem = new TreeViewItem(); 760 | 761 | StackPanel stackPanel = new StackPanel(); 762 | 763 | _treeViewItem.Header = stackPanel; 764 | 765 | stackPanel.Orientation = Orientation.Horizontal; 766 | 767 | _checkBox = new CheckBox(); 768 | 769 | _checkBox.IsChecked = _enabled = bEnabled; 770 | 771 | stackPanel.Children.Add(_checkBox); 772 | 773 | TextBlock textBlock = new TextBlock() { Text = _groupName }; 774 | 775 | stackPanel.Children.Add(textBlock); 776 | 777 | if (counterTypes != null) 778 | { 779 | for (int i = 0; i < counterTypes.Length; ++i) 780 | { 781 | BasicPerformanceCounter newCounter = CreatePerformanceCounter(counterTypes[i]); 782 | 783 | newCounter.Initialize(targetProcess); 784 | 785 | _treeViewItem.Items.Add(newCounter._treeViewItem); 786 | } 787 | } 788 | 789 | parentTreeView.Items.Add(_treeViewItem); 790 | 791 | _initialized = true; 792 | } 793 | } 794 | 795 | public bool CaptureNewSample() 796 | { 797 | bool bSuccess = false; 798 | 799 | for (int i = 0; i < _counters.Count; ++i) 800 | { 801 | bSuccess = _counters[i].CaptureNewSample(); 802 | 803 | if (!bSuccess) 804 | { 805 | break; 806 | } 807 | } 808 | 809 | return bSuccess; 810 | } 811 | 812 | 813 | public bool _enabled = false; 814 | 815 | public bool _initialized = false; 816 | 817 | public bool UpdateGeometry(double X, double Y, Point mousePos, double zoomFactor, bool bForceUpdate, Int64 timeStepMS) 818 | { 819 | bool bUpdatedGeometry = false; 820 | 821 | if (_initialized) 822 | { 823 | // first check if we have been enabled/disabled since the last frame 824 | bUpdatedGeometry = (_enabled != (bool)_checkBox.IsChecked); 825 | 826 | // reconcile our enabled state 827 | _enabled = (bool)_checkBox.IsChecked; 828 | 829 | if (_enabled) 830 | { 831 | foreach (var counter in _counters) 832 | { 833 | bUpdatedGeometry |= counter.UpdateGeometry(X, Y, mousePos, zoomFactor, bForceUpdate, timeStepMS); 834 | } 835 | } 836 | } 837 | 838 | return bUpdatedGeometry; 839 | } 840 | 841 | public void OnRender(DrawingContext dc) 842 | { 843 | if (_initialized && _enabled) 844 | { 845 | foreach (var counter in _counters) 846 | { 847 | counter.OnRender(dc); 848 | } 849 | } 850 | } 851 | 852 | public bool HandleLogEvent(Int64 eventTimeMS, string counterName, string counterUnitTag, float value) 853 | { 854 | bool bSuccess = true; 855 | 856 | BasicPerformanceCounter perfCounter = null; 857 | 858 | foreach( var counter in _counters) 859 | { 860 | if (counter._description == counterName) 861 | { 862 | perfCounter = counter; 863 | break; 864 | } 865 | } 866 | 867 | if (perfCounter == null) 868 | { 869 | perfCounter = CreatePerformanceCounter(PerformanceCounterType.Custom); 870 | 871 | perfCounter.Initialize(null, counterName, counterUnitTag); 872 | 873 | _treeViewItem.Items.Add(perfCounter._treeViewItem); 874 | } 875 | 876 | perfCounter.HandleLogEvent(eventTimeMS, value); 877 | 878 | return bSuccess; 879 | } 880 | } 881 | // Performance Groups 882 | public enum PerformanceCountersGroupsType 883 | { 884 | System = 0, // global counters for the local system (live group) 885 | TargetProcess, // counters for a specific targeted process (live group) 886 | LiveGroups, // This defines the number of live groups, all groups after this one will not be considered as live groups thus they won't be able to capture New Samples 887 | Custom, 888 | Max 889 | } 890 | 891 | public List _performanceCountersGroups = new List(); 892 | 893 | public bool _bSessionOpen = false; 894 | 895 | public bool _liveSession = false; 896 | 897 | 898 | public PerformanceCountersGroup CreateNewGroup(string groupName, bool bEnabled, TreeView parentTreeView, PerformanceCountersGroupsType groupType = PerformanceCountersGroupsType.Custom, PerformanceCountersGroup.PerformanceCounterType[] counterTypes = null, int targetProcessID = 0) 899 | { 900 | Debug.Assert(!(groupType == PerformanceCountersGroupsType.Custom && counterTypes != null), "Pre-defined PerformanceCounterTypes cannot be used with a custom PerformanceCountersGroupsType"); 901 | 902 | PerformanceCountersGroup newGroup = new PerformanceCountersGroup(groupName, bEnabled, parentTreeView, groupType, counterTypes, targetProcessID); 903 | 904 | _performanceCountersGroups.Add(newGroup); 905 | 906 | return newGroup; 907 | } 908 | 909 | public void OpenSession(bool bLiveSession, int targetProcessID) 910 | { 911 | // Reset our color selection counter; 912 | PerformanceCountersGroup.BasicPerformanceCounter._sColorsIndex = 0; 913 | 914 | TreeView parentTreeView = FASTBuildMonitorControl._StaticWindow.graphsSelectionTreeView; 915 | 916 | parentTreeView.Items.Clear(); 917 | 918 | // Create the live session groups 919 | { 920 | CreateNewGroup("System", true, parentTreeView, PerformanceCountersGroupsType.System, 921 | new PerformanceCountersGroup.PerformanceCounterType[] { 922 | PerformanceCountersGroup.PerformanceCounterType.CPU_Time, 923 | PerformanceCountersGroup.PerformanceCounterType.RAM_Used, 924 | PerformanceCountersGroup.PerformanceCounterType.DISK_Read, 925 | PerformanceCountersGroup.PerformanceCounterType.DISK_Write, 926 | PerformanceCountersGroup.PerformanceCounterType.NET_Received, 927 | PerformanceCountersGroup.PerformanceCounterType.NET_Sent}); 928 | 929 | if (targetProcessID != 0) 930 | { 931 | CreateNewGroup("Process", false, parentTreeView, PerformanceCountersGroupsType.TargetProcess, 932 | new PerformanceCountersGroup.PerformanceCounterType[] { 933 | PerformanceCountersGroup.PerformanceCounterType.CPU_Time, 934 | PerformanceCountersGroup.PerformanceCounterType.RAM_Used, 935 | PerformanceCountersGroup.PerformanceCounterType.DISK_Read, 936 | PerformanceCountersGroup.PerformanceCounterType.DISK_Write}, 937 | targetProcessID); 938 | } 939 | } 940 | 941 | _liveSession = bLiveSession; 942 | 943 | _bSessionOpen = true; 944 | } 945 | 946 | 947 | public void CloseSession() 948 | { 949 | _lastSampleTimeMS = 0; 950 | 951 | _bSessionOpen = false; 952 | 953 | _liveSession = false; 954 | } 955 | 956 | public static Int64 _lastSampleTimeMS = 0; 957 | private const Int64 cSamplingPeriodMS = 1 * 1000; 958 | 959 | public void CaptureNewSamples() 960 | { 961 | if (_liveSession) 962 | { 963 | var currentTime = FASTBuildMonitorControl.GetCurrentSystemTimeMS(); 964 | 965 | if ((currentTime - _lastSampleTimeMS) > cSamplingPeriodMS) 966 | { 967 | foreach (var group in _performanceCountersGroups) 968 | { 969 | // Only capture samples for live groups. Other groups will have samples sent to them from the log events 970 | if (group._groupType < PerformanceCountersGroupsType.LiveGroups) 971 | { 972 | group.CaptureNewSample(); 973 | } 974 | } 975 | 976 | _lastSampleTimeMS = currentTime; 977 | } 978 | } 979 | } 980 | 981 | 982 | public bool _visible = false; 983 | 984 | public const int cSystemGraphsHeight = 150; 985 | 986 | 987 | public void SetVisibility(bool visible) 988 | { 989 | TreeView parentTreeView = FASTBuildMonitorControl._StaticWindow.graphsSelectionTreeView; 990 | 991 | if (visible) 992 | { 993 | parentTreeView.Visibility = Visibility = Visibility.Visible; 994 | this.Height = _parentCanvas.Height = cSystemGraphsHeight; 995 | this.Width = _parentCanvas.Width; 996 | } 997 | else 998 | { 999 | parentTreeView.Visibility = Visibility = Visibility.Collapsed; 1000 | this.Height = _parentCanvas.Height = 0.0f; 1001 | this.Width = _parentCanvas.Width = 0.0f; 1002 | } 1003 | 1004 | _visible = visible; 1005 | } 1006 | 1007 | 1008 | protected override void OnRender(DrawingContext dc) 1009 | { 1010 | foreach (var group in _performanceCountersGroups) 1011 | { 1012 | group.OnRender(dc); 1013 | } 1014 | } 1015 | 1016 | private bool UpdateGeometry(double X, double Y, Point mousePos, double zoomFactor, bool bForceUpdate) 1017 | { 1018 | bool bUpdatedGeometry = false; 1019 | 1020 | foreach (var group in _performanceCountersGroups) 1021 | { 1022 | bUpdatedGeometry |= group.UpdateGeometry(X, Y, mousePos, zoomFactor, bForceUpdate, _smallTimeUnit * 1000); 1023 | } 1024 | 1025 | return bUpdatedGeometry; 1026 | } 1027 | 1028 | // Returns if we must force a geometry update 1029 | bool UpdateTimeUnits() 1030 | { 1031 | bool bNeedsToUpdateGeometry = false; 1032 | 1033 | const double pixChunkSize = 100.0f; 1034 | 1035 | double timePerChunk = pixChunkSize / (FASTBuildMonitorControl._zoomFactor * FASTBuildMonitorControl.pix_per_second); 1036 | 1037 | int newBigTimeUnit = 0; 1038 | int newSmallTimeUnit = 0; 1039 | 1040 | if (timePerChunk > 30.0f) 1041 | { 1042 | newBigTimeUnit = 60; 1043 | newSmallTimeUnit = 10; 1044 | } 1045 | else if (timePerChunk > 10.0f) 1046 | { 1047 | newBigTimeUnit = 30; 1048 | newSmallTimeUnit = 6; 1049 | } 1050 | else if (timePerChunk > 5.0f) 1051 | { 1052 | newBigTimeUnit = 10; 1053 | newSmallTimeUnit = 2; 1054 | } 1055 | else 1056 | { 1057 | newBigTimeUnit = 5; 1058 | newSmallTimeUnit = 1; 1059 | } 1060 | 1061 | Point newHorizontalViewPort = new Point(FASTBuildMonitorControl._StaticWindow.EventsScrollViewer.HorizontalOffset, FASTBuildMonitorControl._StaticWindow.EventsScrollViewer.HorizontalOffset + FASTBuildMonitorControl._StaticWindow.EventsScrollViewer.ViewportWidth); 1062 | 1063 | if (FASTBuildMonitorControl._zoomFactor != _savedZoomFactor || FASTBuildMonitorControl.GetCurrentBuildTimeMS() != _savedBuildTime || newHorizontalViewPort != _savedHorizontalViewport) 1064 | { 1065 | _bigTimeUnit = newBigTimeUnit; 1066 | _smallTimeUnit = newSmallTimeUnit; 1067 | 1068 | _savedZoomFactor = FASTBuildMonitorControl._zoomFactor; 1069 | 1070 | _savedBuildTime = FASTBuildMonitorControl.GetCurrentBuildTimeMS(); 1071 | 1072 | _savedHorizontalViewport = newHorizontalViewPort; 1073 | 1074 | bNeedsToUpdateGeometry = true; 1075 | } 1076 | 1077 | return bNeedsToUpdateGeometry; 1078 | } 1079 | 1080 | public void RenderUpdate(double X, double Y, double zoomFactor) 1081 | { 1082 | if (_bSessionOpen) 1083 | { 1084 | CaptureNewSamples(); 1085 | } 1086 | 1087 | if (_visible) 1088 | { 1089 | Width = _parentCanvas.Width; 1090 | Height = _parentCanvas.Height; 1091 | 1092 | _hasSelectedGraphPoint = false; 1093 | 1094 | // Find out if the zoom has changed and if we need to force an update 1095 | bool bForceGeometryUpdate = UpdateTimeUnits(); 1096 | 1097 | Point mousePos = Mouse.GetPosition(this); 1098 | 1099 | bool bNeedToRedraw = UpdateGeometry(X, Y, mousePos, zoomFactor, bForceGeometryUpdate); 1100 | 1101 | if (bNeedToRedraw) 1102 | { 1103 | InvalidateVisual(); 1104 | } 1105 | } 1106 | } 1107 | 1108 | public bool HandleLogEvent(Int64 eventTimeMS, string groupName, string counterName, string counterUnitTag, float value) 1109 | { 1110 | PerformanceCountersGroup perfGroup = null; 1111 | 1112 | foreach( var g in _performanceCountersGroups) 1113 | { 1114 | if (g._groupName == groupName) 1115 | { 1116 | perfGroup = g; 1117 | break; 1118 | } 1119 | } 1120 | 1121 | if (perfGroup == null) 1122 | { 1123 | TreeView parentTreeView = FASTBuildMonitorControl._StaticWindow.graphsSelectionTreeView; 1124 | 1125 | perfGroup = CreateNewGroup(groupName, true, parentTreeView); 1126 | } 1127 | 1128 | return perfGroup.HandleLogEvent(eventTimeMS, counterName, counterUnitTag, value); 1129 | } 1130 | 1131 | 1132 | int _bigTimeUnit = 0; 1133 | int _smallTimeUnit = 0; 1134 | 1135 | double _savedZoomFactor = 0.0f; 1136 | double _savedBuildTime = 0.0f; 1137 | 1138 | static public Point _savedHorizontalViewport = new Point(); 1139 | 1140 | static public bool _hasSelectedGraphPoint = false; 1141 | 1142 | Canvas _parentCanvas = null; 1143 | } 1144 | } 1145 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Code/TextUtils.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright 2017 Yassine Riahi and Liam Flookes. 3 | // Provided under a MIT License, see license file on github. 4 | //------------------------------------------------------------------------------ 5 | 6 | using System; 7 | using System.Windows; 8 | using System.Windows.Media; 9 | 10 | namespace FASTBuildMonitor 11 | { 12 | class TextUtils 13 | { 14 | // Text rendering stuff 15 | private static GlyphTypeface _glyphTypeface = null; 16 | 17 | private const double _cFontSize = 12.0f; 18 | 19 | 20 | public static bool StaticInitialize() 21 | { 22 | bool bSuccess = true; 23 | 24 | // Font text 25 | if (_glyphTypeface == null) 26 | { 27 | Typeface typeface = new Typeface(new FontFamily("Segoe UI"), 28 | FontStyles.Normal, 29 | FontWeights.Normal, 30 | FontStretches.Normal); 31 | 32 | if (!typeface.TryGetGlyphTypeface(out _glyphTypeface)) 33 | { 34 | bSuccess = false; 35 | throw new InvalidOperationException("No glyphtypeface found"); 36 | } 37 | } 38 | 39 | return bSuccess; 40 | } 41 | 42 | public static Point ComputeTextSize(string text) 43 | { 44 | Point result = new Point(); 45 | 46 | for (int charIndex = 0; charIndex < text.Length; charIndex++) 47 | { 48 | ushort glyphIndex = _glyphTypeface.CharacterToGlyphMap[text[charIndex]]; 49 | 50 | double width = _glyphTypeface.AdvanceWidths[glyphIndex] * _cFontSize; 51 | 52 | result.Y = Math.Max(_glyphTypeface.AdvanceHeights[glyphIndex] * _cFontSize, result.Y); 53 | 54 | result.X += width; 55 | } 56 | 57 | return result; 58 | } 59 | 60 | public static void DrawText(DrawingContext dc, string text, double x, double y, double maxWidth, bool bEnableDotDotDot, SolidColorBrush colorBrush) 61 | { 62 | ushort[] glyphIndexes = null; 63 | double[] advanceWidths = null; 64 | 65 | ushort[] tempGlyphIndexes = new ushort[text.Length]; 66 | double[] tempAdvanceWidths = new double[text.Length]; 67 | 68 | double totalTextWidth = 0; 69 | double maxHeight = 0.0f; 70 | 71 | bool needDoTDotDot = false; 72 | double desiredTextWidth = maxWidth; 73 | int charIndex = 0; 74 | 75 | // Build the text info and measure the final text width 76 | for (; charIndex < text.Length; charIndex++) 77 | { 78 | ushort glyphIndex = _glyphTypeface.CharacterToGlyphMap[text[charIndex]]; 79 | tempGlyphIndexes[charIndex] = glyphIndex; 80 | 81 | double width = _glyphTypeface.AdvanceWidths[glyphIndex] * _cFontSize; 82 | tempAdvanceWidths[charIndex] = width; 83 | 84 | maxHeight = Math.Max(_glyphTypeface.AdvanceHeights[glyphIndex] * _cFontSize, maxHeight); 85 | 86 | totalTextWidth += width; 87 | 88 | if (totalTextWidth > desiredTextWidth) 89 | { 90 | //we need to clip the text since it doesn't fit the allowed width 91 | //do a second measurement pass 92 | needDoTDotDot = true; 93 | break; 94 | } 95 | } 96 | 97 | if (bEnableDotDotDot && needDoTDotDot) 98 | { 99 | ushort suffixGlyphIndex = _glyphTypeface.CharacterToGlyphMap['.']; 100 | double suffixWidth = _glyphTypeface.AdvanceWidths[suffixGlyphIndex] * _cFontSize; 101 | 102 | desiredTextWidth -= suffixWidth * 3; 103 | 104 | for (; charIndex > 0; charIndex--) 105 | { 106 | double removedCharacterWidth = tempAdvanceWidths[charIndex]; 107 | 108 | totalTextWidth -= removedCharacterWidth; 109 | 110 | if (totalTextWidth <= desiredTextWidth) 111 | { 112 | charIndex--; 113 | break; 114 | } 115 | } 116 | 117 | int finalNumCharacters = charIndex + 1 + 3; 118 | 119 | glyphIndexes = new ushort[finalNumCharacters]; 120 | advanceWidths = new double[finalNumCharacters]; 121 | 122 | Array.Copy(tempGlyphIndexes, glyphIndexes, charIndex + 1); 123 | Array.Copy(tempAdvanceWidths, advanceWidths, charIndex + 1); 124 | 125 | for (int i = charIndex + 1; i < finalNumCharacters; ++i) 126 | { 127 | glyphIndexes[i] = suffixGlyphIndex; 128 | advanceWidths[i] = suffixWidth; 129 | } 130 | } 131 | else 132 | { 133 | glyphIndexes = tempGlyphIndexes; 134 | advanceWidths = tempAdvanceWidths; 135 | } 136 | 137 | double roundedX = Math.Round(x); 138 | double roundedY = Math.Round(y + maxHeight); 139 | 140 | GlyphRun gr = new GlyphRun( 141 | _glyphTypeface, 142 | 0, // Bi-directional nesting level 143 | false, // isSideways 144 | _cFontSize, // pt size 145 | glyphIndexes, // glyphIndices 146 | new Point(roundedX, roundedY), // baselineOrigin 147 | advanceWidths, // advanceWidths 148 | null, // glyphOffsets 149 | null, // characters 150 | null, // deviceFontName 151 | null, // clusterMap 152 | null, // caretStops 153 | null); // xmlLanguage 154 | 155 | dc.DrawGlyphRun(colorBrush, gr); 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Code/Timebar.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright 2017 Yassine Riahi and Liam Flookes. 3 | // Provided under a MIT License, see license file on github. 4 | //------------------------------------------------------------------------------ 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | using System.Windows.Media; 11 | 12 | namespace FASTBuildMonitor 13 | { 14 | class TimeBar : Canvas 15 | { 16 | public TimeBar(Canvas parentCanvas, ResourceDictionary theme) 17 | { 18 | _parentCanvas = parentCanvas; 19 | _theme = theme; 20 | 21 | this.Width = _parentCanvas.Width; 22 | this.Height = _parentCanvas.Height; 23 | 24 | _parentCanvas.Children.Add(this); 25 | } 26 | 27 | protected override void OnRender(DrawingContext dc) 28 | { 29 | var color = _theme["ForegroundColor"] as SolidColorBrush; 30 | dc.DrawGeometry(color, new Pen(color, 1), _geometry); 31 | 32 | _textTags.ForEach(tag => TextUtils.DrawText(dc, tag._text, tag._x, tag._y, 100, false, color)); 33 | } 34 | 35 | void UpdateGeometry(double X, double Y, double zoomFactor) 36 | { 37 | // Clear old geometry 38 | _geometry.Clear(); 39 | 40 | _textTags.Clear(); 41 | 42 | // Open a StreamGeometryContext that can be used to describe this StreamGeometry 43 | // object's contents. 44 | using (StreamGeometryContext ctx = _geometry.Open()) 45 | { 46 | Int64 totalTimeMS = 0; 47 | 48 | Int64 numSteps = FASTBuildMonitorControl.GetCurrentBuildTimeMS() / (_bigTimeUnit * 1000); 49 | Int64 remainder = FASTBuildMonitorControl.GetCurrentBuildTimeMS() % (_bigTimeUnit * 1000); 50 | 51 | numSteps += remainder > 0 ? 2 : 1; 52 | 53 | Int64 timeLimitMS = numSteps * _bigTimeUnit * 1000; 54 | 55 | while (totalTimeMS <= timeLimitMS) 56 | { 57 | bool bDrawBigMarker = totalTimeMS % (_bigTimeUnit * 1000) == 0; 58 | 59 | double x = X + zoomFactor * FASTBuildMonitorControl.pix_per_second * totalTimeMS / 1000.0f; 60 | 61 | // TODO: activate culling optimization 62 | //if (x >= _savedTimebarViewPort.X && x <= _savedTimebarViewPort.Y) 63 | { 64 | double height = bDrawBigMarker ? 5.0f : 2.0f; 65 | 66 | ctx.BeginFigure(new Point(x, Y), true /* is filled */, false /* is closed */); 67 | 68 | // Draw a line to the next specified point. 69 | ctx.LineTo(new Point(x, Y + height), true /* is stroked */, false /* is smooth join */); 70 | 71 | if (bDrawBigMarker) 72 | { 73 | string formattedText = FASTBuildMonitorControl.GetTimeFormattedString(totalTimeMS); 74 | 75 | Point textSize = TextUtils.ComputeTextSize(formattedText); 76 | 77 | double horizontalCorrection = textSize.X / 2.0f; 78 | 79 | TextTag newTag = new TextTag(formattedText, x - horizontalCorrection, Y + height + 2); 80 | 81 | _textTags.Add(newTag); 82 | } 83 | } 84 | 85 | totalTimeMS += _smallTimeUnit * 1000; 86 | } 87 | } 88 | } 89 | 90 | bool UpdateTimeUnits() 91 | { 92 | bool bNeedsToUpdateGeometry = false; 93 | 94 | const double pixChunkSize = 100.0f; 95 | 96 | double timePerChunk = pixChunkSize / (FASTBuildMonitorControl._zoomFactor * FASTBuildMonitorControl.pix_per_second); 97 | 98 | int newBigTimeUnit = 0; 99 | int newSmallTimeUnit = 0; 100 | 101 | if (timePerChunk > 30.0f) 102 | { 103 | newBigTimeUnit = 60; 104 | newSmallTimeUnit = 10; 105 | } 106 | else if (timePerChunk > 10.0f) 107 | { 108 | newBigTimeUnit = 30; 109 | newSmallTimeUnit = 6; 110 | } 111 | else if (timePerChunk > 5.0f) 112 | { 113 | newBigTimeUnit = 10; 114 | newSmallTimeUnit = 2; 115 | } 116 | else 117 | { 118 | newBigTimeUnit = 5; 119 | newSmallTimeUnit = 1; 120 | } 121 | 122 | Point newTimebarViewPort = new Point(FASTBuildMonitorControl._StaticWindow.EventsScrollViewer.HorizontalOffset, FASTBuildMonitorControl._StaticWindow.EventsScrollViewer.HorizontalOffset + FASTBuildMonitorControl._StaticWindow.EventsScrollViewer.ViewportWidth); 123 | 124 | if (FASTBuildMonitorControl._zoomFactor != _savedZoomFactor || FASTBuildMonitorControl.GetCurrentBuildTimeMS() != _savedBuildTime || newTimebarViewPort != _savedTimebarViewPort) 125 | { 126 | _bigTimeUnit = newBigTimeUnit; 127 | _smallTimeUnit = newSmallTimeUnit; 128 | 129 | _savedZoomFactor = FASTBuildMonitorControl._zoomFactor; 130 | 131 | _savedBuildTime = FASTBuildMonitorControl.GetCurrentBuildTimeMS(); 132 | 133 | _savedTimebarViewPort = newTimebarViewPort; 134 | 135 | this.InvalidateVisual(); 136 | 137 | bNeedsToUpdateGeometry = true; 138 | } 139 | 140 | return bNeedsToUpdateGeometry; 141 | } 142 | 143 | public void RenderUpdate(double X, double Y, double zoomFactor) 144 | { 145 | if (UpdateTimeUnits()) 146 | { 147 | this.InvalidateVisual(); 148 | 149 | UpdateGeometry(X, Y, zoomFactor); 150 | } 151 | } 152 | 153 | public void UpdateTheme(ResourceDictionary theme) 154 | { 155 | _theme = theme; 156 | InvalidateVisual(); 157 | } 158 | 159 | private class TextTag 160 | { 161 | public TextTag(string text, double x, double y) 162 | { 163 | _text = text; 164 | _x = x; 165 | _y = y; 166 | } 167 | 168 | public string _text; 169 | public double _x; 170 | public double _y; 171 | } 172 | 173 | List _textTags = new List(); 174 | 175 | StreamGeometry _geometry = new StreamGeometry(); 176 | 177 | int _bigTimeUnit = 0; 178 | int _smallTimeUnit = 0; 179 | 180 | double _savedZoomFactor = 0.0f; 181 | double _savedBuildTime = 0.0f; 182 | Point _savedTimebarViewPort = new Point(); 183 | 184 | Canvas _parentCanvas = null; 185 | ResourceDictionary _theme = null; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/FASTBuildMonitor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E} 8 | Library 9 | Properties 10 | FASTBuildMonitor 11 | FASTBuildMonitor 12 | v4.6.1 13 | 512 14 | true 15 | 16 | Debug;Release;Debug Legacy;Release Legacy 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | true 37 | 38 | 39 | Key.snk 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | FASTBuildMonitorControl.xaml 55 | 56 | 57 | 58 | 59 | True 60 | True 61 | Images.resx 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | Designer 94 | MSBuild:Compile 95 | 96 | 97 | Designer 98 | MSBuild:Compile 99 | 100 | 101 | Designer 102 | MSBuild:Compile 103 | 104 | 105 | 106 | 107 | ResXFileCodeGenerator 108 | Images.Designer.cs 109 | Designer 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Key.snk -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("FASTBuildMonitor")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("FASTBuildMonitor")] 12 | [assembly: AssemblyCopyright("Copyright © 2020")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("3aa63c05-2341-4e72-adbc-22c33341ec6e")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/BuildStatusErrors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/BuildStatusErrors.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/BuildStatusOK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/BuildStatusOK.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/BuildStatusWarnings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/BuildStatusWarnings.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Failed.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/HeartBeat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/HeartBeat.gif -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Images.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace FASTBuildMonitor.Resources { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Images { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Images() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FASTBuildMonitor.Resources.Images", typeof(Images).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap box { 67 | get { 68 | object obj = ResourceManager.GetObject("box", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Bitmap. 75 | /// 76 | internal static System.Drawing.Bitmap BuildStatusErrors { 77 | get { 78 | object obj = ResourceManager.GetObject("BuildStatusErrors", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized resource of type System.Drawing.Bitmap. 85 | /// 86 | internal static System.Drawing.Bitmap BuildStatusOK { 87 | get { 88 | object obj = ResourceManager.GetObject("BuildStatusOK", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// Looks up a localized resource of type System.Drawing.Bitmap. 95 | /// 96 | internal static System.Drawing.Bitmap BuildStatusWarnings { 97 | get { 98 | object obj = ResourceManager.GetObject("BuildStatusWarnings", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | 103 | /// 104 | /// Looks up a localized resource of type System.Drawing.Bitmap. 105 | /// 106 | internal static System.Drawing.Bitmap Failed { 107 | get { 108 | object obj = ResourceManager.GetObject("Failed", resourceCulture); 109 | return ((System.Drawing.Bitmap)(obj)); 110 | } 111 | } 112 | 113 | /// 114 | /// Looks up a localized resource of type System.Drawing.Bitmap. 115 | /// 116 | internal static System.Drawing.Bitmap HeartBeat { 117 | get { 118 | object obj = ResourceManager.GetObject("HeartBeat", resourceCulture); 119 | return ((System.Drawing.Bitmap)(obj)); 120 | } 121 | } 122 | 123 | /// 124 | /// Looks up a localized resource of type System.Drawing.Bitmap. 125 | /// 126 | internal static System.Drawing.Bitmap LODBlock { 127 | get { 128 | object obj = ResourceManager.GetObject("LODBlock", resourceCulture); 129 | return ((System.Drawing.Bitmap)(obj)); 130 | } 131 | } 132 | 133 | /// 134 | /// Looks up a localized resource of type System.Drawing.Bitmap. 135 | /// 136 | internal static System.Drawing.Bitmap ProgressBar { 137 | get { 138 | object obj = ResourceManager.GetObject("ProgressBar", resourceCulture); 139 | return ((System.Drawing.Bitmap)(obj)); 140 | } 141 | } 142 | 143 | /// 144 | /// Looks up a localized resource of type System.Drawing.Bitmap. 145 | /// 146 | internal static System.Drawing.Bitmap race_flag { 147 | get { 148 | object obj = ResourceManager.GetObject("race_flag", resourceCulture); 149 | return ((System.Drawing.Bitmap)(obj)); 150 | } 151 | } 152 | 153 | /// 154 | /// Looks up a localized resource of type System.Drawing.Bitmap. 155 | /// 156 | internal static System.Drawing.Bitmap race_flag_lost { 157 | get { 158 | object obj = ResourceManager.GetObject("race_flag_lost", resourceCulture); 159 | return ((System.Drawing.Bitmap)(obj)); 160 | } 161 | } 162 | 163 | /// 164 | /// Looks up a localized resource of type System.Drawing.Bitmap. 165 | /// 166 | internal static System.Drawing.Bitmap race_flag_win { 167 | get { 168 | object obj = ResourceManager.GetObject("race_flag_win", resourceCulture); 169 | return ((System.Drawing.Bitmap)(obj)); 170 | } 171 | } 172 | 173 | /// 174 | /// Looks up a localized resource of type System.Drawing.Bitmap. 175 | /// 176 | internal static System.Drawing.Bitmap Running { 177 | get { 178 | object obj = ResourceManager.GetObject("Running", resourceCulture); 179 | return ((System.Drawing.Bitmap)(obj)); 180 | } 181 | } 182 | 183 | /// 184 | /// Looks up a localized resource of type System.Drawing.Bitmap. 185 | /// 186 | internal static System.Drawing.Bitmap SettingsTabIcon { 187 | get { 188 | object obj = ResourceManager.GetObject("SettingsTabIcon", resourceCulture); 189 | return ((System.Drawing.Bitmap)(obj)); 190 | } 191 | } 192 | 193 | /// 194 | /// Looks up a localized resource of type System.Drawing.Bitmap. 195 | /// 196 | internal static System.Drawing.Bitmap Spinner { 197 | get { 198 | object obj = ResourceManager.GetObject("Spinner", resourceCulture); 199 | return ((System.Drawing.Bitmap)(obj)); 200 | } 201 | } 202 | 203 | /// 204 | /// Looks up a localized resource of type System.Drawing.Bitmap. 205 | /// 206 | internal static System.Drawing.Bitmap Success_cached { 207 | get { 208 | object obj = ResourceManager.GetObject("Success_cached", resourceCulture); 209 | return ((System.Drawing.Bitmap)(obj)); 210 | } 211 | } 212 | 213 | /// 214 | /// Looks up a localized resource of type System.Drawing.Bitmap. 215 | /// 216 | internal static System.Drawing.Bitmap Success_code { 217 | get { 218 | object obj = ResourceManager.GetObject("Success_code", resourceCulture); 219 | return ((System.Drawing.Bitmap)(obj)); 220 | } 221 | } 222 | 223 | /// 224 | /// Looks up a localized resource of type System.Drawing.Bitmap. 225 | /// 226 | internal static System.Drawing.Bitmap Success_noncode { 227 | get { 228 | object obj = ResourceManager.GetObject("Success_noncode", resourceCulture); 229 | return ((System.Drawing.Bitmap)(obj)); 230 | } 231 | } 232 | 233 | /// 234 | /// Looks up a localized resource of type System.Drawing.Bitmap. 235 | /// 236 | internal static System.Drawing.Bitmap Success_preprocessed { 237 | get { 238 | object obj = ResourceManager.GetObject("Success_preprocessed", resourceCulture); 239 | return ((System.Drawing.Bitmap)(obj)); 240 | } 241 | } 242 | 243 | /// 244 | /// Looks up a localized resource of type System.Drawing.Bitmap. 245 | /// 246 | internal static System.Drawing.Bitmap TextOutputTabIcon { 247 | get { 248 | object obj = ResourceManager.GetObject("TextOutputTabIcon", resourceCulture); 249 | return ((System.Drawing.Bitmap)(obj)); 250 | } 251 | } 252 | 253 | /// 254 | /// Looks up a localized resource of type System.Drawing.Bitmap. 255 | /// 256 | internal static System.Drawing.Bitmap TimeLineTabIcon { 257 | get { 258 | object obj = ResourceManager.GetObject("TimeLineTabIcon", resourceCulture); 259 | return ((System.Drawing.Bitmap)(obj)); 260 | } 261 | } 262 | 263 | /// 264 | /// Looks up a localized resource of type System.Drawing.Bitmap. 265 | /// 266 | internal static System.Drawing.Bitmap Timeout { 267 | get { 268 | object obj = ResourceManager.GetObject("Timeout", resourceCulture); 269 | return ((System.Drawing.Bitmap)(obj)); 270 | } 271 | } 272 | 273 | /// 274 | /// Looks up a localized resource of type System.Drawing.Bitmap. 275 | /// 276 | internal static System.Drawing.Bitmap Warning { 277 | get { 278 | object obj = ResourceManager.GetObject("Warning", resourceCulture); 279 | return ((System.Drawing.Bitmap)(obj)); 280 | } 281 | } 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Images.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Images.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | box.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | BuildStatusErrors.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | BuildStatusOK.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | BuildStatusWarnings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | Failed.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | HeartBeat.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | LODBlock.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | 143 | ProgressBar.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 144 | 145 | 146 | Running.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 147 | 148 | 149 | Spinner.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 150 | 151 | 152 | Success-code.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 153 | 154 | 155 | Success-noncode.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 156 | 157 | 158 | TextOutputTabIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 159 | 160 | 161 | TimeLineTabIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 162 | 163 | 164 | Timeout.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 165 | 166 | 167 | Warning.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 168 | 169 | 170 | SettingsTabIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 171 | 172 | 173 | Success-cached.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 174 | 175 | 176 | Success-preprocessed.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 177 | 178 | 179 | race_flag.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 180 | 181 | 182 | race_flag_lost.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 183 | 184 | 185 | race_flag_win.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 186 | 187 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/LODBlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/LODBlock.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/ProgressBar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/ProgressBar.gif -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Running.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/SettingsTabIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/SettingsTabIcon.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Spinner.gif -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Success-cached.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Success-cached.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Success-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Success-code.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Success-noncode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Success-noncode.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Success-preprocessed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Success-preprocessed.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/TextOutputTabIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/TextOutputTabIcon.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Themes/DarkTheme.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | #111111 5 | #222222 6 | #333333 7 | #222222 8 | 9 | #FFC7C7C7 10 | 11 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Themes/DefaultTheme.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | #FFFFFF 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | #41020202 16 | 17 | 18 | 19 | 20 | 21 | 22 | #000000 23 | 24 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/TimeLineTabIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/TimeLineTabIcon.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Timeout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Timeout.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/Warning.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/box.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/box.gif -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/race_flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/race_flag.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/race_flag_lost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/race_flag_lost.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/race_flag_win.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitor/Resources/race_flag_win.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace FASTBuildMonitorStandalone 4 | { 5 | /// 6 | /// Interaction logic for App.xaml 7 | /// 8 | public partial class App : Application 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/FASTBuildMonitorStandalone.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3} 8 | WinExe 9 | Properties 10 | FASTBuildMonitorStandalone 11 | FASTBuildMonitorStandalone 12 | v4.6.1 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | true 17 | false 18 | publish\ 19 | true 20 | Disk 21 | false 22 | Foreground 23 | 7 24 | Days 25 | false 26 | false 27 | true 28 | 0 29 | 1.0.0.%2a 30 | false 31 | true 32 | 33 | 34 | AnyCPU 35 | true 36 | full 37 | false 38 | bin\Debug\ 39 | DEBUG;TRACE 40 | prompt 41 | 4 42 | false 43 | 44 | 45 | AnyCPU 46 | pdbonly 47 | true 48 | bin\Release\ 49 | TRACE 50 | prompt 51 | 4 52 | false 53 | 54 | 55 | Resources\green.ico 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 4.0 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | MSBuild:Compile 72 | Designer 73 | 74 | 75 | MSBuild:Compile 76 | Designer 77 | 78 | 79 | App.xaml 80 | Code 81 | 82 | 83 | MainWindow.xaml 84 | Code 85 | 86 | 87 | 88 | 89 | Code 90 | 91 | 92 | True 93 | True 94 | Resources.resx 95 | 96 | 97 | True 98 | Settings.settings 99 | True 100 | 101 | 102 | ResXFileCodeGenerator 103 | Resources.Designer.cs 104 | 105 | 106 | SettingsSingleFileGenerator 107 | Settings.Designer.cs 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | False 118 | Microsoft .NET Framework 4.5.2 %28x86 and x64%29 119 | true 120 | 121 | 122 | False 123 | .NET Framework 3.5 SP1 124 | false 125 | 126 | 127 | 128 | 129 | {3aa63c05-2341-4e72-adbc-22c33341ec6e} 130 | FASTBuildMonitor 131 | 132 | 133 | 134 | 135 | 1.0.8 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Input; 4 | 5 | namespace FASTBuildMonitorStandalone 6 | { 7 | /// 8 | /// Interaction logic for MainWindow.xaml 9 | /// 10 | public partial class MainWindow : Window 11 | { 12 | public static MainWindow Window = null; 13 | public MainWindow() 14 | { 15 | Window = this; 16 | InitializeComponent(); 17 | 18 | this.Content = new FASTBuildMonitor.FASTBuildMonitorControl( 19 | "FASTBuildMonitor Standalone", 20 | version: "?", // TODO: retrieve those from AssemblyInfo 21 | authors: "?" 22 | ); 23 | 24 | this.StateChanged += Window_StateChanged; 25 | } 26 | 27 | private void Window_StateChanged(object sender, EventArgs e) 28 | { 29 | if (this.WindowState == WindowState.Minimized) 30 | { 31 | this.ShowInTaskbar = false; 32 | } 33 | else 34 | { 35 | this.ShowInTaskbar = true; 36 | } 37 | } 38 | } 39 | 40 | /// 41 | /// This simple class is used to handle click and double click on the tray icon(this restore and minimize the app window) 42 | /// 43 | public class ClickTrayIcon : ICommand 44 | { 45 | public void Execute(object parameter) 46 | { 47 | if (MainWindow.Window.WindowState == WindowState.Minimized) 48 | MainWindow.Window.WindowState = WindowState.Normal; 49 | else 50 | MainWindow.Window.WindowState = WindowState.Minimized; 51 | } 52 | 53 | public bool CanExecute(object parameter) 54 | { 55 | return true; 56 | } 57 | 58 | public event EventHandler CanExecuteChanged 59 | { 60 | add { } 61 | remove { } 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using System.Windows; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("FASTBuildMonitorStandalone")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FASTBuildMonitorStandalone")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | //In order to begin building localizable applications, set 23 | //CultureYouAreCodingWith in your .csproj file 24 | //inside a . For example, if you are using US english 25 | //in your source files, set the to en-US. Then uncomment 26 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 27 | //the line below to match the UICulture setting in the project file. 28 | 29 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 30 | 31 | 32 | [assembly: ThemeInfo( 33 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 34 | //(used if a resource is not found in the page, 35 | // or application resource dictionaries) 36 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 37 | //(used if a resource is not found in the page, 38 | // app, or any theme specific resource dictionaries) 39 | )] 40 | 41 | 42 | // Version information for an assembly consists of the following four values: 43 | // 44 | // Major Version 45 | // Minor Version 46 | // Build Number 47 | // Revision 48 | // 49 | // You can specify all the values or you can default the Build and Revision Numbers 50 | // by using the '*' as shown below: 51 | // [assembly: AssemblyVersion("1.0.*")] 52 | [assembly: AssemblyVersion("1.0.0.0")] 53 | [assembly: AssemblyFileVersion("1.0.0.0")] 54 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace FASTBuildMonitorStandalone.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FASTBuildMonitorStandalone.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 65 | /// 66 | internal static System.Drawing.Icon green { 67 | get { 68 | object obj = ResourceManager.GetObject("green", resourceCulture); 69 | return ((System.Drawing.Icon)(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\green.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace FASTBuildMonitorStandalone.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/Resources/green.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitorStandalone/Resources/green.ico -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32519.379 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FASTBuildMonitorVSIX", "FASTBuildMonitorVSIX\FASTBuildMonitorVSIX.csproj", "{E50A8B0A-8964-4ADB-B504-71DD7228B20A}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FASTBuildMonitorStandalone", "FASTBuildMonitorStandalone\FASTBuildMonitorStandalone.csproj", "{D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FASTBuildMonitor", "FASTBuildMonitor\FASTBuildMonitor.csproj", "{3AA63C05-2341-4E72-ADBC-22C33341EC6E}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug Legacy|Any CPU = Debug Legacy|Any CPU 15 | Debug|Any CPU = Debug|Any CPU 16 | Release Legacy|Any CPU = Release Legacy|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A}.Debug Legacy|Any CPU.ActiveCfg = Debug Legacy|Any CPU 21 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A}.Debug Legacy|Any CPU.Build.0 = Debug Legacy|Any CPU 22 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A}.Release Legacy|Any CPU.ActiveCfg = Release Legacy|Any CPU 25 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A}.Release Legacy|Any CPU.Build.0 = Release Legacy|Any CPU 26 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}.Debug Legacy|Any CPU.ActiveCfg = Debug|Any CPU 29 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}.Debug Legacy|Any CPU.Build.0 = Debug|Any CPU 30 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}.Release Legacy|Any CPU.ActiveCfg = Release|Any CPU 33 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}.Release Legacy|Any CPU.Build.0 = Release|Any CPU 34 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {D15FA9F3-2B94-495E-A53A-576DFBA6D1F3}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E}.Debug Legacy|Any CPU.ActiveCfg = Debug Legacy|Any CPU 37 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E}.Debug Legacy|Any CPU.Build.0 = Debug Legacy|Any CPU 38 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E}.Release Legacy|Any CPU.ActiveCfg = Release Legacy|Any CPU 41 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E}.Release Legacy|Any CPU.Build.0 = Release Legacy|Any CPU 42 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {3AA63C05-2341-4E72-ADBC-22C33341EC6E}.Release|Any CPU.Build.0 = Release|Any CPU 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {B1CBC84D-A6C5-40CB-B162-CBF560A62D09} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Code/FASTBuildMonitorCommand.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright 2017 Yassine Riahi and Liam Flookes. 3 | // Provided under a MIT License, see license file on github. 4 | //------------------------------------------------------------------------------ 5 | 6 | using System; 7 | using System.ComponentModel.Design; 8 | using Microsoft.VisualStudio.Shell; 9 | using Microsoft.VisualStudio.Shell.Interop; 10 | 11 | namespace FASTBuildMonitorVSIX 12 | { 13 | /// 14 | /// Command handler 15 | /// 16 | internal sealed class FASTBuildMonitorCommand 17 | { 18 | /// 19 | /// VS Package that provides this command, not null. 20 | /// 21 | private readonly Package package; 22 | 23 | /// 24 | /// Initializes a new instance of the class. 25 | /// Adds our command handlers for menu (commands must exist in the command table file) 26 | /// 27 | /// Owner package, not null. 28 | private FASTBuildMonitorCommand(Package package) 29 | { 30 | if (package == null) 31 | { 32 | throw new ArgumentNullException("package"); 33 | } 34 | 35 | this.package = package; 36 | 37 | OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService; 38 | if (commandService != null) 39 | { 40 | var menuCommandID1 = new CommandID(PackageGuids.guidFASTBuildMonitorPackageCmdSet, PackageIds.FASTBuildMonitorCommandId); 41 | var menuItem1 = new MenuCommand(this.ShowToolWindow, menuCommandID1); 42 | commandService.AddCommand(menuItem1); 43 | 44 | var menuCommandID2 = new CommandID(PackageGuids.guidFASTBuildMonitorPackageCmdSet, PackageIds.FASTBuildMonitorToolsCommandId); 45 | var menuItem2 = new MenuCommand(this.ShowToolWindow, menuCommandID2); 46 | commandService.AddCommand(menuItem2); 47 | } 48 | } 49 | 50 | /// 51 | /// Gets the instance of the command. 52 | /// 53 | public static FASTBuildMonitorCommand Instance 54 | { 55 | get; 56 | private set; 57 | } 58 | 59 | /// 60 | /// Gets the service provider from the owner package. 61 | /// 62 | private IServiceProvider ServiceProvider => package; 63 | 64 | /// 65 | /// Initializes the singleton instance of the command. 66 | /// 67 | /// Owner package, not null. 68 | public static void Initialize(Package package) 69 | { 70 | Instance = new FASTBuildMonitorCommand(package); 71 | } 72 | 73 | /// 74 | /// Shows the tool window when the menu item is clicked. 75 | /// 76 | /// The event sender. 77 | /// The event args. 78 | private void ShowToolWindow(object sender, EventArgs e) 79 | { 80 | // Get the instance number 0 of this tool window. This window is single instance so this instance 81 | // is actually the only one. 82 | // The last flag is set to true so that if the tool window does not exists it will be created. 83 | ToolWindowPane window = this.package.FindToolWindow(typeof(FASTBuildMonitorPane), 0, true); 84 | if (window?.Frame == null) 85 | { 86 | throw new NotSupportedException("Cannot create tool window"); 87 | } 88 | 89 | ThreadHelper.ThrowIfNotOnUIThread(); 90 | IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame; 91 | Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show()); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Code/FASTBuildMonitorPackage.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright 2017 Yassine Riahi and Liam Flookes. 3 | // Provided under a MIT License, see license file on github. 4 | //------------------------------------------------------------------------------ 5 | 6 | using System; 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Runtime.InteropServices; 9 | using EnvDTE; 10 | using EnvDTE80; 11 | #if FBM_LEGACY 12 | using FASTBuildMonitorVSIX.Manifests.Legacy; 13 | #else 14 | using FASTBuildMonitorVSIX.Manifests; 15 | #endif 16 | using Microsoft.VisualStudio.Shell; 17 | 18 | namespace FASTBuildMonitorVSIX 19 | { 20 | /// 21 | /// This is the class that implements the package exposed by this assembly. 22 | /// 23 | /// 24 | /// 25 | /// The minimum requirement for a class to be considered a valid package for Visual Studio 26 | /// is to implement the IVsPackage interface and register itself with the shell. 27 | /// This package uses the helper classes defined inside the Managed Package Framework (MPF) 28 | /// to do it: it derives from the Package class that provides the implementation of the 29 | /// IVsPackage interface and uses the registration attributes defined in the framework to 30 | /// register itself and its components with the shell. These attributes tell the pkgdef creation 31 | /// utility what data to put into .pkgdef file. 32 | /// 33 | /// 34 | /// To get loaded into VS, the package must be referred by <Asset Type="Microsoft.VisualStudio.VsPackage" ...> in .vsixmanifest file. 35 | /// 36 | /// 37 | [PackageRegistration(UseManagedResourcesOnly = true)] 38 | [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About 39 | [ProvideMenuResource("Menus.ctmenu", 1)] 40 | [ProvideToolWindow(typeof(FASTBuildMonitorPane))] 41 | [Guid(PackageGuids.guidFASTBuildMonitorPackageString)] 42 | [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")] 43 | public sealed class FASTBuildMonitorPackage : Package 44 | { 45 | public DTE2 _dte; 46 | 47 | public static FASTBuildMonitorPackage _instance = null; 48 | 49 | /// 50 | /// Initializes a new instance of the class. 51 | /// 52 | public FASTBuildMonitorPackage() 53 | { 54 | // Inside this method you can place any initialization code that does not require 55 | // any Visual Studio service because at this point the package object is created but 56 | // not sited yet inside Visual Studio environment. The place to do all the other 57 | // initialization is the Initialize method. 58 | } 59 | 60 | #region Package Members 61 | 62 | /// 63 | /// Initialization of the package; this method is called right after the package is sited, so this is the place 64 | /// where you can put all the initialization code that rely on services provided by VisualStudio. 65 | /// 66 | protected override void Initialize() 67 | { 68 | FASTBuildMonitorCommand.Initialize(this); 69 | base.Initialize(); 70 | 71 | _instance = this; 72 | 73 | ThreadHelper.ThrowIfNotOnUIThread(); 74 | _dte = (DTE2)base.GetService(typeof(DTE)); 75 | } 76 | 77 | public class VSIXPackageInformation 78 | { 79 | public string _version; 80 | public string _packageName; 81 | public string _authors; 82 | } 83 | 84 | public static VSIXPackageInformation GetCurrentVSIXPackageInformation() 85 | { 86 | VSIXPackageInformation outInfo = null; 87 | 88 | try 89 | { 90 | outInfo = new VSIXPackageInformation 91 | { 92 | _version = Vsix.Version, 93 | _authors = Vsix.Author, 94 | _packageName = Vsix.Name, 95 | }; 96 | } 97 | catch (System.Exception ex) 98 | { 99 | Console.WriteLine("Exception: " + ex.ToString()); 100 | } 101 | 102 | return outInfo; 103 | } 104 | } 105 | 106 | #endregion 107 | } 108 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Code/FASTBuildMonitorPane.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright 2017 Yassine Riahi and Liam Flookes. 3 | // Provided under a MIT License, see license file on github. 4 | //------------------------------------------------------------------------------ 5 | 6 | using System; 7 | using System.Runtime.InteropServices; 8 | using EnvDTE; 9 | using EnvDTE80; 10 | using Microsoft.VisualStudio.Shell; 11 | 12 | namespace FASTBuildMonitorVSIX 13 | { 14 | /// 15 | /// This class implements the tool window exposed by this package and hosts a user control. 16 | /// 17 | /// 18 | /// In Visual Studio tool windows are composed of a frame (implemented by the shell) and a pane, 19 | /// usually implemented by the package implementer. 20 | /// 21 | /// This class derives from the ToolWindowPane class provided from the MPF in order to use its 22 | /// implementation of the IVsUIElementPane interface. 23 | /// 24 | /// 25 | [Guid("a73d6380-6d5f-4cab-8490-72ca61772d09")] 26 | public class FASTBuildMonitorPane : ToolWindowPane 27 | { 28 | /// 29 | /// Initializes a new instance of the class. 30 | /// 31 | public FASTBuildMonitorPane() : base(null) 32 | { 33 | this.Caption = "FASTBuild Monitor"; 34 | 35 | // This is the user control hosted by the tool window; Note that, even if this class implements IDisposable, 36 | // we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on 37 | // the object returned by the Content property. 38 | var vsixPackageInfo = FASTBuildMonitorPackage.GetCurrentVSIXPackageInformation(); 39 | var monitorControl = new FASTBuildMonitor.FASTBuildMonitorControl( 40 | vsixPackageInfo._packageName, 41 | vsixPackageInfo._version, 42 | vsixPackageInfo._authors 43 | ); 44 | 45 | monitorControl.OnPreviewDocumentClick += MonitorControl_OnPreviewDocumentClick; 46 | 47 | this.Content = monitorControl; 48 | } 49 | 50 | private void MonitorControl_OnPreviewDocumentClick(string filePath, int lineNumber) 51 | { 52 | if (string.IsNullOrEmpty(filePath)) 53 | return; 54 | 55 | ThreadHelper.ThrowIfNotOnUIThread(); 56 | VsShellUtilities.OpenDocument(FASTBuildMonitorPackage._instance, filePath); 57 | 58 | DTE2 _dte = FASTBuildMonitorPackage._instance._dte; 59 | 60 | //Console.WriteLine("Window: {0}", _dte.ActiveWindow.Caption); 61 | 62 | TextSelection sel = _dte.ActiveDocument.Selection as EnvDTE.TextSelection; 63 | 64 | sel.StartOfDocument(false); 65 | sel.EndOfDocument(true); 66 | sel.GotoLine(lineNumber); 67 | 68 | try 69 | { 70 | sel.ActivePoint.TryToShow(vsPaneShowHow.vsPaneShowCentered, null); 71 | } 72 | catch (System.Exception ex) 73 | { 74 | Console.WriteLine("Exception! " + ex.ToString()); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/FASTBuildMonitorPackage.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------------ 2 | // 3 | // This file was generated by VSIX Synchronizer 4 | // 5 | // ------------------------------------------------------------------------------ 6 | namespace FASTBuildMonitorVSIX 7 | { 8 | using System; 9 | 10 | /// 11 | /// Helper class that exposes all GUIDs used across VS Package. 12 | /// 13 | internal sealed partial class PackageGuids 14 | { 15 | public const string guidFASTBuildMonitorPackageString = "73de7c44-188b-45d3-aab2-19af8724c5c9"; 16 | public static Guid guidFASTBuildMonitorPackage = new Guid(guidFASTBuildMonitorPackageString); 17 | 18 | public const string guidFASTBuildMonitorPackageCmdSetString = "f5f8a562-4be2-48ed-93d7-dc122dd25775"; 19 | public static Guid guidFASTBuildMonitorPackageCmdSet = new Guid(guidFASTBuildMonitorPackageCmdSetString); 20 | 21 | public const string guidImagesString = "e6461ab7-05a5-42cf-b1fb-08c8e0783ddf"; 22 | public static Guid guidImages = new Guid(guidImagesString); 23 | } 24 | /// 25 | /// Helper class that encapsulates all CommandIDs uses across VS Package. 26 | /// 27 | internal sealed partial class PackageIds 28 | { 29 | public const int MyMenuGroup = 0x1020; 30 | public const int FASTBuildMonitorCommandId = 0x0100; 31 | public const int FASTBuildMonitorToolsCommandId = 0x0101; 32 | public const int bmpPic1 = 0x0001; 33 | public const int bmpPic2 = 0x0002; 34 | public const int bmpPicSearch = 0x0003; 35 | public const int bmpPicX = 0x0004; 36 | public const int bmpPicArrows = 0x0005; 37 | public const int bmpPicStrikethrough = 0x0006; 38 | } 39 | } -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/FASTBuildMonitorPackage.vsct: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 51 | 52 | 59 | 66 | 67 | 68 | 75 | 76 | 77 | 78 | 79 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/FASTBuildMonitorVSIX.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 15.0 6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 7 | true 8 | 15.0 9 | publish\ 10 | true 11 | Disk 12 | false 13 | Foreground 14 | 7 15 | Days 16 | false 17 | false 18 | true 19 | 0 20 | 1.0.0.%2a 21 | false 22 | false 23 | true 24 | true 25 | Key.snk 26 | 2.0 27 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 28 | {E50A8B0A-8964-4ADB-B504-71DD7228B20A} 29 | Library 30 | Properties 31 | FASTBuildMonitorVSIX 32 | FASTBuildMonitorVSIX 33 | v4.7.2 34 | true 35 | true 36 | true 37 | true 38 | false 39 | v3 40 | True 41 | true 42 | true 43 | Program 44 | $(DevEnvDir)\devenv.exe 45 | /rootsuffix Exp 46 | Debug;Release;Debug Legacy;Release Legacy 47 | 48 | 49 | DEBUG 50 | false 51 | true 52 | full 53 | bin\Debug\ 54 | prompt 55 | 4 56 | True 57 | True 58 | 59 | 60 | pdbonly 61 | true 62 | bin\Release\ 63 | TRACE 64 | prompt 65 | 4 66 | 67 | 68 | 69 | False 70 | 71 | 72 | 73 | 74 | 75 | 76 | True 77 | True 78 | FASTBuildMonitorPackage.vsct 79 | 80 | 81 | True 82 | True 83 | source.extension.vsixmanifest 84 | 85 | 86 | True 87 | True 88 | source.extension.vsixmanifest 89 | 90 | 91 | 92 | 93 | 94 | Menus.ctmenu 95 | VsctGenerator 96 | FASTBuildMonitorPackage.cs 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | true 106 | VSPackage 107 | Designer 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | Designer 117 | VsixManifestGenerator 118 | source.extension.cs 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 17.2.32505.113 130 | 131 | 132 | 133 | 17.2.32505.113 134 | 135 | 136 | 137 | 138 | 139 | FASTBuildMonitorVSIXLegacy 140 | FBM_LEGACY 141 | 142 | 143 | 144 | 145 | 146 | Designer 147 | VsixManifestGenerator 148 | source.extension.cs 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | False 163 | Microsoft .NET Framework 4.5.2 %28x86 and x64%29 164 | true 165 | 166 | 167 | False 168 | .NET Framework 3.5 SP1 169 | false 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | {3aa63c05-2341-4e72-adbc-22c33341ec6e} 181 | FASTBuildMonitor 182 | BuiltProjectOutputGroup%3bDebugSymbolsProjectOutputGroup 183 | DebugSymbolsProjectOutputGroup 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Key.snk -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Manifests/Legacy/source.extension.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------------ 2 | // 3 | // This file was generated by VSIX Synchronizer 4 | // 5 | // ------------------------------------------------------------------------------ 6 | namespace FASTBuildMonitorVSIX.Manifests.Legacy 7 | { 8 | internal sealed partial class Vsix 9 | { 10 | public const string Id = "FASTBuildMonitorVSIX.44bf85a5-7635-4a2e-86d7-7b7f3bf757a8"; 11 | public const string Name = "FASTBuildMonitorVSIX"; 12 | public const string Description = @"FASTBuild Visual Studio viewer."; 13 | public const string Language = "en-US"; 14 | public const string Version = "1.101"; 15 | public const string Author = "Ubisoft_KnownShippable"; 16 | public const string Tags = ""; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Manifests/Legacy/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | FASTBuildMonitorVSIX 6 | FASTBuild Visual Studio viewer. 7 | https://gitlab-ncsa.ubisoft.org/FastBuild/FASTBuildMonitor 8 | 9 | 10 | 11 | x86 12 | 13 | 14 | x86 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Manifests/source.extension.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------------ 2 | // 3 | // This file was generated by VSIX Synchronizer 4 | // 5 | // ------------------------------------------------------------------------------ 6 | namespace FASTBuildMonitorVSIX.Manifests 7 | { 8 | internal sealed partial class Vsix 9 | { 10 | public const string Id = "FASTBuildMonitorVSIX.2b5eff03-aa25-48ab-b76b-d380c3ff6d6c"; 11 | public const string Name = "FASTBuildMonitorVSIX"; 12 | public const string Description = @"FASTBuild Visual Studio viewer. 13 | Vs 2022"; 14 | public const string Language = "en-US"; 15 | public const string Version = "1.2"; 16 | public const string Author = "Ubisoft_KnownShippable"; 17 | public const string Tags = ""; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Manifests/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | FASTBuildMonitorVSIX 6 | FASTBuild Visual Studio viewer. 7 | Vs 2022 8 | https://gitlab-ncsa.ubisoft.org/FastBuild/FASTBuildMonitor 9 | 10 | 11 | 12 | amd64 13 | 14 | 15 | amd64 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("FASTBuildMonitorVSIX")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("FASTBuildMonitorVSIX")] 12 | [assembly: AssemblyCopyright("")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // Version information for an assembly consists of the following four values: 22 | // 23 | // Major Version 24 | // Minor Version 25 | // Build Number 26 | // Revision 27 | // 28 | // You can specify all the values or you can default the Build and Revision Numbers 29 | // by using the '*' as shown below: 30 | // [assembly: AssemblyVersion("1.0.*")] 31 | [assembly: AssemblyVersion("1.0.0.0")] 32 | [assembly: AssemblyFileVersion("1.0.0.0")] 33 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Resources/FASTBuildMonitorCommand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Resources/FASTBuildMonitorCommand.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Resources/FASTBuildMonitorPackage.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Resources/FASTBuildMonitorPackage.ico -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Resources/Images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/Resources/Images.png -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/VSPackage.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | FASTBuildMonitor Extension 122 | 123 | 124 | FASTBuildMonitor Visual Studio Extension Detailed Info 125 | 126 | 127 | 128 | Resources\FASTBuildMonitorPackage.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/stylesheet.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | border: 0; 5 | color: #1E1E1E; 6 | font-size: 13px; 7 | font-family: "Segoe UI", Helvetica, Arial, sans-serif; 8 | line-height: 1.45; 9 | word-wrap: break-word; 10 | } 11 | 12 | /* General & 'Reset' Stuff */ 13 | 14 | 15 | .container { 16 | width: 980px; 17 | margin: 0 auto; 18 | } 19 | 20 | section { 21 | display: block; 22 | margin: 0; 23 | } 24 | 25 | h1, h2, h3, h4, h5, h6 { 26 | margin: 0; 27 | } 28 | 29 | /* Header,
30 | header - container 31 | h1 - project name 32 | h2 - project description 33 | */ 34 | 35 | #header { 36 | color: #FFF; 37 | background: #68217a; 38 | position:relative; 39 | } 40 | #hangcloud { 41 | width: 190px; 42 | height: 160px; 43 | background: url("../images/bannerart03.png"); 44 | position: absolute; 45 | top: 0; 46 | right: -30px; 47 | } 48 | h1, h2 { 49 | font-family: "Segoe UI Light", "Segoe UI", Helvetica, Arial, sans-serif; 50 | line-height: 1; 51 | margin: 0 18px; 52 | padding: 0; 53 | } 54 | #header h1 { 55 | font-size: 3.4em; 56 | padding-top: 18px; 57 | font-weight: normal; 58 | margin-left: 15px; 59 | } 60 | 61 | #header h2 { 62 | font-size: 1.5em; 63 | margin-top: 10px; 64 | padding-bottom: 18px; 65 | font-weight: normal; 66 | } 67 | 68 | 69 | #main_content { 70 | width: 100%; 71 | display: flex; 72 | flex-direction: row; 73 | } 74 | 75 | 76 | h1, h2, h3, h4, h5, h6 { 77 | font-weight: bolder; 78 | } 79 | 80 | #main_content h1 { 81 | font-size: 1.8em; 82 | margin-top: 34px; 83 | } 84 | 85 | #main_content h1:first-child { 86 | margin-top: 30px; 87 | } 88 | 89 | #main_content h2 { 90 | font-size: 1.4em; 91 | font-weight: bold; 92 | } 93 | p, ul { 94 | margin: 11px 18px; 95 | } 96 | 97 | #main_content a { 98 | color: #06C; 99 | text-decoration: none; 100 | } 101 | ul { 102 | margin-top: 13px; 103 | margin-left: 18px; 104 | padding-left: 0; 105 | } 106 | ul li { 107 | margin-left: 18px; 108 | padding-left: 0; 109 | } 110 | #lpanel { 111 | width: 620px; 112 | float: left; 113 | } 114 | #rpanel ul { 115 | list-style-type: none; 116 | width: 300px; 117 | } 118 | #rpanel ul li { 119 | line-height: 1.8em; 120 | } 121 | #rpanel { 122 | background: #e7e7e7; 123 | width: 360px; 124 | float: right; 125 | } 126 | 127 | #rpanel div { 128 | width: 300px; 129 | } 130 | -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/vsix/FASTBuildMonitorVSIX.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubisoft/FASTBuildMonitor/a44e8a43fbea614cc3653ffd2f6a677942a0f481/FASTBuildMonitorVSIX/FASTBuildMonitorVSIX/vsix/FASTBuildMonitorVSIX.vsix -------------------------------------------------------------------------------- /FASTBuildMonitorVSIX/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 KnownShippable (Yassine Riahi & Liam Flookes) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FASTBuild Monitor 2 | ![msfastbuild example image](http://dualsoftinc.com/wp-content/uploads/2016/09/FASTBuildMonitorScreenshot.png "msfastbuild example") 3 | 4 | https://www.youtube.com/watch?v=saxFpmNq_Vw 5 | 6 | A graphical Visualizer for FASTBuild (Supports VS 2012, 2013, 2015, 2017). Now officially supported by FASTBuild starting v0.92 7 | 8 | 9 | 10 | ##Instructions : 11 | 12 | 1) Download the Release zip file. 13 | 14 | 2) Install the VSIX package FASTBuildMonitorVSIX.vsix 15 | 16 | 4) Restart VisualStudio and Click on Tools->FASTBuildMonitor 17 | 18 | 5) Download FASTBuild 0.92 or higher (http://fastbuild.org/docs/download.html). 19 | 20 | 6) Launch FBuild.exe with the -monitor argument 21 | 22 | 7) The FASTBuildMonitor VS extension should show the live build activity (or the previous build results). 23 | --------------------------------------------------------------------------------