Browse Source

Basic monitoring implementation

Tidying, ignore user files, etc
master
unknown 12 years ago
parent
commit
e3843c9730

+ 2
- 1
.gitignore View File

@@ -1,4 +1,5 @@
1 1
 /*.suo
2 2
 /WindowMonitor/bin
3 3
 /WindowMonitor/obj
4
-/_ReSharper.*
4
+/_ReSharper.*
5
+*.user

+ 4
- 4
WindowMonitor.sln View File

@@ -9,10 +9,10 @@ Global
9 9
 		Release|x86 = Release|x86
10 10
 	EndGlobalSection
11 11
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
12
-		{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}.Debug|x86.ActiveCfg = Debug|x86
13
-		{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}.Debug|x86.Build.0 = Debug|x86
14
-		{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}.Release|x86.ActiveCfg = Release|x86
15
-		{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}.Release|x86.Build.0 = Release|x86
12
+		{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}.Debug|x86.ActiveCfg = Debug|x64
13
+		{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}.Debug|x86.Build.0 = Debug|x64
14
+		{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}.Release|x86.ActiveCfg = Release|x64
15
+		{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}.Release|x86.Build.0 = Release|x64
16 16
 	EndGlobalSection
17 17
 	GlobalSection(SolutionProperties) = preSolution
18 18
 		HideSolutionNode = FALSE

+ 25
- 15
WindowMonitor/Program.cs View File

@@ -1,24 +1,34 @@
1
-using System;
2
-using System.Collections.Generic;
3
-using System.Linq;
4
-using System.ServiceProcess;
5
-using System.Text;
6
-
7
-namespace WindowMonitor
1
+namespace WindowMonitor
8 2
 {
9
-    static class Program
3
+    using System;
4
+    using System.ServiceProcess;
5
+
6
+    /// <summary>
7
+    /// The main entry point. Starts the service either as a console app or
8
+    /// registered with the service manager.
9
+    /// </summary>
10
+    internal static class Program
10 11
     {
11 12
         /// <summary>
12 13
         /// The main entry point for the application.
13 14
         /// </summary>
14
-        static void Main()
15
+        public static void Main()
15 16
         {
16
-            ServiceBase[] ServicesToRun;
17
-            ServicesToRun = new ServiceBase[] 
18
-			{ 
19
-				new Service1() 
20
-			};
21
-            ServiceBase.Run(ServicesToRun);
17
+            if (Environment.UserInteractive)
18
+            {
19
+                var service = new WindowMonitorService();
20
+                service.Startup();
21
+                Console.WriteLine("Service started; Press <enter> to stop.");
22
+                Console.ReadLine();
23
+                service.Shutdown();
24
+            }
25
+            else
26
+            {
27
+                ServiceBase.Run(new ServiceBase[] 
28
+                { 
29
+                    new WindowMonitorService() 
30
+                });                
31
+            }
22 32
         }
23 33
     }
24 34
 }

+ 0
- 27
WindowMonitor/Service1.cs View File

@@ -1,27 +0,0 @@
1
-using System;
2
-using System.Collections.Generic;
3
-using System.ComponentModel;
4
-using System.Data;
5
-using System.Diagnostics;
6
-using System.Linq;
7
-using System.ServiceProcess;
8
-using System.Text;
9
-
10
-namespace WindowMonitor
11
-{
12
-    public partial class Service1 : ServiceBase
13
-    {
14
-        public Service1()
15
-        {
16
-            InitializeComponent();
17
-        }
18
-
19
-        protected override void OnStart(string[] args)
20
-        {
21
-        }
22
-
23
-        protected override void OnStop()
24
-        {
25
-        }
26
-    }
27
-}

+ 82
- 0
WindowMonitor/WindowMonitor.cs View File

@@ -0,0 +1,82 @@
1
+namespace WindowMonitor
2
+{
3
+    using System;
4
+    using System.Diagnostics;
5
+    using System.Management;
6
+    using System.Runtime.InteropServices;
7
+    using System.Text;
8
+
9
+    /// <summary>
10
+    /// Utility class to monitor the currently active window.
11
+    /// </summary>
12
+    public class WindowMonitor
13
+    {
14
+        /// <summary>
15
+        /// Gets a pointer to the currently active window.
16
+        /// </summary>
17
+        /// <returns>
18
+        /// A pointer to the active window.
19
+        /// </returns>
20
+        public IntPtr GetActiveWindowHandle()
21
+        {
22
+            return GetForegroundWindow();
23
+        }
24
+
25
+        /// <summary>
26
+        /// Gets the title of the window with the given handle.
27
+        /// </summary>
28
+        /// <param name="handle">
29
+        /// The handle of the window to look up.
30
+        /// </param>
31
+        /// <returns>
32
+        /// The textual title of the given window.
33
+        /// </returns>
34
+        public string GetWindowTitle(IntPtr handle)
35
+        {
36
+            var length = GetWindowTextLength(handle);
37
+            var buffer = new StringBuilder(length + 1);
38
+            GetWindowText(handle, buffer, length + 1);
39
+            return buffer.ToString();
40
+        }
41
+
42
+        /// <summary>
43
+        /// Gets the full command line of the process that owns the window
44
+        /// with the given handle.
45
+        /// </summary>
46
+        /// <param name="handle">
47
+        /// The handle of the window to look up.
48
+        /// </param>
49
+        /// <returns>
50
+        /// The command line of the owning process, or <c>string.Empty</c> if
51
+        /// it couldn't be found.
52
+        /// </returns>
53
+        public string GetWindowFileName(IntPtr handle)
54
+        {
55
+            int processId;
56
+            GetWindowThreadProcessId(handle, out processId);
57
+
58
+            var wmiQuery = string.Format("select CommandLine from Win32_Process where ProcessId={0}", processId);
59
+            var searcher = new ManagementObjectSearcher(wmiQuery);
60
+            var resultEnumerator = searcher.Get().GetEnumerator();
61
+
62
+            if (resultEnumerator.MoveNext())
63
+            {
64
+                return resultEnumerator.Current["CommandLine"].ToString();
65
+            }
66
+
67
+            return string.Empty;
68
+        }
69
+
70
+        [DllImport("user32.dll")]
71
+        private static extern IntPtr GetForegroundWindow();
72
+
73
+        [DllImport("user32.dll")]
74
+        private static extern int GetWindowTextLength(IntPtr handle);
75
+
76
+        [DllImport("user32.dll")]
77
+        private static extern int GetWindowText(IntPtr handle, StringBuilder text, int count);
78
+
79
+        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
80
+        private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
81
+    }
82
+}

+ 42
- 4
WindowMonitor/WindowMonitor.csproj View File

@@ -6,7 +6,7 @@
6 6
     <ProductVersion>8.0.30703</ProductVersion>
7 7
     <SchemaVersion>2.0</SchemaVersion>
8 8
     <ProjectGuid>{41B32E2F-66A0-4F73-9705-E062EEA7C3ED}</ProjectGuid>
9
-    <OutputType>WinExe</OutputType>
9
+    <OutputType>Exe</OutputType>
10 10
     <AppDesignerFolder>Properties</AppDesignerFolder>
11 11
     <RootNamespace>WindowMonitor</RootNamespace>
12 12
     <AssemblyName>WindowMonitor</AssemblyName>
@@ -33,9 +33,46 @@
33 33
     <ErrorReport>prompt</ErrorReport>
34 34
     <WarningLevel>4</WarningLevel>
35 35
   </PropertyGroup>
36
+  <PropertyGroup>
37
+    <StartupObject />
38
+  </PropertyGroup>
39
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
40
+    <DebugSymbols>true</DebugSymbols>
41
+    <OutputPath>bin\x64\Debug\</OutputPath>
42
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
43
+    <DebugType>full</DebugType>
44
+    <PlatformTarget>x64</PlatformTarget>
45
+    <CodeAnalysisLogFile>bin\Debug\WindowMonitor.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
46
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
47
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
48
+    <ErrorReport>prompt</ErrorReport>
49
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
50
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
51
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
52
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
53
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
54
+    <CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
55
+  </PropertyGroup>
56
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
57
+    <OutputPath>bin\x64\Release\</OutputPath>
58
+    <DefineConstants>TRACE</DefineConstants>
59
+    <Optimize>true</Optimize>
60
+    <DebugType>pdbonly</DebugType>
61
+    <PlatformTarget>x64</PlatformTarget>
62
+    <CodeAnalysisLogFile>bin\Release\WindowMonitor.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
63
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
64
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
65
+    <ErrorReport>prompt</ErrorReport>
66
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
67
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
68
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
69
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
70
+    <CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
71
+  </PropertyGroup>
36 72
   <ItemGroup>
37 73
     <Reference Include="System" />
38 74
     <Reference Include="System.Core" />
75
+    <Reference Include="System.Management" />
39 76
     <Reference Include="System.Xml.Linq" />
40 77
     <Reference Include="System.Data.DataSetExtensions" />
41 78
     <Reference Include="Microsoft.CSharp" />
@@ -44,11 +81,12 @@
44 81
     <Reference Include="System.Xml" />
45 82
   </ItemGroup>
46 83
   <ItemGroup>
47
-    <Compile Include="Service1.cs">
84
+    <Compile Include="WindowMonitor.cs" />
85
+    <Compile Include="WindowMonitorService.cs">
48 86
       <SubType>Component</SubType>
49 87
     </Compile>
50
-    <Compile Include="Service1.Designer.cs">
51
-      <DependentUpon>Service1.cs</DependentUpon>
88
+    <Compile Include="WindowMonitorService.Designer.cs">
89
+      <DependentUpon>WindowMonitorService.cs</DependentUpon>
52 90
     </Compile>
53 91
     <Compile Include="Program.cs" />
54 92
     <Compile Include="Properties\AssemblyInfo.cs" />

WindowMonitor/Service1.Designer.cs → WindowMonitor/WindowMonitorService.Designer.cs View File

@@ -1,6 +1,6 @@
1 1
 namespace WindowMonitor
2 2
 {
3
-    partial class Service1
3
+    partial class WindowMonitorService
4 4
     {
5 5
         /// <summary> 
6 6
         /// Required designer variable.
@@ -29,7 +29,7 @@
29 29
         private void InitializeComponent()
30 30
         {
31 31
             components = new System.ComponentModel.Container();
32
-            this.ServiceName = "Service1";
32
+            this.ServiceName = "WindowMonitorService";
33 33
         }
34 34
 
35 35
         #endregion

+ 89
- 0
WindowMonitor/WindowMonitorService.cs View File

@@ -0,0 +1,89 @@
1
+namespace WindowMonitor
2
+{
3
+    using System;
4
+    using System.ServiceProcess;
5
+    using System.Timers;
6
+
7
+    /// <summary>
8
+    /// Background service to monitor window status.
9
+    /// </summary>
10
+    public partial class WindowMonitorService : ServiceBase
11
+    {
12
+        /// <summary>
13
+        /// Timer to use to schedule window checks.
14
+        /// </summary>
15
+        private Timer timer;
16
+
17
+        /// <summary>
18
+        /// The window monitor to use.
19
+        /// </summary>
20
+        private WindowMonitor monitor;
21
+
22
+        /// <summary>
23
+        /// Initializes a new instance of the <see cref="WindowMonitorService"/> class. 
24
+        /// </summary>
25
+        public WindowMonitorService()
26
+        {
27
+            this.InitializeComponent();
28
+        }
29
+
30
+        /// <summary>
31
+        /// Starts the service.
32
+        /// </summary>
33
+        public void Startup()
34
+        {
35
+            this.monitor = new WindowMonitor();
36
+            this.timer = new Timer(1000);
37
+            this.timer.Elapsed += this.OnTimerElapsed;
38
+            this.timer.Start();
39
+        }
40
+
41
+        /// <summary>
42
+        /// Stops the service.
43
+        /// </summary>
44
+        public void Shutdown()
45
+        {
46
+            this.timer.Stop();
47
+            this.timer.Elapsed -= this.OnTimerElapsed;
48
+            this.timer.Dispose();
49
+            this.timer = null;
50
+            this.monitor = null;
51
+        }
52
+
53
+        /// <summary>
54
+        /// Called when the service is being started by the Windows host.
55
+        /// </summary>
56
+        /// <param name="args">
57
+        /// The arguments given to the service.
58
+        /// </param>
59
+        protected override void OnStart(string[] args)
60
+        {
61
+            this.Startup();
62
+        }
63
+
64
+        /// <summary>
65
+        /// Called when the service is being stopped by the Windows host.
66
+        /// </summary>
67
+        protected override void OnStop()
68
+        {
69
+            this.Shutdown();
70
+        }
71
+
72
+        /// <summary>
73
+        /// Called when our timer elapses, triggering us to do some work.
74
+        /// </summary>
75
+        /// <param name="sender">
76
+        /// The timer that sent the event.
77
+        /// </param>
78
+        /// <param name="e">
79
+        /// The event arguments.
80
+        /// </param>
81
+        private void OnTimerElapsed(object sender, ElapsedEventArgs e)
82
+        {
83
+            var handle = this.monitor.GetActiveWindowHandle();
84
+            Console.WriteLine(this.monitor.GetWindowTitle(handle));
85
+            Console.WriteLine(this.monitor.GetWindowFileName(handle));
86
+            Console.WriteLine();
87
+        }
88
+    }
89
+}

Loading…
Cancel
Save