CreateProcessWithLogonWがW2Kで動かない

解決


ポンポンポン  2006-07-20 09:29:07  No: 96038

CreateProcessWithLogonWを使用して、別アカウントでVBSを起動するプログラムを作っています。
WinXPでは動作したのですが、Win2000SP4で動作しません。

RunAsサービスは起動していますし、advapi32.dllもありました。
VBの開発環境がインストールされているWin2000では動作しました。

MSDN等で確認すると、Win2000も対応しているようなのですが、
環境等で、何か他に足りないものがあるのでしょうか?

環境:VB6SP5 Win2KSP4


K.J.K.  2006-07-20 12:51:19  No: 96039

戻り値及び呼び出した直後のErr.LastDllErrorの値は?


ポンポンポン  2006-07-20 14:01:00  No: 96040

戻り値はゼロ、Err.LastDllErrorは267でした。
(ちなみにありえないユーザ名やパスワードで実行するとErr.LastDllErrorは1326でした。)


K.J.K.  2006-07-20 15:13:43  No: 96041

winerror.hより引用すると、

// MessageId: ERROR_DIRECTORY
//
// MessageText:
//
//  The directory name is invalid.
//
#define ERROR_DIRECTORY                  267L

となってます。
正しい文字列を送っているのかをチェックしてみては。

まさか、第1〜3、5、6、9引数をByVal ... As Stringとはして
はいないでしょうし。
# 今時、こういうことをする人がいるとは思えないし。


ポンポンポン  2006-07-20 16:46:19  No: 96042

ご回答ありがとうございます。

記述方法が分からなかったので、インターネットでサンプルを探し、
下記のような2通りの方法で試しています。
①は、267のエラーが返ってきます。
②は、VBが落ちてしまいます。
(WinXPや開発環境で動作したものは、②です。)

①ここから---------------------------------------------
Private Declare Function CreateProcessWithLogonW Lib "advapi32.dll" _
        (ByVal lpUsername As String, _
        ByVal lpDomain As String, _
        ByVal lpPassword As String, _
        ByVal dwLogonFlags As Long, _
        ByVal lpApplicationName As Long, _
        ByVal lpCommandLine As String, _
        ByVal dwCreationFlags As Long, _
        ByVal lpEnvironment As Long, _
        ByVal lpCurrentDirectory As String, _
        ByRef lpStartupInfo As STARTUPINFO, _
        ByRef lpProcessInformation As PROCESS_INFORMATION) As Long

    Dim si As STARTUPINFO
    Dim pi As PROCESS_INFORMATION
    
    Dim wUser As String
    Dim wDomain As String
    Dim wPassword As String
    Dim wCommandLine As String
    Dim wCurrentDir As String
    
    Dim Result As Long
    
    si.cb = Len(si)
        
    wUser = StrConv(UserName + Chr$(0), vbUnicode)
    wDomain = StrConv(DomainName + Chr$(0), vbUnicode)
    wPassword = StrConv(Password + Chr$(0), vbUnicode)
    wCommandLine = StrConv(CommandLine + Chr$(0), vbUnicode)
    wCurrentDir = StrConv(CurrentDirectory + Chr$(0), vbUnicode)

    Result = CreateProcessWithLogonW(wUser, wDomain, wPassword, _
          LOGON_WITH_PROFILE, 0&, wCommandLine, _
          CREATE_DEFAULT_ERROR_MODE, 0&, wCurrentDir, si, pi)

②ここから---------------------------------------------
 Private Declare Function CreateProcessWithLogonW Lib "advapi32.dll" _
    (ByVal lpUsername As Long, _
    ByVal lpDomain As Long, _
    ByVal lpPassword As Long, _
    ByVal dwLogonFlags As Long, _
    ByVal lpApplicationName As Long, _
    ByVal lpCommandLine As Long, _
    ByVal dwCreationFlags As Long, _
    ByVal lpEnvironment As Long, _
    ByVal lpCurrentDirectory As Long, _
    lpStartupInfo As STARTUPINFO, _
    lpProcessInfo As PROCESS_INFORMATION) As Long

       wRet = CreateProcessWithLogonW(StrPtr(iUser), StrPtr(iDomain), StrPtr(iPass), LOGON_WITH_PROFILE, _
                                      StrPtr(iApplicationName), StrPtr(iCommandLine), 0, ByVal 0, 0, wSTARTUPINFO, wPROCESSINFO)

ご指摘からすると、①は間違いということでしょうか?
何度も申し訳ありませんが、お気づきの点がありましたら、返信お願い致します。


K.J.K.  2006-07-20 20:19:07  No: 96043

駄目なサンプルを真似しても駄目なだけでしょう。
確認しませんが、こんな感じでは。

Private Declare Function CreateProcessWithLogonW _
    Lib "advapi32.dll" _
(ByRef UserName As Any, _
 ByRef Domain As Any, _
 ByRef Password As Any, _
 ByVal LogonFlags As Long, _
 ByRef ApplicationName As Any, _
 ByRef CommandLine As Any, _
 ByVal CreationFlags As Long, _
 ByRef Environment As Any, _
 ByRef CurrentDirectory As Any, _
 ByRef StartupInfo As STARTUPINFO, _
 ByRef ProcessInformation As PROCESS_INFORMATION) As Long

    Dim uStartupInfo As STARTUPINFO
    Dim uProcessInfo As PROCESS_INFORMATION
    
    Dim abUser() As Byte
    Dim abDomain() As Byte
    Dim abPassword() As Byte
    Dim abCommandLine() As Byte
    Dim abCurrentDir() As Byte
    
    Dim iResult As Long
    
    uStartupInfo.cb = Len(uStartupInfo)
        
    abUser = UserName & vbNullChar
    abDomain = DomainName & vbNullChar
    abPassword = Password & vbNullChar
    abCommandLine = CommandLine & vbNullChar
    abCurrentDir = CurrentDirectory & vbNullChar

    iResult = CreateProcessWithLogonW _
            (abUser(0&), abDomain(0&), abPassword(0&), _
             LOGON_WITH_PROFILE, ByVal vbNullString, _
             abCommandLine(0&), CREATE_DEFAULT_ERROR_MODE, _
             ByVal vbNullString, abCurrentDir(0&), _
             uStartupInfo, uProcessInfo)


Blue  2006-07-21 09:18:46  No: 96044

※丸付き数字は機種依存文字です。
  どの機種で閲覧されるかわからないWeb上のサイトでは文字化けの原因になるので
  使用するのは控えましょう。

(2)のほうですが

wRet = CreateProcessWithLogonW(
 ※ StrPtr(iUser),
 ※ StrPtr(iDomain),
 ※ StrPtr(iPass), 
    LOGON_WITH_PROFILE,
 ※ StrPtr(iApplicationName), 
 ※ StrPtr(iCommandLine), 
    0, 
    ByVal 0,
 ※ 0,
    wSTARTUPINFO,
    wPROCESSINFO)

の※の部分は StrPtr で文字列を指定しないといけないところです。
で、lpCurrentDirectoryの指定のところ(最後の※)を単に 0 にしているので、VBが落ちてしまっているんだと思います。

StrPtr("")

とか

Dim iCurrentDirectory As String

StrPtr(iCurrentDirectory )

とかにしてみてはどうでしょうか?


ポンポンポン  2006-07-21 13:08:18  No: 96045

> ※丸付き数字は機種依存文字です。
>  どの機種で閲覧されるかわからないWeb上のサイトでは文字化けの原因になるので
>  使用するのは控えましょう。
アドバイスありがとうございます。
以後気をつけます。

さて、ご指摘いただいた2通りを試してみましたが、両方ともVBが落ちてしまいました。
原因は、パラメータの型だということが分かりましたので、もう少し自分で試してみます。
また、結果をご報告致します。


ポンポンポン  2006-07-21 14:54:42  No: 96046

解決しました。
原因は2つあったみたいです。
1つはご指摘の通りパラメータの型で、
もう1つはカレントディレクトリを空にしていたからでした。
動作環境のパスを渡したら動作しました。

参考までに、マイクロソフトもサンプルを出していました。
http://support.microsoft.com/kb/285879/ja
とても勉強になり、大変助かりました。
どうもありがとうございました。


※作成する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。







   このエントリーをはてなブックマークに追加