- PR -

認証ダイアログの自動入力について

1
投稿者投稿内容
なな
会議室デビュー日: 2005/10/12
投稿数: 13
投稿日時: 2006-03-01 10:51
ブラウザを利用しているときに認証を要求してくるダイアログ(例:タイトルが192.168.xx.xxに接続)に対して、
登録したアカウント情報を自動で入力してくれるアプリをC#で作成したいと思っています。
(多人数で使用するPCで使用する想定なので、ダイアログにあるパスワードを記憶する機能を使用しない仕様です)

既存ソフトの動作をみてみると、goo IDメモリーやロボフォームなどでは、
認証ダイアログの自身情報と書き込まれた情報を記憶しているということを確認しました。

そこで、同じ動作を実現したいのですが、
1:認証ダイアログの情報(大きさ、テキストボックスの位置、タイトルなど)はどのように取得できるのでしょうか?
2:認証ダイアログへのアカウント情報の送信はどのようにすれば実現できるのでしょうか?
3:認証ダイアログが出現したことを意味するイベントはどのようなものがあがってくるのでしょうか?

1に関しては、見当もつきません。WindowsAPIなどがあるのでしょうか?

2に関しては、認証ダイアログが統一されていると思うので、
ID文字 + Tab + Password文字 + Tab + Tab + SpaceKeyで一応は動作できると思いますが、
この場合だと、認証ダイアログのフォーカスが外れてしまった場合はうまく入力できないように思います。
確実に入力できる方法はどのような手段が考えられるのでしょうか?これもWindowsAPIなどがあるのでしょうか?

よろしくお願いいたします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-03-01 19:14
 Windows の場合、すべてメッセージのやりとりで処理されています。ウインドウだのなんだのは、人間の目に訴えるためのものであって、コンピュータ自身には関係ないですよね。
 なので、メッセージを盗聴します。ある ID のコントロールを作れというメッセージが流れたら、そのフォームが表示されたと判断します。
 キー入力もメッセージです。同じように、ある ID のコントロールに対して、こういうキー入力があったというメッセージを送ります。

 具体的にどの様なメッセージに対して反応するかは、spy++ を起動して、追跡します。

 今の段階では、手を付けない方が無難な領域かと思います。
k_kazu
常連さん
会議室デビュー日: 2006/02/11
投稿数: 25
投稿日時: 2006-03-02 17:45
以下のコードで目的の処理が実現できると思います。
ためしてみてください。プログラム中にあるコントロールIDは Spy++ で調べました。

コード:
using System.Runtime.InteropServices;

        [DllImport("user32.dll", EntryPoint = "FindWindowA")]
        static extern IntPtr FindWindow(string lpszClass, string lpszWindow);
        
        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

        [DllImport("user32.dll")]
        static extern IntPtr GetDlgItem(IntPtr hWnd, int nIDDlgItem);

        const int WM_SETTEXT = 0x000c;
        const int BM_CLICK = 0x00F5; // ボタンのクリック

        string param_UserName = "user";
        string param_Password = "pass";

        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr hWnd1 = FindWindow("#32770", "192.168.xx.xx に接続");
            if (hWnd1 != IntPtr.Zero)
            {
                // ユーザ名に値を設定する(コントロールID 3EA の 中の3EB)
                IntPtr hWndDlg = GetDlgItem(hWnd1, 0x03EA);
                if (hWndDlg == IntPtr.Zero) return;
                IntPtr hWnd4 = GetDlgItem(hWndDlg, 0x3EB);
                if (hWnd4 == IntPtr.Zero) return;

                SendMessage(hWnd4, WM_SETTEXT, 0, Marshal.StringToHGlobalAnsi(param_UserName));

                // パスワードに値を設定する(コントロールID 3EA の 中の3ED)
                IntPtr hWnd2 = GetDlgItem(hWndDlg, 0x03ED);
                if (hWnd2 == IntPtr.Zero) return;
                SendMessage(hWnd2, WM_SETTEXT, 0, Marshal.StringToHGlobalAnsi(param_Password));

                // 「OK」ボタンをクリックする。(コントロールID 001)
                IntPtr hWnd3 = GetDlgItem(hWnd1, 0x0001);
                if (hWnd3 != IntPtr.Zero)
                {
                    SendMessage(hWnd3, BM_CLICK, 0, 0);
                }
            }

なな
会議室デビュー日: 2005/10/12
投稿数: 13
投稿日時: 2006-03-03 09:54
Jittaさん、k_kazuさんありがとうございます。
お返事遅れてすみませんでした。

今、レスを見たばかりなのでこれから試してみて、
結果を報告いたします。
もしかしたらその途中で疑問点が出てきて質問するかもしれませんが
そのときは皆様よろしくお願いいたします。
なな
会議室デビュー日: 2005/10/12
投稿数: 13
投稿日時: 2006-04-04 21:05
k_kazuさんのコードを試した結果うまく入力ができました。
ありがとうございます。

現在、これまでの作業の逆=入力をはきだすことを試している最中です。
(入力値を個別に記憶させるために、ダイアログの入力値を利用したい)

ユーザ名やタイトルは取得することはできたのですが、
パスワードは取得できませんでした。
セキュリティ上、禁止されているのかもしれませんが、
パスワードのEditコントロールに入力されている文字の取得する方法はあるのでしょうか?

ちなみに、はきだし方法は(ソース一部引用)
StringBuilder sb1 = new StringBuilder(0x1000);

SendMessage(hWnd1, WM_GETTEXT, 255, sb1);
this.label1.Text = sb1.ToString();

// ユーザ名に値を設定する(コントロールID 3EA の 中の3EB)
IntPtr hWndDlg = GetDlgItem(hWnd1, 0x03EA);
if (hWndDlg == IntPtr.Zero) return;
IntPtr hWnd4 = GetDlgItem(hWndDlg, 0x3EB);
if (hWnd4 == IntPtr.Zero) return;

SendMessage(hWnd4, WM_GETTEXT, 255, sb1);
this.label2.Text = sb1.ToString();

// パスワードに値を設定する(コントロールID 3EA の 中の3ED)
IntPtr hWnd2 = GetDlgItem(hWndDlg, 0x03ED);
if (hWnd2 == IntPtr.Zero) return;

SendMessage(hWnd2, WM_GETTEXT, 255, sb1);
this.label3.Text = sb1.ToString();

label1,label2は入力値が表示されましたが、label3は表示されませんでした。
また、Spy++でも見てみましたが、パスワードの項目は空になっていました。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-04-04 21:26
引用:

ななさんの書き込み (2006-04-04 21:05) より:
ユーザ名やタイトルは取得することはできたのですが、
パスワードは取得できませんでした。
セキュリティ上、禁止されているのかもしれませんが、
パスワードのEditコントロールに入力されている文字の取得する方法はあるのでしょうか?


こちらの掲示板の過去のスレッドに話題があったような気がします。何番だったかは思い出せませんが。WM_GETTEXT あたりをキーワードにして検索したらヒットするかな、と思ったのですが、違いました。
なお、そのときに読んだ記憶では Windows XP や 2000 などでは、ご推察のとおりセキュリティーの制限のため無理だったと思います。セキュリティーの仕組みが違う Windows 98 などだったら取得できたかもしれません。もっとも現在ならば、OS の種類に関わらず取得はできないものとしてアプリケーションを作ったほうがよいでしょう。
ちなみにぜんぜん別のソリューションとして最近ふと思い付いたのは、プロキシーや Web サーバーを作ってその中で HTTP ヘッダーの中の基本認証の情報を「盗む」ことや付け加えることをするという手もあるかもしれません。これだとブラウザーの種類によらずにできます。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-04-04 22:00
引用:

unibonさんの書き込み (2006-04-04 21:26) より:

こちらの掲示板の過去のスレッドに話題があったような気がします。何番だったかは思い出せませんが。WM_GETTEXT あたりをキーワードにして検索したらヒットするかな、と思ったのですが、違いました。


この記事じゃないかな?
http://www.atmarkit.co.jp/fnetwork/rensai/netool05/asterisklogger02.html
1

スキルアップ/キャリアアップ(JOB@IT)