2015-06-05 21:48:04 +00:00
namespace VitaliiGanzha.VsDingExtension
2014-03-13 22:21:47 +00:00
{
2015-06-05 21:48:04 +00:00
using System ;
using System.Diagnostics ;
2015-06-12 21:09:04 +00:00
using System.Drawing ;
2015-06-05 21:48:04 +00:00
using System.Globalization ;
using System.Media ;
using System.Runtime.InteropServices ;
2015-06-12 21:09:04 +00:00
using System.Windows.Forms ;
2015-06-05 21:48:04 +00:00
using EnvDTE ;
using EnvDTE80 ;
using Microsoft.VisualStudio.ComponentModelHost ;
using Microsoft.VisualStudio.Shell ;
using Microsoft.VisualStudio.TestWindow.Extensibility ;
2015-12-16 15:04:33 +00:00
using Microsoft.VisualStudio.TestWindow.Controller ;
2015-06-05 21:48:04 +00:00
using Process = System . Diagnostics . Process ;
2015-12-16 15:04:33 +00:00
2014-03-13 22:21:47 +00:00
[PackageRegistration(UseManagedResourcesOnly = true)]
2015-06-05 22:02:21 +00:00
[InstalledProductRegistration("#110", "#112", "1.1", IconResourceID = 400)]
2014-03-13 22:21:47 +00:00
[Guid(GuidList.guidVsDingExtensionProjectPkgString)]
2014-03-20 23:28:02 +00:00
[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
2015-06-01 01:02:52 +00:00
[ProvideOptionPage(typeof(OptionsDialog), "Ding", "Options", 0, 0, true)]
2015-06-08 19:05:20 +00:00
public sealed class VsDingExtensionProjectPackage : Package , IDisposable
2014-03-13 22:21:47 +00:00
{
private DTE2 applicationObject ;
2014-03-22 00:03:52 +00:00
private BuildEvents buildEvents ;
private DebuggerEvents debugEvents ;
2015-06-05 21:48:04 +00:00
private OptionsDialog _options = null ;
2015-12-29 03:52:44 +00:00
private Players players = new Players ( ) ;
2015-06-01 01:02:52 +00:00
2014-03-13 22:21:47 +00:00
public VsDingExtensionProjectPackage ( )
{
2015-06-01 01:02:52 +00:00
Debug . WriteLine ( string . Format ( CultureInfo . CurrentCulture , "Entering constructor for: {0}" , ToString ( ) ) ) ;
2014-03-13 22:21:47 +00:00
}
#region Package Members
protected override void Initialize ( )
{
2015-06-01 01:02:52 +00:00
Debug . WriteLine ( string . Format ( CultureInfo . CurrentCulture , "Entering Initialize() of: {0}" , ToString ( ) ) ) ;
2014-03-13 22:21:47 +00:00
base . Initialize ( ) ;
2014-03-25 05:40:05 +00:00
applicationObject = ( DTE2 ) GetService ( typeof ( DTE ) ) ;
2015-06-01 01:02:52 +00:00
buildEvents = applicationObject . Events . BuildEvents ;
debugEvents = applicationObject . Events . DebuggerEvents ;
2014-03-13 22:21:47 +00:00
2015-12-29 03:52:44 +00:00
SetupEventHandlers ( ) ;
}
private void SetupEventHandlers ( )
{
2015-06-01 01:02:52 +00:00
buildEvents . OnBuildDone + = ( scope , action ) = >
{
2015-06-12 21:09:04 +00:00
if ( Options . IsBeepOnBuildComplete )
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( EventType . BuildCompleted , "Build has been completed." ) ;
2015-06-12 21:09:04 +00:00
}
2015-06-01 01:02:52 +00:00
} ;
2015-06-12 21:09:04 +00:00
2015-12-29 03:52:44 +00:00
debugEvents . OnEnterBreakMode + = delegate ( dbgEventReason reason , ref dbgExecutionAction action )
2014-03-25 05:40:05 +00:00
{
2015-06-12 21:09:04 +00:00
if ( reason ! = dbgEventReason . dbgEventReasonStep & & Options . IsBeepOnBreakpointHit )
2014-03-25 05:40:05 +00:00
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( EventType . BreakpointHit , "Breakpoint was hit." ) ;
2014-03-25 05:40:05 +00:00
}
} ;
2014-03-13 22:21:47 +00:00
2014-03-20 23:28:02 +00:00
var componentModel =
2015-06-01 01:02:52 +00:00
GetGlobalService ( typeof ( SComponentModel ) ) as IComponentModel ;
2014-03-13 22:21:47 +00:00
2014-03-20 23:28:02 +00:00
if ( componentModel = = null )
{
2014-03-22 00:03:52 +00:00
Debug . WriteLine ( "componentModel is null" ) ;
return ;
2014-03-20 23:28:02 +00:00
}
var operationState = componentModel . GetService < IOperationState > ( ) ;
operationState . StateChanged + = OperationStateOnStateChanged ;
2014-03-13 22:21:47 +00:00
}
2014-03-20 23:28:02 +00:00
2015-06-05 21:48:04 +00:00
private OptionsDialog Options
{
get
{
if ( _options = = null )
{
_options = ( OptionsDialog ) GetDialogPage ( typeof ( OptionsDialog ) ) ;
}
return _options ;
}
}
2015-12-29 03:52:44 +00:00
private void HandleEventSafe ( EventType eventType , string messageText )
2015-12-16 16:18:16 +00:00
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( eventType , messageText , ToolTipIcon . Info ) ;
2015-12-16 16:18:16 +00:00
}
2015-12-29 03:52:44 +00:00
private void HandleEventSafe ( EventType eventType , string messageText , ToolTipIcon icon )
2015-06-12 21:09:04 +00:00
{
2015-06-12 21:33:43 +00:00
if ( ! ShouldPerformNotificationAction ( ) )
{
return ;
}
2015-12-29 03:52:44 +00:00
players . PlaySoundSafe ( eventType ) ;
2015-12-16 16:18:16 +00:00
ShowNotifyMessage ( messageText , icon ) ;
2015-06-12 21:09:04 +00:00
}
private void ShowNotifyMessage ( string messageText )
2015-12-16 16:18:16 +00:00
{
ShowNotifyMessage ( messageText , ToolTipIcon . Info ) ;
}
private void ShowNotifyMessage ( string messageText , ToolTipIcon icon )
2015-06-12 21:09:04 +00:00
{
if ( ! _options . ShowTrayNotifications )
{
return ;
}
2015-12-16 16:18:16 +00:00
if ( Options . ShowTrayDisableMessage )
{
string autoAppendMessage = System . Environment . NewLine + "You can disable this notification in:" + System . Environment . NewLine + "Tools->Options->Ding->Show tray notifications" ;
messageText = string . Format ( "{0}{1}" , messageText , autoAppendMessage ) ;
}
2015-06-12 21:09:04 +00:00
System . Threading . Tasks . Task . Run ( async ( ) = >
{
var tray = new NotifyIcon
{
Icon = SystemIcons . Application ,
2015-12-16 16:18:16 +00:00
BalloonTipIcon = icon ,
2015-06-12 21:09:04 +00:00
BalloonTipText = messageText ,
BalloonTipTitle = "Visual Studio Ding extension" ,
Visible = true
} ;
tray . ShowBalloonTip ( 5000 ) ;
await System . Threading . Tasks . Task . Delay ( 5000 ) ;
tray . Icon = ( Icon ) null ;
tray . Visible = false ;
tray . Dispose ( ) ;
} ) ;
}
2015-06-12 21:33:43 +00:00
private bool ShouldPerformNotificationAction ( )
2014-03-20 23:28:02 +00:00
{
2015-06-12 21:09:04 +00:00
if ( ! Options . IsBeepOnlyWhenVisualStudioIsInBackground )
2014-03-20 23:28:02 +00:00
{
2015-06-05 21:48:04 +00:00
return true ;
2014-03-20 23:28:02 +00:00
}
2015-12-29 03:52:44 +00:00
return Options . IsBeepOnlyWhenVisualStudioIsInBackground & & ! WinApiHelper . ApplicationIsActivated ( ) ;
2014-03-20 23:28:02 +00:00
}
2014-03-13 22:21:47 +00:00
2015-06-05 21:48:04 +00:00
private void OperationStateOnStateChanged ( object sender , OperationStateChangedEventArgs operationStateChangedEventArgs )
2015-06-01 01:02:52 +00:00
{
2015-12-16 15:04:33 +00:00
if ( Options . IsBeepOnTestComplete & & operationStateChangedEventArgs . State . HasFlag ( TestOperationStates . TestExecutionFinished ) )
2015-06-05 21:48:04 +00:00
{
2015-12-29 03:52:44 +00:00
var testOperation = ( ( TestRunRequest ) operationStateChangedEventArgs . Operation ) ;
var isTestsFailed = testOperation . DominantTestState = = TestState . Failed ;
var eventType = isTestsFailed ? EventType . TestsCompletedFailure : EventType . TestsCompletedSuccess ;
if ( Options . IsBeepOnTestFailed & & isTestsFailed )
2015-12-16 15:04:33 +00:00
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( eventType , "Test execution failed!" , ToolTipIcon . Error ) ;
2015-12-16 15:04:33 +00:00
}
else
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( eventType , "Test execution has been completed." ) ;
2015-12-16 15:04:33 +00:00
}
2015-06-05 21:48:04 +00:00
}
2015-06-01 01:02:52 +00:00
}
2015-06-05 21:48:04 +00:00
#endregion
2015-06-04 18:42:54 +00:00
2015-06-08 19:05:20 +00:00
public void Dispose ( )
{
2015-12-29 03:52:44 +00:00
players . Dispose ( ) ;
2015-06-08 19:05:20 +00:00
}
2014-03-13 22:21:47 +00:00
}
}