質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

  • C#

    7714questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

数秒単位で監視し特定のウインドウを開けないようにする

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 730

mercurian-teto

score 47

数秒単位で監視し、特定のウインドウを開けないようにするプログラムを作ろうとしています。(visual studio2017で作成しています。C#コンソールアプリで作成しています。)
まず、
秒単位で一定の操作をするプログラムをベースにします
参照リンクを見てください。

これをベースに数秒単位で監視し特定のウインドウを開けないようにするプログラムを作成しようと考えました。

using何とかを追加して、

        //ここに一定時間で実行したい処理を書く
        Console\.WriteLine\("{0} Checking status {0}\.",
            DateTime\.Now\.ToString\("h:mm:ss\.fff"\)\);


ここの内容を書き換えます。

つぎに特定のウインドウが開けないようにするコードです。
例はfirefoxのアドオンマネージャーの画面
(ウインドウ名アドオンマネージャー - Mozilla Firefox)です。
プログラムは主にこのサイトを参考にしました。

下のプログラムは一応、コンパイルが通って、期待通りの操作をしました。
firefoxのアドオンマネージャーが開いているとfirefoxがまるごと
閉じられます。
また以下のコードを組み入れるときには
以下のコードのmainを別の名前に変更しなければなりません。
このリンクを参照してください。

以上のことを踏まえて作りました。

using System;
using System\.Threading;
using System\.Runtime\.InteropServices;
using System\.Text;
using System\.Diagnostics;
using System\.Collections;

class TimerExample
{
    static void Main\(\)
    {
        AutoResetEvent autoEvent = new AutoResetEvent\(false\);
        StatusChecker statusChecker = new StatusChecker\(\);

        // Create the delegate that invokes methods for the timer\.
        TimerCallback timerDelegate =
            new TimerCallback\(statusChecker\.CheckStatus\);

        // タイマー起動
        Console\.WriteLine\("{0} タイマーを起動します\.\\n",
            DateTime\.Now\.ToString\("h:mm:ss\.fff"\)\);

        Timer stateTimer =
        //最後の2つの値→初動実行までの時間,実行間隔\(ミリ秒\)
                new Timer\(timerDelegate, autoEvent, 0, 30\);

        // タイマーの待機時間は-1にすると無制限になる\(有限にしたい場合はミリ秒で記述\)
        autoEvent\.WaitOne\(-1, false\);
        //タイマーの開放
        stateTimer\.Dispose\(\);
    }
}

class StatusChecker
{
    public StatusChecker\(\)
    {
    }

    // This method is called by the timer delegate\.
    public void CheckStatus\(Object stateInfo\)
    {
        AutoResetEvent autoEvent = \(AutoResetEvent\)stateInfo;
    }

        //ここに一定時間で実行したい処理を書く
        public class Program
    {
        /// <summary>
        /// エントリポイント
        /// </summary>
        public static void  addonblock \(\)
        {
            //ウィンドウのタイトルに\[アドオンマネージャー\]を含むプロセスをすべて取得する
            Process\[\] ps = GetProcessesByWindow\("アドオンマネージャー - Mozilla Firefox", null\);

            //結果を表示する
            foreach \(Process p in ps\)
            {

                p\.Kill\(\);
            }

            Console\.WriteLine\("開いてはいけません!!!!!!!!!!!!!!"\);
            Console\.ReadLine\(\);

        }


        public static Process\[\] GetProcessesByWindow\(
            string windowText, string className\)
        {
            //検索の準備をする
            foundProcesses = new ArrayList\(\);
            foundProcessIds = new ArrayList\(\);
            searchWindowText = windowText;
            searchClassName = className;

            //ウィンドウを列挙して、対象のプロセスを探す
            EnumWindows\(new EnumWindowsDelegate\(EnumWindowCallBack\), IntPtr\.Zero\);

            //結果を返す
            return \(Process\[\]\)foundProcesses\.ToArray\(typeof\(Process\)\);
        }

        private static string searchWindowText = null;
        private static string searchClassName = null;
        private static ArrayList foundProcessIds = null;
        private static ArrayList foundProcesses = null;

        private delegate bool EnumWindowsDelegate\(IntPtr hWnd, IntPtr lparam\);

        \[DllImport\("user32\.dll"\)\]
        \[return: MarshalAs\(UnmanagedType\.Bool\)\]
        private extern static bool EnumWindows\(EnumWindowsDelegate lpEnumFunc,
            IntPtr lparam\);

        \[DllImport\("user32\.dll", CharSet = CharSet\.Auto, SetLastError = true\)\]
        private static extern int GetWindowText\(IntPtr hWnd,
            StringBuilder lpString, int nMaxCount\);

        \[DllImport\("user32\.dll", CharSet = CharSet\.Auto, SetLastError = true\)\]
        private static extern int GetWindowTextLength\(IntPtr hWnd\);

        \[DllImport\("user32\.dll", CharSet = CharSet\.Auto, SetLastError = true\)\]
        private static extern int GetClassName\(IntPtr hWnd,
            StringBuilder lpClassName, int nMaxCount\);

        \[DllImport\("user32\.dll", SetLastError = true\)\]
        private static extern int GetWindowThreadProcessId\(
            IntPtr hWnd, out int lpdwProcessId\);

        private static bool EnumWindowCallBack\(IntPtr hWnd, IntPtr lparam\)
        {
            if \(searchWindowText != null\)
            {
                //ウィンドウのタイトルの長さを取得する
                int textLen = GetWindowTextLength\(hWnd\);
                if \(textLen == 0\)
                {
                    //次のウィンドウを検索
                    return true;
                }
                //ウィンドウのタイトルを取得する
                StringBuilder tsb = new StringBuilder\(textLen \+ 1\);
                GetWindowText\(hWnd, tsb, tsb\.Capacity\);
                //タイトルに指定された文字列を含むか
                if \(tsb\.ToString\(\)\.IndexOf\(searchWindowText\) < 0\)
                {
                    //含んでいない時は、次のウィンドウを検索
                    return true;
                }
            }

            if \(searchClassName != null\)
            {
                //ウィンドウのクラス名を取得する
                StringBuilder csb = new StringBuilder\(256\);
                GetClassName\(hWnd, csb, csb\.Capacity\);
                //クラス名に指定された文字列を含むか
                if \(csb\.ToString\(\)\.IndexOf\(searchClassName\) < 0\)
                {
                    //含んでいない時は、次のウィンドウを検索
                    return true;
                }
            }

            //プロセスのIDを取得する
            int processId;
            GetWindowThreadProcessId\(hWnd, out processId\);
            //今まで見つかったプロセスでは無いことを確認する
            if \(!foundProcessIds\.Contains\(processId\)\)
            {
                foundProcessIds\.Add\(processId\);
                //プロセスIDをからProcessオブジェクトを作成する
                foundProcesses\.Add\(Process\.GetProcessById\(processId\)\);
            }

            //次のウィンドウを検索
            return true;
        }
    }
}

コード


コンパイルが通りましたが、うまく期待の操作ができません。
実行結果が
4:16:57\.367 タイマーを起動します\.
イメージ説明
と表示されたままコードが実行され続けていますが、
実行中firefoxのアドオンマネージャーの画面を開いても全く反応がありません。
(firefoxのアドオンマネージャーを開いてもfirefoxがとじられません)
だれか、解決策をご教授ください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

using System;
using System\.Diagnostics;
using System\.Threading;

namespace Close_Window
{
    class Program
    {
        static void Main\(\)
        {
            new Program\(\)\.Run\(\);
        }

        public void Run\(\)
        { 
            var timer = new Timer\(new TimerCallback\(Check_Process\)\);
            Console\.WriteLine\("{0}タイマーを起動します",
                DateTime\.Now\.ToString\("h:mm:ss\.fff"\)\);
            timer\.Change\(0, 1000\);
            for\(;;\) {}; // これがないとプログラムが終了する。
        }

        public void Check_Process\(object args\)
        {
            foreach \(var p in Process\.GetProcesses\(\)\)
                if \(p\.MainWindowTitle == "アドオンマネージャ - Mozilla Firefox"\)
                {
                    p\.CloseMainWindow\(\);
                    Console\.WriteLine\("開いてはいけません" \+ new string\('!', 14\)\);
                }                   
        }
    }
}


「アドオンマネージャ - Mozilla Firefox」という名前の
MainWindowがあるプロセスを終了させるプログラム。
ブラウザの操作ができないのでタブではなくプロセスが閉じられる。
私の環境では「アドオンマネージャー」ではなく
「アドオンマネージャ」だった。

参考:
\.NET TIPS:タイマにより一定時間間隔で処理を行うには?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/23 21:05

    for(;;) {}; // これがないとプログラムが終了する。
    の部分は「for(;;) {};」よりも「Console.ReadLine();」
    の方がCPU使用率が低い。

    キャンセル

  • 2017/09/23 21:18

    Thread.Sleep(Timeout.Infinite);を使うと
    入力があってもプログラムが終了しない
    かつCPU使用率も低い。

    キャンセル

  • 2017/09/23 22:53

    回答してすぐ退会してまた入会してコメントして退会して
    最近こういうことを繰り返してますが何か理由があるのですか?

    キャンセル

  • 2017/09/24 01:16

    回答ありがとうございます!!!期待のアプリが作成できました。
    結局、退会済みユーザーさんにほとんど任せてしまう形になってしまいましたが、
    zuishinさんのアドバイスを参考にして自分のプログラムも見直したいと思います。
    皆さん回答ありがとうございました。

    キャンセル

0

addonblock がどこからも呼ばれていないように見えます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C#

    7714questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。