Merge pull request #2 from dannoh/master

Added options
This commit is contained in:
thecoderok 2015-06-05 13:11:23 -07:00
commit 00a0240863
7 changed files with 114 additions and 19 deletions

View File

@ -7,6 +7,8 @@ This small extension will play notification sounds when following events occur:
- Entering debugger mode (breakpoint hit, etc) - Entering debugger mode (breakpoint hit, etc)
- Unit tests finished to run - Unit tests finished to run
Ability to toggle when the notifications sound can be found in the Visual Studio Options under 'Ding'
Useful when working with big solutions or when build/test run/hitting a breakpoint takes a lot of time and developer can be distructed on other things while he waits. Useful when working with big solutions or when build/test run/hitting a breakpoint takes a lot of time and developer can be distructed on other things while he waits.
This is an open source project, join! This is an open source project, join!

View File

@ -128,6 +128,9 @@
<ItemGroup> <ItemGroup>
<Compile Include="..\VsDingExtensionProject\GlobalSuppressions.cs" /> <Compile Include="..\VsDingExtensionProject\GlobalSuppressions.cs" />
<Compile Include="..\VsDingExtensionProject\Guids.cs" /> <Compile Include="..\VsDingExtensionProject\Guids.cs" />
<Compile Include="..\VsDingExtensionProject\OptionsDialog.cs">
<Link>OptionsDialog.cs</Link>
</Compile>
<Compile Include="..\VsDingExtensionProject\Properties\AssemblyInfo.cs" /> <Compile Include="..\VsDingExtensionProject\Properties\AssemblyInfo.cs" />
<Compile Include="..\VsDingExtensionProject\Resources.Designer.cs" /> <Compile Include="..\VsDingExtensionProject\Resources.Designer.cs" />
<Compile Include="..\VsDingExtensionProject\VsDingExtensionProjectPackage.cs" /> <Compile Include="..\VsDingExtensionProject\VsDingExtensionProjectPackage.cs" />

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011"> <PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata> <Metadata>
<Identity Id="ab75aa82-c4e8-42a7-b4ec-b5bae2fa4925" Version="1.1" Language="en-US" Publisher="Vitalii Ganzha" /> <Identity Id="ab75aa82-c4e8-42a7-b4ec-b5bae2fa4925" Version="1.2" Language="en-US" Publisher="Vitalii Ganzha" />
<DisplayName>Visual Studio Ding extension for VS 2012</DisplayName> <DisplayName>Visual Studio Ding extension for VS 2012</DisplayName>
<Description xml:space="preserve">This small extension will play notification sounds when following events occur: <Description xml:space="preserve">This small extension will play notification sounds when following events occur:
- Build Complete - Build Complete

View File

@ -0,0 +1,39 @@
using Microsoft.VisualStudio.Shell;
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace VitaliiGanzha.VsDingExtension
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[CLSCompliant(false), ComVisible(true)]
public class OptionsDialog : DialogPage
{
[Category("Beeps")]
[DisplayName("Breakpoint")]
[Description("Beep when a breakpoint is hit")]
public bool BreakpointBeep { get; set; }
[Category("Beeps")]
[DisplayName("Build")]
[Description("Beep when a build is completed")]
public bool BuildBeep { get; set; }
[Category("Beeps")]
[DisplayName("Tests")]
[Description("Beep when a test run is completed")]
public bool TestBeep { get; set; }
[DisplayName("Only when in background")]
[Description("Beep only when Visual Studio does not have focus")]
public bool BeepOnUnfocus { get; set; }
public OptionsDialog()
{
BreakpointBeep = true;
BuildBeep = true;
TestBeep = true;
BeepOnUnfocus = false;
}
}
}

View File

@ -148,6 +148,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Guids.cs" /> <Compile Include="Guids.cs" />
<Compile Include="OptionsDialog.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Resources.Designer.cs"> <Compile Include="Resources.Designer.cs">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>

View File

@ -1,13 +1,16 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Media; using System.Media;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms;
using EnvDTE; using EnvDTE;
using EnvDTE80; using EnvDTE80;
using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TestWindow.Extensibility; using Microsoft.VisualStudio.TestWindow.Extensibility;
using Process = System.Diagnostics.Process;
namespace VitaliiGanzha.VsDingExtension namespace VitaliiGanzha.VsDingExtension
{ {
@ -15,6 +18,7 @@ namespace VitaliiGanzha.VsDingExtension
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
[Guid(GuidList.guidVsDingExtensionProjectPkgString)] [Guid(GuidList.guidVsDingExtensionProjectPkgString)]
[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")] [ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
[ProvideOptionPage(typeof(OptionsDialog), "Ding", "Options", 0, 0, true)]
public sealed class VsDingExtensionProjectPackage : Package public sealed class VsDingExtensionProjectPackage : Package
{ {
private DTE2 applicationObject; private DTE2 applicationObject;
@ -24,18 +28,33 @@ namespace VitaliiGanzha.VsDingExtension
private SoundPlayer buildCompleteSoundPlayer; private SoundPlayer buildCompleteSoundPlayer;
private SoundPlayer debugSoundPlayer; private SoundPlayer debugSoundPlayer;
private SoundPlayer testCompleteSoundPlayer; private SoundPlayer testCompleteSoundPlayer;
private bool onlyOnUnFocus;
private bool onBuild;
private bool onTestRunCompleted;
private bool onBreakpoint;
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
public VsDingExtensionProjectPackage() public VsDingExtensionProjectPackage()
{ {
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString())); Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", ToString()));
} }
#region Package Members #region Package Members
protected override void OnSaveOptions(string key, Stream stream)
{
base.OnSaveOptions(key, stream);
ApplySettings();
}
protected override void Initialize() protected override void Initialize()
{ {
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", ToString()));
this.ToString()));
base.Initialize(); base.Initialize();
buildCompleteSoundPlayer = new SoundPlayer(Resources.build); buildCompleteSoundPlayer = new SoundPlayer(Resources.build);
@ -43,21 +62,25 @@ namespace VitaliiGanzha.VsDingExtension
testCompleteSoundPlayer = new SoundPlayer(Resources.ding); testCompleteSoundPlayer = new SoundPlayer(Resources.ding);
applicationObject = (DTE2)GetService(typeof(DTE)); applicationObject = (DTE2)GetService(typeof(DTE));
ApplySettings();
buildEvents = applicationObject.Events.BuildEvents;
debugEvents = applicationObject.Events.DebuggerEvents;
this.buildEvents = applicationObject.Events.BuildEvents; buildEvents.OnBuildDone += (scope, action) =>
this.debugEvents = applicationObject.Events.DebuggerEvents; {
if (onBuild)
buildEvents.OnBuildDone += (scope, action) => PlaySafe(buildCompleteSoundPlayer); PlaySafe(buildCompleteSoundPlayer);
};
debugEvents.OnEnterBreakMode += delegate(dbgEventReason reason, ref dbgExecutionAction action) debugEvents.OnEnterBreakMode += delegate(dbgEventReason reason, ref dbgExecutionAction action)
{ {
if (reason != dbgEventReason.dbgEventReasonStep) if (reason != dbgEventReason.dbgEventReasonStep && onBreakpoint)
{ {
PlaySafe(debugSoundPlayer); PlaySafe(debugSoundPlayer);
} }
}; };
var componentModel = var componentModel =
Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel; GetGlobalService(typeof(SComponentModel)) as IComponentModel;
if (componentModel == null) if (componentModel == null)
{ {
@ -70,6 +93,8 @@ namespace VitaliiGanzha.VsDingExtension
} }
private void PlaySafe(SoundPlayer soundPlayer) private void PlaySafe(SoundPlayer soundPlayer)
{
if (onlyOnUnFocus && !ApplicationIsActivated())
{ {
try try
{ {
@ -77,19 +102,42 @@ namespace VitaliiGanzha.VsDingExtension
} }
catch (Exception ex) catch (Exception ex)
{ {
ActivityLog.LogError(this.GetType().FullName, ex.Message); ActivityLog.LogError(GetType().FullName, ex.Message);
}
} }
} }
private void OperationStateOnStateChanged(object sender, OperationStateChangedEventArgs operationStateChangedEventArgs) private void OperationStateOnStateChanged(object sender, OperationStateChangedEventArgs operationStateChangedEventArgs)
{ {
if (onTestRunCompleted && operationStateChangedEventArgs.State.HasFlag(TestOperationStates.TestExecutionFinished))
if (operationStateChangedEventArgs.State.HasFlag(TestOperationStates.TestExecutionFinished))
{ {
PlaySafe(testCompleteSoundPlayer); PlaySafe(testCompleteSoundPlayer);
} }
} }
#endregion #endregion
private void ApplySettings()
{
onlyOnUnFocus = (applicationObject.Properties["Ding", "Options"].Item("BeepOnUnfocus").Value as bool?) ?? false;
onBreakpoint = (applicationObject.Properties["Ding", "Options"].Item("BreakpointBeep").Value as bool?) ?? true;
onTestRunCompleted = (applicationObject.Properties["Ding", "Options"].Item("TestBeep").Value as bool?) ?? true;
onBuild = (applicationObject.Properties["Ding", "Options"].Item("BuildBeep").Value as bool?) ?? true;
Debug.WriteLine(string.Format("OnlyOnUnFocus: {0}", onlyOnUnFocus));
}
public bool ApplicationIsActivated()
{
var activatedHandle = GetForegroundWindow();
if (activatedHandle == IntPtr.Zero)
{
return false; // No window is currently activated
}
var procId = Process.GetCurrentProcess().Id;
int activeProcId;
GetWindowThreadProcessId(activatedHandle, out activeProcId);
return activeProcId == procId;
}
} }
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011"> <PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata> <Metadata>
<Identity Id="26ba08d0-0d25-4479-8684-3054dd122876" Version="1.1" Language="en-US" Publisher="Vitalii Ganzha" /> <Identity Id="26ba08d0-0d25-4479-8684-3054dd122876" Version="1.2" Language="en-US" Publisher="Vitalii Ganzha" />
<DisplayName>Visual Studio Ding extension</DisplayName> <DisplayName>Visual Studio Ding extension</DisplayName>
<Description xml:space="preserve">This small extension will play notification sounds when following events occur: <Description xml:space="preserve">This small extension will play notification sounds when following events occur:
- Build Complete - Build Complete