2026年2月8日

Windows11の、右下に出てくるポップ広告を出た瞬間に消すアプリ(2)「PopSentry02.exe」

 ここで、コードを全部公開する。

プログラミングは40年も昔にN88_BASICでちょこっとやっただけなので、とても自信が無いけど、AIの力をお借りしてなんとか形になったとは思う。コード生成はAI任せだったので全くわかりません。でもちゃんと機能してるみたいですよ。



このアプリは、「PopSentry02.exe」という名前にした。POPの見張番という意味だ。

インストール不要、Windows11の適当なフォルダにコピーして、ショートカットをスタートアップにおいておくだけで、起動時に常駐する。

アプリの説明だけど、ここにWIN11機がないからスクショが取れない、よって言葉だけで説明する。

ポップが出た瞬間に感知し、表示の許可を求めてくる。重要だと思えば「はい」にすれば、同種のポップは今後も同じように表示してくる。不要なポップは「いいえ」を選べば、ブラックリストに追加され、瞬時に消され、今後一切出てきた瞬間に消去される。

という感じのアプリです。

https://github.com/sanmasystem-Jima/Popsentry02

ここで公開しました!github


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー


using Newtonsoft.Json;

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Drawing;

using System.IO;

using System.Runtime.InteropServices;

using System.Text;

using System.Threading;

using System.Windows.Forms;


namespace PopSentry

{

    internal static class Program

    {

        // WinAPI

        private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);


        [DllImport("user32.dll")]

        private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);


        [DllImport("user32.dll")]

        private static extern bool IsWindowVisible(IntPtr hWnd);


        [DllImport("user32.dll")]

        private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);


        [DllImport("user32.dll")]

        private static extern int GetWindowTextLength(IntPtr hWnd);


        [DllImport("user32.dll")]

        private static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);


        [DllImport("user32.dll")]

        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);


        [DllImport("user32.dll")]

        private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);


        private const uint WM_CLOSE = 0x0010;


        [StructLayout(LayoutKind.Sequential)]

        private struct RECT

        {

            public int Left;

            public int Top;

            public int Right;

            public int Bottom;

        }


        // 設定

        class Settings

        {

            public List<string> WhiteList { get; set; } = new List<string>();

            public List<string> BlackList { get; set; } = new List<string>();

        }


        private static Settings settings = new Settings();

        private const string SettingsFile = "popsentry.json";

        private const string LogFile = "popsentry.log";


        [STAThread]

        static void Main()

        {

            bool createdNew;

            using (var mutex = new System.Threading.Mutex(true, "PopSentryMutex", out createdNew))

            {

                if (!createdNew)

                {

                    MessageBox.Show(

                        "PopSentry はすでに起動しています。",

                        "PopSentry",

                        MessageBoxButtons.OK,

                        MessageBoxIcon.Information

                    );

                    return;

                }


                Application.EnableVisualStyles();

                Application.SetCompatibleTextRenderingDefault(false);


                LoadSettings();


                // トレイアイコン

                NotifyIcon icon = new NotifyIcon();

                icon.Icon = SystemIcons.Information;

                icon.Visible = true;

                icon.Text = "PopSentry - 稼働中";


                ContextMenuStrip menu = new ContextMenuStrip();

                menu.Items.Add("ログを開く", null, (s, e) =>

                {

                    if (File.Exists(LogFile))

                        Process.Start("notepad.exe", LogFile);

                });

                menu.Items.Add("終了", null, (s, e) =>

                {

                    icon.Visible = false;

                    Application.Exit();

                });

                icon.ContextMenuStrip = menu;


                // 監視スレッド

                Thread t = new Thread(RunLoop);

                t.IsBackground = true;

                t.Start();


                Application.Run();

            }

        }


        private static void RunLoop()

        {

            while (true)

            {

                EnumWindows(EnumWindowCallback, IntPtr.Zero);

                Thread.Sleep(300);

            }

        }


        private static bool EnumWindowCallback(IntPtr hWnd, IntPtr lParam)

        {

            if (!IsWindowVisible(hWnd))

                return true;


            int length = GetWindowTextLength(hWnd);

            if (length == 0)

                return true;


            StringBuilder sb = new StringBuilder(length + 1);

            GetWindowText(hWnd, sb, sb.Capacity);

            string title = sb.ToString();


            if (!GetWindowRect(hWnd, out RECT rect))

                return true;


            var screen = Screen.PrimaryScreen.WorkingArea;


            bool isRightBottom =

                rect.Left > screen.Right - 800 &&

                rect.Top > screen.Bottom - 800;


            if (!isRightBottom)

                return true;


            GetWindowThreadProcessId(hWnd, out uint pid);

            string procName = "unknown";


            try

            {

                using (var p = Process.GetProcessById((int)pid))

                    procName = p.ProcessName;

            }

            catch { }


            // ホワイト → 毎回ログしてスルー

            if (settings.WhiteList.Contains(procName))

            {

                LogWhite(procName, title);

                return true;

            }


            // ブラック → 毎回ログして即死

            if (settings.BlackList.Contains(procName))

            {

                LogKill(procName, title);

                SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);

                return true;

            }


            // 未登録 → ユーザーに聞く

            DialogResult result = MessageBox.Show(

                $"このポップアップを許可しますか?\n\nプロセス: {procName}\nタイトル: {title}",

                "PopSentry",

                MessageBoxButtons.YesNo,

                MessageBoxIcon.Question);


            if (result == DialogResult.Yes)

            {

                settings.WhiteList.Add(procName);

                SaveSettings();

                LogWhite(procName, title);   // 初回ログ

            }

            else

            {

                settings.BlackList.Add(procName);

                SaveSettings();

                LogKill(procName, title);    // 初回ログ

                SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);

            }


            return true;

        }


        private static void LoadSettings()

        {

            try

            {

                if (File.Exists(SettingsFile))

                {

                    string json = File.ReadAllText(SettingsFile);

                    settings = JsonConvert.DeserializeObject<Settings>(json) ?? new Settings();

                }

            }

            catch

            {

                settings = new Settings();

            }

        }


        private static void SaveSettings()

        {

            try

            {

                string json = JsonConvert.SerializeObject(settings, Formatting.Indented);

                File.WriteAllText(SettingsFile, json);

            }

            catch { }

        }


        // ホワイトログ(毎回)

        private static void LogWhite(string procName, string title)

        {

            try

            {

                string line = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} WHITE {procName} | {title}";

                File.AppendAllText(LogFile, line + Environment.NewLine);

            }

            catch { }

        }


        // ブラックログ(毎回)

        private static void LogKill(string procName, string title)

        {

            try

            {

                string line = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} KILL {procName} | {title}";

                File.AppendAllText(LogFile, line + Environment.NewLine);

            }

            catch { }

        }

    }

}

2026年2月7日

Windows11の、右下に出てくるポップ広告を出た瞬間に消すアプリを作ったよ。

 去年の10月14日に、長年使ってきたWindows10が使えなくなったのは皆様ご存知の通りです。私めの、dynabook_T75/RR2だけど、10年以上使ってきたかわいいPCが、MS帝王の意向により今後使用できなくなったわけであります。

そんな折、Ubuntuというものがあるということで、T75/RR2は延命処置を受け、ここに甦って現役で動いているわけであります。

しかし、会社で使用しているPCにおいては、W11に強制アップグレードされたのです。

長年連れ添ったおとなしいけど有能なW10と強制的にお別れさせられたと思ったら、高飛車な公爵令嬢が嫁に来た感じです。

AIさんに描画してもらったのがあるのでここに貼ってみます。(Copilot)

このお姉さんがW10だよ。静かで優しくて従順で有能だった。でも強制的にお別れさせられた。(描画:Copilot)



この人が新しい嫁さんのWIN11令嬢。
きれいだけど、能天気でおせっかいでやかましいんだよ
(描画:Gemini)


Upgradeがとんでもないダウングレードだったことに気付いたときは、もうWIN10はサポート外だったわけです。


どういうことかと、簡単に申し上げます

なんなら、日本語IMEが勝手に終わって、ローマ字モードになってる。 いちいち広告がでて集中をそがれる。その設定をいじれば消えるんじゃない?と設定をいくらいじっても、IMEの勝手な終了と広告を消し去ることはできなかった。

そういうわけで、MS帝国の出先機関であるCopilotにその旨苦情を申立たわけです。

Copilot「それは仕様です」

俺「ぷち」

何十年ぶりかに切れましたよ。

そういうわけで、WIN11の開発環境を仕入れて、ポップを物理的に出ないようにするアプリの開発に手を染めたわけであります。


・・・続く


2026年2月5日

絶対撃たれないF15のラッピングデザインしてみた

 


わたくし、この頃AIにハマっています。
とくに描画機能がお気に入りで、妄想などを形にしてもらって喜んでいます。

さて、ニュースで、航空自衛隊の戦闘機が中国海軍の戦闘機にレーダー照準されたとか言ってた。舐め腐りやがって!航空自衛隊は何もできないと信じてるんだよな。

今回はミサイル攻撃はされてはいないけど、もしもミサイルを撃ち尽くしたあとに機関砲による戦闘になったとき、中国パイロットに撃たれないための「痛戦闘機」のデザインをして、AI(Gemini)に描画してもらいました。

最期の盾になるかな?

逆に「なめんなよ」って撃たれそうだけど、一瞬躊躇くらいするよね。そのスキをついて離脱、反撃する作戦。

中国戦闘機のJ15は、F15よりきれいな機体デザインだけど、エンジンナセルの形状を絶対領域に一致させてラッピングしたとき、エンジン間隔が広すぎてガニマタになるし、真中の棒が非常にデザイン的に邪魔と言うか、放送事故を誘発する。




いくらモノマネ上手な中国人でもダメ!絶対。

航空自衛隊の優位性を発見して喜んでる。