{"id":17095596,"url":"https://github.com/meyfa/csharp-windowtitlewatcher","last_synced_at":"2025-09-26T12:35:28.287Z","repository":{"id":68200442,"uuid":"93450808","full_name":"meyfa/CSharp-WindowTitleWatcher","owner":"meyfa","description":"Allows observing window states and titles in C#.","archived":false,"fork":false,"pushed_at":"2018-09-27T12:20:29.000Z","size":33,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-01T05:18:40.043Z","etag":null,"topics":["csharp","observer","titles","watcher","windows"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/WindowTitleWatcher/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meyfa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"meyfa"}},"created_at":"2017-06-05T21:57:56.000Z","updated_at":"2025-01-07T16:02:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"5afa2696-264f-4a28-bc1d-646f6e014875","html_url":"https://github.com/meyfa/CSharp-WindowTitleWatcher","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meyfa%2FCSharp-WindowTitleWatcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meyfa%2FCSharp-WindowTitleWatcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meyfa%2FCSharp-WindowTitleWatcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meyfa%2FCSharp-WindowTitleWatcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meyfa","download_url":"https://codeload.github.com/meyfa/CSharp-WindowTitleWatcher/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245144021,"owners_count":20568049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","observer","titles","watcher","windows"],"created_at":"2024-10-14T14:43:15.130Z","updated_at":"2025-09-26T12:35:28.205Z","avatar_url":"https://github.com/meyfa.png","language":"C#","funding_links":["https://github.com/sponsors/meyfa"],"categories":[],"sub_categories":[],"readme":"# WindowTitleWatcher\n\n[![Build status](https://ci.appveyor.com/api/projects/status/wcj98yq1x83fa7yf?svg=true)](https://ci.appveyor.com/project/meyfa/csharp-windowtitlewatcher)\n[![NuGet](https://img.shields.io/nuget/v/WindowTitleWatcher.svg)](https://www.nuget.org/packages/WindowTitleWatcher)\n\nAllows retrieving and observing window titles in C#.\n\n## Usage\n\nAfter the library has been added to your project, it is available within the\nnamespaces `WindowTitleWatcher` and `WindowTitleWatcher.Util`.\n\n### Retrieve a title\n\nThe simplest way of retrieving a window's information is through\n`WindowTitleWatcher.Util.WindowInfo`. Example:\n\n```csharp\nusing WindowTitleWatcher.Util;\nusing System.Diagnostics;\n// ...\n\nvar window = new WindowInfo(Process.GetProcessById(12345).MainWindowHandle);\nConsole.WriteLine(window.ProcessId);    // 12345\nConsole.WriteLine(window.ProcessName);  // \"notepad\"\nConsole.WriteLine(window.IsVisible);    // true\nConsole.WriteLine(window.Title);        // \"Untitled - Notepad\"\n```\n\n### `BasicWatcher`: Watch for updates\n\n`WindowTitleWatcher.BasicWatcher` is an extension of the abstract `Watcher`\nclass and provides facilities for accessing a specific window's title,\nvisibility state, and also whether that window still exists. Events are included\nthat fire when any of the aforementioned properties change.\n\n`BasicWatcher` instances can be constructed with any of the following:\n- a `System.Diagnostics.Process` object (whose main window will be chosen)\n- a `WindowTitleWatcher.Util.WindowInfo` object\n- a window handle in the form of an `IntPtr`\n\nThe watcher can optionally keep its own process alive as long as the watched\nwindow exists, although that is not default behavior.\n\nExample:\n\n```csharp\nusing WindowTitleWatcher;\nusing System.Diagnostics;\n// ...\n\nvar watcher = new BasicWatcher(Process.GetProcessById(12345));\nConsole.WriteLine(watcher.Title); // log current window title\nConsole.WriteLine(watcher.IsVisible);\n\nwatcher.TitleChanged += (sender, e) =\u003e\n{\n    Console.WriteLine(e.PreviousTitle + \" -\u003e \" + e.NewTitle);\n};\nwatcher.VisibilityChanged += (sender, e) =\u003e\n{\n    Console.WriteLine(watcher.IsVisible ? \"shown\" : \"hidden\");\n};\nwatcher.Disposed += (sender, e) =\u003e\n{\n    Console.WriteLine(\"Window is disposed and cannot be watched further.\");\n    // The foreign process has disposed the watched window.\n    // At this point, the watcher thread will exit.\n};\n```\n\n### `RecurrentWatcher`: Watch windows that might close/reopen\n\nA `RecurrentWatcher` is used when the watching should not stop after the\nwindow's disposal. It will then later reactivate when another window matching\nsome criteria appears.\n\nFor this, it uses a generator function supplied by you, which should return\nquickly as it may be called hundreds of times each second. Its return value\nshould either be a `WindowInfo` instance (or `null` if none found at the\nmoment), or, alternatively, an `IntPtr` to the window handle (or `IntPtr.Zero`\nif none found).\n\n```csharp\nusing WindowTitleWatcher;\n// ...\n\nvar watcher = new RecurrentWatcher(() =\u003e /* your generator function */);\n```\n\n### Window enumeration and filtered lookup\n\nDetails about the target window, such as its handle or the process's id (PID),\nare often unknown. This is why the `WindowTitleWatcher.Util.Windows` class\nprovides static methods for enumerating all active windows as well as for\nfinding windows matching your criteria.\n\nExample for finding a window for the Notepad application:\n\n```csharp\nusing WindowTitleWatcher;\nusing WindowTitleWatcher.Util;\n// ...\n\nWindowInfo window = Windows.FindFirst(w =\u003e w.IsVisible \u0026\u0026 w.ProcessName == \"notepad\");\nif (window != null)\n{\n    // The window exists, create a watcher:\n    BasicWatcher watcher = new BasicWatcher(window);\n    // ...\n}\n```\n\n### Using window lookup with `RecurrentWatcher`\n\nThe most powerful setup is using `Windows.FindFirst` as a generator for the\n`RecurrentWatcher`, as it is able to very reliably watch any window even after\nit has been closed and only later reopened.\n\nExample:\n\n```csharp\nvar watcher = new RecurrentWatcher(() =\u003e Windows.FindFirst(w =\u003e w.ProcessName == \"notepad\"));\nwatcher.TitleChanged += (sender, e) =\u003e Console.WriteLine(e.NewTitle);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeyfa%2Fcsharp-windowtitlewatcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeyfa%2Fcsharp-windowtitlewatcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeyfa%2Fcsharp-windowtitlewatcher/lists"}