none
重複起動のチェック時のvbUnicodeについて RRS feed

  • 質問

  • いつも参考にさせていただいております。

    重複チェックの際に正しいプロセス名が取ってこれない件について、ご教授願いたいと思います。

    環境はWindows 2003 Server , VB.NET です。

     

    当初はVB6で動いていたもののため、

    関数「fGetProcessName」内の、

    sString = Left(StrConv(System.Text.UnicodeEncoding.Unicode.GetString(tModuleBaseName), vbUnicode), lRetValue)

    が有効でした。

     

    やりたいことは、同じプロセス名が存在したとき、「重複エラーです」というメッセージを出すことです。

     

    VB.NETになってvbUnicodeが使えなくなったため、変数

        Dim eUnicode As Encoding = UnicodeEncoding.Unicode
        Dim unicodeBytes As Byte()
        Dim unicodeString As String

    を追加し、

        unicodeString = System.Text.UnicodeEncoding.Unicode.GetString(tModuleBaseName)    

        unicodeBytes = eUnicode.GetBytes(unicodeString)

        Dim unicodeChars(eUnicode.GetCharCount(unicodeBytes, 0, unicodeBytes.Length)) As Char
        eUnicode.GetChars(unicodeBytes, 0, unicodeBytes.Length, unicodeChars, 0)
        sString = unicodeChars

        fGetProcessName = sString
    という行に書き換えました。

    それでも、

        fGetProcessName(tProcesses(i))

    の行で必要なプロセス名を取得することができておりません。

     

    Byte -> Stringへの変換がうまくいっていないように思えます。

     

     

    コードは以下のとおりです。

    ********************************************************************

        Public Function pfRunModule(ByVal sModuleName As String) As Boolean

            '-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
            '関数名:pfRunModule
            '引数 :モジュール名
            '戻り値:正常終了/異常終了
            '概要 :引数のモジュールを起動する 既に起動している場合、手前に表示する
            '-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
            Const sFunctionName As String = "pfRunModule"

            Dim tProcesses(1023) As Integer 'プロセス配列
            Dim lNeeded As Integer 'プロセス配列サイズ
            Dim lProcesses As Integer 'プロセス数
            Dim lWnd As Integer 'ウィンドウハンドル
            Dim i As Integer 'ループカウンタ
            Dim la As Integer

     

            '関数の戻り値を初期化する

            pfRunModule = False
            ''プロセスを列挙する
            lRetValue = EnumProcesses(tProcesses(0), UBound(tProcesses), lNeeded)
            'プロセス数を取得する
            lProcesses = lNeeded / 4
            '取得したプロセスの分、ループする
            For i = 0 To lProcesses - 1
                'モジュールが存在すれば終了する
                If fGetProcessName(tProcesses(i)) = sModuleName Then
                    Call MsgBox("重複起動です", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "9999")
                    Exit Function
                End If
            Next i
            'モジュールが存在しなければ起動する
            Call Shell(My.Application.Info.DirectoryPath & "\" & sModuleName, AppWinStyle.NormalFocus)
            '正常終了する
            pfRunModule = True

     

     

    ********************************************************************

        Private Function fGetProcessName(ByVal lProcessID As Integer) As String
            '-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
            '関数名:fGetProcessName
            '引数 :プロセスID
            '戻り値:モジュールベース名
            '概要 :引数のプロセスIDでモジュールベース名を取得する
            '-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+

            Const sFunctionName As String = "fGetProcessName"

            Dim hProcess As Integer 'プロセスハンドル
            Dim hModules(1023) As Integer 'モジュールハンドル配列
            Dim lModules As Integer 'モジュール数
            Dim lNeeded As Integer 'モジュール配列サイズ
            Dim tModuleBaseName(255) As Byte 'モジュールベース名バッファ
            Dim tModuleFileName(255) As Byte 'モジュールファイル名バッファ
            Dim sString As String

            '***** VB6→.net2005 ADD START *****
            Dim eUnicode As Encoding = UnicodeEncoding.Unicode
            Dim unicodeBytes As Byte()
            Dim unicodeString As String
            '***** VB6→.net2005 ADD END *****

            'プロセスをオープンする
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, False, lProcessID)
            If hProcess <> 0 Then
                'モジュールを列挙する
                If EnumProcessModules(hProcess, hModules(0), UBound(hModules), lNeeded) <> 0 Then
                    'モジュール数を取得する
                    lModules = lNeeded / 4
                    'モジュールベース名を取得する
                    lRetValue = GetModuleBaseName(hProcess, hModules(0), tModuleBaseName(0), UBound(tModuleBaseName))
                    
                    '***** VB6→.net2005 UPD START *****
                    'sString = Left(StrConv(System.Text.UnicodeEncoding.Unicode.GetString(tModuleBaseName), vbUnicode), lRetValue)

                    unicodeString = System.Text.UnicodeEncoding.Unicode.GetString(tModuleBaseName)
                    unicodeBytes = eUnicode.GetBytes(unicodeString)

                    Dim unicodeChars(eUnicode.GetCharCount(unicodeBytes, 0, unicodeBytes.Length)) As Char
                    eUnicode.GetChars(unicodeBytes, 0, unicodeBytes.Length, unicodeChars, 0)
                    sString = unicodeChars

                    '***** VB6→.net2005 UPD END *****

     

                    fGetProcessName = sString
                End If
            End If
            'オープンしたプロセスをクローズする
            Call CloseHandle(hProcess)

        End Function

    **********************************************************************************

     

    Left(StrConv(System.Text.UnicodeEncoding.Unicode.GetString(tModuleBaseName), vbUnicode), lRetValue)

    の代わりになるVB.NETでのコードはどのようなものなのでしょうか。

    MSDNのオンラインヘルプやあちこちを参照したのですが、見当たりませんでした。

    お力をお貸しください。

    よろしくお願いいたします。

    2008年1月29日 7:22

回答

すべての返信