2012年8月15日水曜日

npmでエラー、proxyとかregistryらしい

npm ERR! Error: getaddrinfo ENOENT
npm ERR!     at errnoException (dns.js:31:11)
npm ERR!     at Object.onanswer [as oncomplete] (dns.js:123:16)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <npm-@googlegroups.com>
    :
以下のコマンドを実行する
$ npm set proxy http://proxyHost:proxyPort
$ npm config set registry http://registry.npmjs.org/

2012年8月13日月曜日

今度はnode.jsらしい

node.jsのv0.8.6をCentOS 5.xに入れようとしたら./configureでline 325あたりがエラー。python2.6が必要らしいのでyum searchしたら見つからなかった。なので以下を上から順にインストール。
そのあとpython26をインストール。
yum -y install python26
うまくいったら/usr/bin/pythonがpython24のままなので、/usr/bin/pythonを置き換える
cp /usr/bin/python26 /usr/bin/python
これ大丈夫なの?って気がするけど仮想環境だしそのまま放置して、./configure, make, make install。とりあえずインストールは完了した。

2012/08/21 追記:上記方法でpythonを上書きしてしまうとyumが動作しなくなった orz

2012年7月9日月曜日

Oracle TuxedoのATMIサンプルをネットワーク環境で動かす

Oracle Tuxedo ダウンロードからtuxedo111120_32_win_xp_x86_VS2010_client.exeをダウンロードして、クライアントマシンにインストールしておく。サーバー側のインストールと同じくOracleホームを聞かれるので、適当に。OracleホームをC:\oracle\productにすると、C:\oracle\product\tuxedo11gR1_VS2010にインストールされる。

サーバー側の設定を変更する。
  • サーバーのIPアドレスは192.168.30.128
  • サーバーのポート番号は5000を開けておく
  • NETWORKセクションはまだ使わないけどtmloadcfがエラーになるのでとりあえず設定する
[tuxedo@centos atmi]$ vi ubbsimple
#       (c) 2003 BEA Systems, Inc. All Rights Reserved.
#ident  "@(#) samples/atmi/simpapp/ubbsimple    $Revision: 1.7 $"

#Skeleton UBBCONFIG file for the TUXEDO Simple Application.
#Replace the  items with the appropriate values.

*RESOURCES
IPCKEY          123456

#Example:
#IPCKEY         123456

DOMAINID        simpapp
MASTER          simple
MAXACCESSERS    10
MAXSERVERS      50
MAXSERVICES     100
MODEL           MP
LDBAL           N
OPTIONS         LAN

*MACHINES
DEFAULT:
                APPDIR="/home/tuxedo/atmi"
                TUXCONFIG="/home/tuxedo/atmi/tuxconfig"
                TUXDIR="/home/tuxedo/tuxedo11gR1"
                MAXACCESSERS=100
                MAXWSCLIENTS=50
#Example:
#               APPDIR="/home/me/simpapp"
#               TUXCONFIG="/home/me/simpapp/tuxconfig"
#               TUXDIR="/usr/tuxedo"

centos          LMID=simple

#Example:
#beatux         LMID=simple

*GROUPS
GROUP1
                LMID=simple     GRPNO=1 OPENINFO=NONE

*NETWORK
simple          NADDR="//192.168.30.128:5001"
                NLSADDR="//192.168.30.128:5002"

*SERVERS
DEFAULT:
                CLOPT="-A"

simpserv        SRVGRP=GROUP1 SRVID=1
"WSL"           SRVGRP=GROUP1 SRVID=2
                CLOPT="-A -- -n //192.168.30.128:5000"

*SERVICES
TOUPPER

設定ファイルをバイナリ変換しなおして起動する。tlistenを起動してないので警告が出るけど今は無視。
[tuxedo@centos atmi]$ tmloadcf -y ubbsimple
[tuxedo@centos atmi]$ tmboot -y
Booting all admin and server processes in /home/tuxedo/atmi/tuxconfig
INFO: Oracle Tuxedo, Version 11.1.1.2.0, 32-bit, Patch Level (none)
CMDTUX_CAT:1483: WARN: can't contact local tlisten process

Booting admin processes ...

exec DBBL -A :
        on simple -> process id=19752 ... Started.
exec BBL -A :
        on simple -> process id=19755 ... Started.

Booting server processes ...

exec simpserv -A :
        on simple -> process id=19758 ... Started.
exec WSL -A -- -n //192.168.30.128:5000 :
        on simple -> process id=19759 ... Started.
4 processes started.
[tuxedo@centos atmi]$ 
ここからクライアント側(Windows)
環境変数を設定する。
set TUXDIR=C:\oracle\product\tuxedo11gR1_VS2010
set PATH=%PATH%;%TUXDIR%\bin
set LIB=%LIB%;%TUXDIR%\lib
set INCLUDE=%INCLUDE%;%TUXDIR%\include
set WSNADDR=//192.168.30.128:5000
コードを組む。参照設定に%TUXDIR%\bin\libwscdnet.dllを追加しておくこと。(Visual Basic Expressの場合)
Imports Bea.Tuxedo.ATMI

Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim sndstr, rcvstr As TypedString
        Dim ac As AppContext = Nothing
        Dim info As New TypedTPINIT()

        info.flags = TypedTPINIT.TPMULTICONTEXTS
        'info.cltname = "vb client"

        Try
            ac = AppContext.tpinit(info)
            sndstr = New TypedString("hello world")
            rcvstr = New TypedString(1000)

            ac.tpcall("TOUPPER", sndstr, rcvstr, 0)

            Console.WriteLine("rcvstr = {0}", rcvstr.GetString(0, 1000))
        Catch ex As ApplicationException
            Console.WriteLine("Got Exception = {0}", ex)
        Finally
            If Not ac Is Nothing Then
                ac.tpterm()
            End If
        End Try
    End Sub
End Class
起動してButton1を押すとコンソールに以下が出力される
rcvstr = HELLO WORLD
おまけ
MAXSERVERS、MAXSERVICESの値が小さいと、サーバー起動時にエラーが出ます。
[tuxedo@centos atmi]$ tmboot -y
Booting all admin and server processes in /home/tuxedo/atmi/tuxconfig
INFO: Oracle Tuxedo, Version 11.1.1.2.0, 32-bit, Patch Level (none)
CMDTUX_CAT:1483: WARN: can't contact local tlisten process

Booting admin processes ...

exec DBBL -A :
        on simple -> process id=20199 ... Started.
exec BBL -A :
        on simple -> process id=20202 ... Started.

Booting server processes ...

exec simpserv -A :
        on simple -> Failed.
exec WSL -A -- -n //192.168.30.128:5000 :
        on simple -> process id=20207 ... Started.
3 processes started.
[tuxedo@centos atmi]$
$APPDIR/ULOG.mmddyyを見るとこんな感じのエラーが出る。
161413.centos!tmboot.20198.3086485184.-2: 07-09-2012: Tuxedo Version 11.1.1.2.0, 32-bit
161413.centos!tmboot.20198.3086485184.-2: CMDTUX_CAT:1578: ERROR: Could not contact NLS on simple
161413.centos!tmboot.20198.3086485184.-2: CMDTUX_CAT:1576: ERROR: No NLS available for remote machine simple
161415.centos!DBBL.20199.3086223040.0: 07-09-2012: Tuxedo Version 11.1.1.2.0, 32-bit
161415.centos!DBBL.20199.3086223040.0: LIBTUX_CAT:262: INFO: Standard main starting
161417.centos!DBBL.20199.3086223040.0: CMDTUX_CAT:4350: INFO: BBL started on simple - Release 11112
161417.centos!BBL.20202.3086956224.0: 07-09-2012: Tuxedo Version 11.1.1.2.0, 32-bit, Patch Level (none)
161417.centos!BBL.20202.3086956224.0: LIBTUX_CAT:262: INFO: Standard main starting
161417.centos!BRIDGE.20205.3086526144.0: 07-09-2012: Tuxedo Version 11.1.1.2.0, 32-bit
161417.centos!BRIDGE.20205.3086526144.0: LIBTUX_CAT:262: INFO: Standard main starting
161417.centos!BRIDGE.20205.3086526144.0: LIBTMIB_CAT:74: ERROR: Failed to advertise dynamic /Admin service _TBR_0
161417.centos!BRIDGE.20205.3086526144.0: CMDTUX_CAT:1788: WARN: Could not advertise administrative service
161418.centos!DBBL.20199.3086223040.0: LIBTUX_CAT:328: ERROR: No space in Bulletin Board for Service Table
161418.centos!simpserv.20206.3086805200.0: 07-09-2012: Tuxedo Version 11.1.1.2.0, 32-bit
161418.centos!simpserv.20206.3086805200.0: LIBTUX_CAT:248: ERROR: System init function failed, Uunixerr = 
161418.centos!tmboot.20198.3086485184.-2: CMDTUX_CAT:825: ERROR: Process simpserv at simple failed with /T tperrno (TPENOENT - no entry found)
161418.centos!WSL.20207.3086792384.0: 07-09-2012: Tuxedo Version 11.1.1.2.0, 32-bit
161418.centos!WSL.20207.3086792384.0: LIBTUX_CAT:262: INFO: Standard main starting

Oracle TuxedoのATMIサンプルをローカル環境で動かす

インストール後の作業の手順通りです。
まずはtuxedo11gR1/tux.envの内容を実行して環境変数を設定する。
[tuxedo@centos ~]$ TUXDIR=/home/tuxedo/tuxedo11gR1; export TUXDIR
[tuxedo@centos ~]$ JAVA_HOME=$TUXDIR/jre; export JAVA_HOME
[tuxedo@centos ~]$ JVMLIBS=$JAVA_HOME/lib/i386/server:$JAVA_HOME/jre/bin
[tuxedo@centos ~]$ PATH=$TUXDIR/bin:$JAVA_HOME/bin:$PATH; export PATH
[tuxedo@centos ~]$ COBCPY=:$TUXDIR/cobinclude; export COBCPY
[tuxedo@centos ~]$ COBOPT="-C ANS85 -C ALIGN=8 -C NOIBMCOMP -C TRUNC=ANSI -C OSEXT=cbl"; export COBOPT
[tuxedo@centos ~]$ SHLIB_PATH=$TUXDIR/lib:$JVMLIBS:$SHLIB_PATH; export SHLIB_PATH
[tuxedo@centos ~]$ LIBPATH=$TUXDIR/lib:$JVMLIBS:$LIBPATH; export LIBPATH
[tuxedo@centos ~]$ LD_LIBRARY_PATH=$TUXDIR/lib:$JVMLIBS:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH
[tuxedo@centos ~]$ WEBJAVADIR=$TUXDIR/udataobj/webgui/java; export WEBJAVADIR
サンプルアプリをコピーしてアプリ用の環境変数を設定する。
[tuxedo@centos ~]$ mkdir atmi
[tuxedo@centos ~]$ cd atmi
[tuxedo@centos atmi]$ cp $TUXDIR/samples/atmi/simpapp/* .
[tuxedo@centos atmi]$ APPDIR=/home/tuxedo/atmi
[tuxedo@centos atmi]$ TUXCONFIG=$APPDIR/tuxconfig
[tuxedo@centos atmi]$ export APPDIR TUXCONFIG
サーバーアプリとクライアントアプリを作成する。警告が出るけどスルーします。たぶんstdlibのインクルードがなさげ。
[tuxedo@centos atmi]$ buildclient -o simpcl -f simpcl.c 
simpcl.c: In function ‘main’:
simpcl.c:34: 警告: incompatible implicit declaration of built-in function ‘exit’
simpcl.c:40: 警告: incompatible implicit declaration of built-in function ‘exit’
simpcl.c:43: 警告: incompatible implicit declaration of built-in function ‘strlen’
simpcl.c:50: 警告: incompatible implicit declaration of built-in function ‘exit’
simpcl.c:57: 警告: incompatible implicit declaration of built-in function ‘exit’
simpcl.c:60: 警告: incompatible implicit declaration of built-in function ‘strcpy’
simpcl.c:71: 警告: incompatible implicit declaration of built-in function ‘exit’
[tuxedo@centos atmi]$ buildserver -o simpserv -f simpserv.c -s TOUPPER
$APPDIR/ubbsimpleを編集する。マシン名のところ(centosの部分)は'uname -n'の実行結果を設定すること。
[tuxedo@centos atmi]$ vi ubbsimple 
#       (c) 2003 BEA Systems, Inc. All Rights Reserved.
#ident  "@(#) samples/atmi/simpapp/ubbsimple    $Revision: 1.7 $"

#Skeleton UBBCONFIG file for the TUXEDO Simple Application.
#Replace the  items with the appropriate values.

*RESOURCES
IPCKEY          123456

#Example:
#IPCKEY         123456

DOMAINID        simpapp
MASTER          simple
MAXACCESSERS    10
MAXSERVERS      5
MAXSERVICES     10
MODEL           SHM
LDBAL           N

*MACHINES
DEFAULT:
                APPDIR="/home/tuxedo/atmi"
                TUXCONFIG="/home/tuxedo/atmi/tuxconfig"
                TUXDIR="/home/tuxedo/tuxedo11gR1"
#Example:
#               APPDIR="/home/me/simpapp"
#               TUXCONFIG="/home/me/simpapp/tuxconfig"
#               TUXDIR="/usr/tuxedo"

centos          LMID=simple

#Example:
#beatux         LMID=simple

*GROUPS
GROUP1
        LMID=simple     GRPNO=1 OPENINFO=NONE

*SERVERS
DEFAULT:
                CLOPT="-A"

simpserv        SRVGRP=GROUP1 SRVID=1

*SERVICES
TOUPPER

設定ファイルをバイナリ変換してサーバーを起動する。
[tuxedo@centos atmi]$ tmloadcf -y ubbsimple 
[tuxedo@centos atmi]$ tmboot -y
Booting all admin and server processes in /home/tuxedo/atmi/tuxconfig
INFO: Oracle Tuxedo, Version 11.1.1.2.0, 32-bit, Patch Level (none)

Booting admin processes ...

exec BBL -A :
        process id=13381 ... Started.

Booting server processes ...

exec simpserv -A :
        process id=13384 ... Started.
2 processes started.
クライアントアプリを起動して動作確認する。
[tuxedo@centos atmi]$ ./simpcl "hello world"
Returned string is: HELLO WORLD
[tuxedo@centos atmi]$ 
サーバーを停止する。
[tuxedo@centos atmi]$ tmshutdown -y
Shutting down all admin and server processes in /home/tuxedo/atmi/tuxconfig

Shutting down server processes ...

        Server Id = 1 Group Id = GROUP1 Machine = simple:       shutdown succeeded

Shutting down admin processes ...

        Server Id = 0 Group Id = simple Machine = simple:       shutdown succeeded
2 processes stopped.
[tuxedo@centos atmi]$ 

2012年7月6日金曜日

Oracle Tuxedoをアンインストール

[rossy@centos tuxedo]$ cd tuxedo11gR1/uninstaller/
[rossy@centos uninstaller]$ ./Uninstall_Tuxedo_11.1.1.2.0
Preparing CONSOLE Mode Installation...

===============================================================================
Tuxedo 11.1.1.2.0                 (created with InstallAnywhere by Macrovision)
-------------------------------------------------------------------------------




===============================================================================
Tuxedo 11.1.1.2.0のアンインストール
--------------------------

アンインストールしようとしています...



Tuxedo 11.1.1.2.0



ここでは、InstallAnywhereによってインストールされた機能が削除されます。インストール後に作成されたファイルおよびフォルダは削除されません。

続行するには  キーを押します。: 



===============================================================================
アンインストールのオプション
--------------

ENTER THE NUMBER FOR YOUR CHOICE, OR PRESS  TO ACCEPT THE DEFAULT:

  ->1- すべての機能とコンポーネントをすべて削除します。
    2- InstallAnywhereによってインストールされた特定の機能を選択してください。

次のいずれかのオプションを選択してください: 1



===============================================================================
アンインストール中...
------------


...*
*
*************************
*************************
*************************
************************
...*
*
*************************
*************************
*************************
************************
...*
*
*************************
*************************
*************************
************************
...*
*
*************************
*************************
*************************
*************************



===============================================================================
アンインストールの完了
-----------

すべての項目が正常にアンインストールされました。

[rossy@centos uninstaller]$

CentOS 5.xにOracle Tuxedoをインストール

Oracle Tuxedo ダウンロードからtuxedo111120_32_Linux_01_x86.binをダウンロードする。で、UNIXシステム上でのOracle Tuxedoのコンソール・モード・インストールを見ればインストールできる。

[rossy@centos ~]$ su
パスワード:
[root@centos rossy]$ sh tuxedo111120_32_Linux_01_x86.bin -i console
Preparing to install...
Extracting the JRE from the installer archive...
Unpacking the JRE...
Extracting the installation resources from the installer archive...
Configuring the installer for this system's environment...

Launching installer...

Preparing CONSOLE Mode Installation...

===============================================================================
Choose Locale...
----------------

    1- English
  ->2- 日本語

CHOOSE LOCALE BY NUMBER: 2
===============================================================================
Tuxedo 11.1.1.2.0                 (created with InstallAnywhere by Macrovision)
-------------------------------------------------------------------------------




===============================================================================
概要
--

InstallAnywhereの指示に従うとTuxedo 11.1.1.2.0をインストールできます。



このインストールを続行する前に、すべてのプログラムを終了することを強くお薦めします。

次の画面に進むには、"next'と入力します。前の画面の内容を変更する場合は、"back"と入力します。

"quit"と入力すると、このインストールをいつでも取り消せます。



WARNING: "終了"すると、Tuxedo 11.1.1.2.0のインストールが不完全になります。この場合Tuxedo 
11.1.1.2.0を再インストールする必要があります。詳細は、Tuxedo 11.1.1.2.0のインストール・ガイドで「Oracle 
Tuxedoシステムのインストール前の作業」を参照してください。





続行するには  キーを押します。: 



===============================================================================
インストール・セットの選択
-------------

このインストーラでインストールするインストール セットを選択してください。

  ->1- 完全インストール
    2- サーバーのインストール
    3- 完全クライアント・インストール
    4- Joltクライアントのインストール
    5- ATMIクライアントのインストール
    6- CORBAクライアントのインストール

    7- カスタマイズ...

インストール セットの番号を入力するか、デフォルトを使用する場合は  キーを押してください。
      : 2



===============================================================================
Oracleホームの選択
------------


    1- 新しいOracleホームを作成します

数字を入力してください: 1
新しいOracleホーム・ディレクトリを指定してください: /home/tuxedo



===============================================================================
製品ディレクトリの選択
-----------


    1- 現在の選択を変更します(/home/tuxedo/tuxedo11gR1)
    2- 現在の選択を使用します(/home/tuxedo/tuxedo11gR1)

数字を入力してください: 2
サンプルのインストール (Y/N): Y



===============================================================================
インストール前の概要
----------

続行する前に次の内容を確認してください:

製品名:
    Tuxedo 11.1.1.2.0

インストール フォルダ:
    /home/tuxedo/tuxedo11gR1

リンク フォルダ:
    /root

ディスク容量情報 (インストール先): 
    必要なディスク容量:  209,943,511 バイト
    使用可能なディスク容量: 69,824,200,704 バイト

続行するには  キーを押します。: 


===============================================================================
インストールの準備
---------

InstallAnywhereはシステムの次の場所にTuxedo 11.1.1.2.0をインストールする準備が整いました:



   /home/tuxedo/tuxedo11gR1

インストールするには  キーを押してください。: 



===============================================================================
インストール中...
----------

 [==================|==================|==================|==================]
 [------------------|------------------|------------------|------------------]



===============================================================================
tlistenサービスの構成
--------------

パスワード:          
パスワードの確認:          
パスワードが受理されました。お待ちください...



===============================================================================
SSLインストールの選択。
-------------

SSLをサポートをインストールしますか。

  ->1- はい
    2- いいえ

選択する項目の番号を入力するか、デフォルトを使用する場合は <ENTER> キーを押してください。: 2




===============================================================================
インストール完了
--------

おめでとうございます。Tuxedo 11.1.1.2.0は次の場所に正常にインストールされました:



   /home/tuxedo/tuxedo11gR1

 キーを押すと、インストーラが終了します。: 
あとユーザを追加しておく
[root@centos ~]# groupadd tuxedo
[root@centos ~]# useradd -g tuxedo -m tuxedo
[root@centos ~]# chown -R tuxedo:tuxedo /home/tuxedo

途中でOracleホームの場所を聞かれるが、今回はOracleデータベースは入れてないので適当に/home/tuxedoにした。これでもサンプルは動作するので問題なさそう。

ここからが問題で、そっからの文書がとにかく読みにくい。

とにかくどこに何が書いてあるか分からないので自分用リンク。

2012年7月4日水曜日

VB.NETで非アクティブなウィンドウをスムーズに移動できた

VB.NETで非アクティブなウィンドウをスムーズに移動したいのコードを下記に変更した。これなら再フォーカスの問題は発生しない。
Public Class Form1

    :

    Private Structure RECT
        Public Left As Integer
        Public Top As Integer
        Public Right As Integer
        Public Bottom As Integer
    End Structure

    Private Const WM_MOVING As Integer = &H216

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case WM_MOVING
                Dim rect As RECT = Marshal.PtrToStructure(m.LParam, GetType(RECT))
                SetWindowPos(Me.Handle, HWND_TOPMOST, rect.Left, rect.Top, 0, 0, _
                             SWP_SHOWWINDOW Or SWP_NOSIZE)
            Case Else
        End Select
        MyBase.WndProc(m)
    End Sub


2012年7月3日火曜日

VB.NETで非アクティブなウィンドウをスムーズに移動したい

VB.NETで非アクティブで常に手前に表示したいで作ったウィンドウを非アクティブな状態で移動すると、移動が終わってからしか描画されないっぽい。アクティブじゃないから?とりあえず移動時だけアクティブにしてあげてみる。
Public Class Form1

    :

    Declare Function GetForegroundWindow Lib "user32" () As IntPtr
    Declare Function SetForegroundWindow Lib "user32" (hWnd As IntPtr) As Boolean

    Private Const WM_NCLBUTTONDOWN As Integer = &HA1
    Private Const WM_NCLBUTTONUP As Integer = &HA0

    Private m_hForegroundWnd As IntPtr = IntPtr.Zero

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case WM_NCLBUTTONDOWN
                If m_hForegroundWnd = IntPtr.Zero Then
                    m_hForegroundWnd = GetForegroundWindow
                    SetForegroundWindow(Me.Handle)
                End If
            Case WM_NCLBUTTONUP
                If m_hForegroundWnd <> IntPtr.Zero Then
                    SetForegroundWindow(m_hForegroundWnd)
                    m_hForegroundWnd = IntPtr.Zero
                End If
        End Select
        MyBase.WndProc(m)
    End Sub


けどこれだと、前面にいたウィンドウが再フォーカスされることになるからどうかなぁ。例えばIE9のURL部分は一度フォーカス外して再フォーカスすると全選択になるし。

2012年6月27日水曜日

VB.NETで非アクティブで常に手前に表示したい

スクリーンキーボード作りたいから

Windows アプリケーションの作成を参考にしてたけどそのままだとPInvoke~とか言われる。SetWindowPosとかのhWndとかの型が違うので直したげると動いた。

Imports System.Runtime.InteropServices
Public Class Form1

    Public Const HWND_TOPMOST = (-1)
    Public Const SWP_SHOWWINDOW = &H40&
    Public Const SWP_NOSIZE = &H1&
    Public Const SWP_NOMOVE = &H2&

    Public Const WS_EX_NOACTIVATE = &H8000000
    Public Const GWL_EXSTYLE As Long = (-20)

    <DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, _
        ByVal hWndInsertAfter As IntPtr, _
        ByVal X As Integer, _
        ByVal Y As Integer, _
        ByVal cx As Integer, _
        ByVal cy As Integer, _
        ByVal uFlags As UInteger) As Boolean
    End Function

    <DllImport("user32.dll")> _
    Private Shared Function SetWindowLong(hWnd As IntPtr, _
        <MarshalAs(UnmanagedType.I4)> nIndex As Integer, _
        dwNewLong As IntPtr) As Integer
    End Function

    <DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function GetWindowLong(hWnd As IntPtr, _
        <MarshalAs(UnmanagedType.I4)> nIndex As Integer) As Integer
    End Function

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim p As CreateParams = MyBase.CreateParams
            If Not MyBase.DesignMode Then
                p.ExStyle = p.ExStyle Or (WS_EX_NOACTIVATE)
            End If
            Return p
        End Get
    End Property

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim lngRet As Long = SetWindowPos(Me.Handle, HWND_TOPMOST, 0, 0, 0, 0, _
            SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE)
        Call SetWindowLong(Me.Handle, GWL_EXSTYLE, GetWindowLong(Me.Handle, GWL_EXSTYLE) Or WS_EX_NOACTIVATE)
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles ButtonEx1.Click
        SendKey(Keys.A)
    End Sub

End Class

2012年6月25日月曜日

Grails + CAS、CASクライアント編

Acegiプラグインを使ってCASでSSOします。

まず、Grails + CAS、CASサーバ編で作成したユーザ管理アプリをCASクライアントにしてみる。

ユーザ管理アプリのgrails-app/conf/SecurityConfig.groovyに以下の内容を追加する。

// CAS
useCAS = true // false
cas.casServer = 'localhost'
cas.casServerPort = '8080' // '443'
cas.casServerSecure = false // true
cas.localhostSecure = false // true
cas.failureURL = '/index.gsp' // '/denied.jsp'
cas.defaultTargetURL = '/'
cas.fullLoginURL = 'http://localhost:8080/cas/login' // 'https://localhost:443/cas/login'
cas.fullServiceURL = 'http://localhost:8080/cas' // 'https://localhost:443/cas'
cas.authenticationProviderKey = 'cas_key_changeme'
cas.userDetailsService = 'userDetailsService'
cas.sendRenew = false
cas.proxyReceptorUrl = '/' // '/secure/receptor'
cas.filterProcessesUrl = '/j_spring_cas_security_check'

コメントアウトはDefaultSecurityConfig.groovyの設定。
cas.failureURLはdenied.jspを用意するのが面倒なので。
cas.proxyReceptorUrlはCASサーバがリクエストしてくるので'/'に変更。'/secure/receptor'のままだとCASサーバ側でエラーが発生してしまい、Single Sign OutができなくなったSpring SourceのCASサンプルが'/secure/receptor'に設定してるから?

あとはweb.xmlにSingleSignOutフィルタを書く。

grails install-templates

<filter>
   <filter-name>CAS Single Sign Out Filter</filter-name>
   <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>

<filter-mapping>
   <filter-name>CAS Single Sign Out Filter</filter-name>
   <url-pattern>/j_spring_cas_security_check</url-pattern>
</filter-mapping>

<listener>
   <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>

これでOK。
認証が必要なページに遷移するとCASのログイン画面が表示される。ログインすると、Spring Security的にもログインする。ログアウトはCASのログアウトリクエストを送る必要がある。そうしないと、Cookieに情報が残ったままになるので

CASの仕組みについてはcas-server-coreの処理を読めばだいたい分かるのでそちらを見てください。ちなみによく見たクラスは以下。
  • CentralAuthenticationServiceImpl
  • TicketGrantingTicketImpl
  • ServiceTicketImpl


そろそろサンプルをどこかにおきたい。次回はCASサーバが接続するデータベースとCASクライアントのアプリが接続するデータベースが異なる場合についてまとめる。

VB.NETでスクリーンロックしてスクリーンセーバー起動

Imports System.Runtime.InteropServices

Public Class ScreenLockForm
    <DllImport("user32.dll")> _
    Public Shared Function LockWorkStation() As Long
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function SendMessage(ByVal hWnd As IntPtr, _
          ByVal uMsg As Int32, _
          ByVal wParam As Int32, _
          ByVal lParam As Int32) As Int32
    End Function

    Private Const WM_SYSCOMMAND As Int32 = &H112
    Private Const SC_SCREENSAVE As Int32 = &HF140

    Private Sub Lock_Button_Click(sender As System.Object, e As System.EventArgs) _
        Handles Lock_Button.Click
        LockWorkStation()
        SendMessage(Me.Handle, WM_SYSCOMMAND, SC_SCREENSAVE, 0)
        Close()
    End Sub
End Class

VB.NETでCSV読まないといけなくなった

どうやってやるのがいいの?

社員のモデル
Public Class Syain
    '社員コード
    Private mCode As String
    '社員氏名
    Private mName As String

    Public Property Code As String
        Get
            Code = mCode
        End Get
        Set(value As String)
            mCode = value
        End Set
    End Property

    Public Property Name As String
        Get
            Name = mName
        End Get
        Set(value As String)
            mName = value
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return "code: " & mCode & ", name: " & mName
    End Function

End Class

社員のMapper
Public Class SyainMapper
    Inherits CsvMapper

    'カラム名とプロパティ名のマッピング
    Private Shared MAPPINGS As New SortedDictionary(Of String, String) From { _
            {"社員コード", "Code"}, _
            {"社員氏名", "Name"}}

    Protected Overrides Function GetMappings() As SortedDictionary(Of String, String)
        GetMappings = MAPPINGS
    End Function

    'モデルの名前とテーブル名は一致させること
    Protected Overrides Function GetModel() As Type
        GetModel = GetType(Syain)
    End Function

End Class

Mapperの共通部分
Imports System.Data.OleDb

Public Class CsvMapper

    '接続先(CSV用)
    Private Shared connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
              "Data Source=C:\tmp\;" & _
              "Extended Properties=""Text;HDR=YES;FMT=Delimited"""

    'SELECT文
    Private Function selectSQL() As String
        '個別のカラム情報を取得
        Dim columns As String() = (From i As String In GetMappings().Keys Select i).ToArray()
        'テーブル名、カラム名からSELECT文を構築
        selectSQL = "SELECT " & Join(columns, ",") & " FROM " & GetModel.Name() & ".csv"
    End Function

    'SELECT文を実行して一覧を返す
    Public Function List() As IList
        List = New ArrayList()
        Using connection As New OleDbConnection(connectionString)
            Dim command As New OleDbCommand(selectSQL, connection)
            connection.Open()
            Dim reader As OleDbDataReader = command.ExecuteReader()
            While reader.Read()
                List.Add(Transform(reader))
            End While
            reader.Close()
        End Using
    End Function

    'レコードをモデルに変換する
    Protected Overridable Function Transform(reader As OleDbDataReader) As Object

        'サブクラスからモデル情報を取得
        Dim modelType As Type = GetModel()
        If IsNothing(modelType) Then
            'モデル情報がなければHashtableに入れて返す
            Dim obj As New Hashtable
            Dim idx As Integer = 0
            For Each key As String In GetMappings.Values
                obj(key) = reader(idx)
                idx = idx + 1
            Next
            Transform = obj
        Else
            'モデル情報があればインスタンスを生成してプロパティを設定して返す
            Dim obj As Object = modelType.InvokeMember("New", Reflection.BindingFlags.CreateInstance, Nothing, Nothing, Nothing)
            Dim idx As Integer = 0
            For Each key As String In GetMappings.Values
                modelType.InvokeMember(key, Reflection.BindingFlags.SetProperty, Nothing, obj, New Object() {reader(idx)})
                idx = idx + 1
            Next
            Transform = obj
        End If
    End Function

    Protected Overridable Function GetModel() As Type
        GetModel = Nothing
    End Function

    Protected Overridable Function GetMappings() As SortedDictionary(Of String, String)
        Throw New NotImplementedException
    End Function

End Class

2012年5月21日月曜日

grails離れ

火消しを終えて本社戻ってきたらもうGrailsは使わない宣言された

2012年5月14日月曜日

PostgreSQLでemail、creditCardチェックメモ

メールアドレス
yum install postgresql84-plperl
yum install perl-Email-Address

-- Language: plperlu
-- DROP LANGUAGE plperlu;
CREATE PROCEDURAL LANGUAGE 'plperlu';

-- Function: is_email(email text)
-- DROP FUNCTION is_email(email text);
CREATE OR REPLACE FUNCTION is_email(email text)
  RETURNS bool AS
$$
use Email::Address;

return 1 unless defined($_[0]);
my @addresses = Email::Address->parse($_[0]);
return scalar(@addresses) > 0 ? 1 : 0;
$$
  LANGUAGE 'plperlu' VOLATILE;

-- Domain: email
-- DROP DOMAIN email;
CREATE DOMAIN email AS text
  CHECK (is_email(VALUE));


クレジットカード
yum install postgresql84-plperl
cpan install Business::CreditCard

-- Function: is_credit_card(credit_card text)
-- DROP FUNCTION is_credit_card(credit_card text);
CREATE OR REPLACE FUNCTION is_credit_card(credit_card text)
  RETURNS bool AS
$$
use Business::CreditCard;

return 1 unless defined($_[0]);
return validate($_[0]) > 0 ? 1 : 0;
$$
  LANGUAGE 'plperlu' VOLATILE;

-- Domain: credit_card
-- DROP DOMAIN credit_card;
CREATE DOMAIN credit_card AS text
   CHECK (is_credit_card(VALUE));