- PR -

ユーザーログイン状態でexeをadmin権限で実行するには?

投稿者投稿内容
IMPREZA
ベテラン
会議室デビュー日: 2005/07/06
投稿数: 58
投稿日時: 2005-10-18 17:10
はじめまして。

色々と調べたのですが見つからなかったので投稿しました。

表題の通りなのですが、行いたいことは
ユーザー権限(Users,Power Users)でexeやbatをAdmin権限で実行したいのです。

RunasコマンドをWshのsendkeyを使ってというのも考えたのですが、
実行中にユーザがマウスやキーボード操作を行う可能性があるのと、
vbsではAdmin権限のパスワードがメモ帳などから分かってしまうのでNGです。

どなたかVB等でAdmin権限で実行する方法はないか
知ってる方はいらっしゃいませんか?

環境
VS.NET2002(VB)、WindowsXP SP2、.Net Framework1.1です。
admini権限にはパスワードがあります。
ちなみにLocalAdminではなくDomainAdminで考えております。
新人管理人
会議室デビュー日: 2005/06/27
投稿数: 9
投稿日時: 2005-10-18 17:42
VB等で…と書かれているので筋違いかもしれませんが…
自分もDomainUserしか持たないアカウントでデフラグを実行させる為に悩んでおります。
パスを見せたくないので、今のところタスクスケジューラで設定しています。
何かいい方法があれば僕もあやかりたいです。
たつ64
会議室デビュー日: 2005/08/02
投稿数: 16
お住まい・勤務地: 天下の台所?
投稿日時: 2005-10-18 20:25
お疲れさまです。

API(CreateProcessWithLogonW)じゃダメですか?
www.microsoft.com/japan/developer/library/jpwinpf/_win32_createprocesswithlogonw.htm
IMPREZA
ベテラン
会議室デビュー日: 2005/07/06
投稿数: 58
投稿日時: 2005-10-19 16:11
APIのコードを見つけたのですが、それをVB.NETで動かす方法がわかりません。

見つけたのは下記のコードです。

---------------------------------------------------------------------
Option Explicit

Public Const LOGON_WITH_PROFILE = &H1&
Public Const LOGON_NETCREDENTIALS_ONLY = &H2&
Public Const CREATE_DEFAULT_ERROR_MODE = &H4000000
Public Const CREATE_NEW_CONSOLE = &H10&
Public Const CREATE_NEW_PROCESS_GROUP = &H200&
Public Const CREATE_SEPARATE_WOW_VDM = &H800&
Public Const CREATE_SUSPENDED = &H4&
Public Const CREATE_UNICODE_ENVIRONMENT = &H400&
Public Const ABOVE_NORMAL_PRIORITY_CLASS = &H8000&
Public Const BELOW_NORMAL_PRIORITY_CLASS = &H4000&
Public Const HIGH_PRIORITY_CLASS = &H80&
Public Const IDLE_PRIORITY_CLASS = &H40&
Public Const NORMAL_PRIORITY_CLASS = &H20&
Public Const REALTIME_PRIORITY_CLASS = &H100&

Public Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type

Public Type STARTUPINFO
cb As Long
lpReserved As Long
lpDesktop As Long
lpTitle As Long
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Byte
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type

Public Declare Function CreateProcessWithLogon _
Lib "Advapi32" Alias "CreateProcessWithLogonW" ( _
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

Public Declare Function CloseHandle _
Lib "kernel32" (ByVal hObject As Long) As Long

Sub main()

Dim lngRet As Long

lngRet = RunAs("Guest", _
"", _
"", _
"notepad.exe", _
"")

If lngRet = 0 Then
MsgBox "起動に失敗!"
Else
MsgBox "正常終了!"
End If

End Sub

' @(f)
'
' 機能 : 別ユーザーとして実行
'
' 返り値 : CreateProcessWithLogon()の返り値をそのまま返す
'
' 引き数 : lpUsername - ユーザ名
' : lpDomain - ドメイン(ローカルにログオンしている場合は空文字)
' : lpPassword - パスワード
' : lpApplicationName - アプリケーションのパス
' : lpCommandLine - コマンドライン引数
'
' 機能説明 : 別ユーザーとしてアプリケーションを実行する
' 実行するアプリケーションは、それを実行したいユーザが
' アクセスできる場所に置いておくこと
'
' 備考 : なし
'
Public Function RunAs( _
ByVal lpUsername As String, _
ByVal lpDomain As String, _
ByVal lpPassword As String, _
ByVal lpApplicationName As String, _
ByVal lpCommandLine As String) As Long

Dim lpCurrentDirectory As String
Dim StartInfo As STARTUPINFO
Dim ProcessInfo As PROCESS_INFORMATION

' lpCommandLine = vbNullString
lpCurrentDirectory = vbNullString
StartInfo.cb = LenB(StartInfo) --------------------------→ココ
StartInfo.dwFlags = 0&

Dim lngRet As Long
lngRet = CreateProcessWithLogon( _
StrPtr(lpUsername), _ --------------------------→ココ
StrPtr(lpDomain), _
StrPtr(lpPassword), _
LOGON_WITH_PROFILE, _
StrPtr(lpApplicationName), _
StrPtr(lpCommandLine), _
CREATE_DEFAULT_ERROR_MODE _
Or CREATE_NEW_CONSOLE _
Or CREATE_NEW_PROCESS_GROUP, _
ByVal 0&, _  --------------------------→ココ
StrPtr(lpCurrentDirectory), _
StartInfo, _
ProcessInfo)

CloseHandle ProcessInfo.hThread
CloseHandle ProcessInfo.hProcess

RunAs = lngRet

End Function
---------------------------------------------------------------------


上記のココと書いているところをVB.NET用に変換するとどのようになるのか分かりますか?
LenB→Len、StrPrt→Strではダメですよね〜?
たつ64
会議室デビュー日: 2005/08/02
投稿数: 16
お住まい・勤務地: 天下の台所?
投稿日時: 2005-10-19 17:15
お疲れさまです。

MSDNでは
コード:
BOOL CreateProcessWithLogonW(
  LPCWSTR lpUsername,            // ユーザーの名前
  LPCWSTR lpDomain,              // ユーザーのドメイン
  LPCWSTR lpPassword,            // ユーザーのパスワード
  DWORD dwLogonFlags,            // ログオン オプション
  LPCWSTR lpApplicationName,     // 実行可能モジュール名
  LPWSTR lpCommandLine,          // コマンドライン文字列
  DWORD dwCreationFlags,         // 作成フラグ
  LPVOID lpEnvironment,          // 新しい環境ブロック
  LPCWSTR lpCurrentDirectory,    // カレントディレクトリの名前
  LPSTARTUPINFOW lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);


となってます。

よって
引用:

Public Declare Function CreateProcessWithLogon _
Lib "Advapi32" Alias "CreateProcessWithLogonW" ( _
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


というのは何故?。

因みに.NETでのAPI利用は
@IT .NET TIPSより
Win32 APIやDLL関数を呼び出すには?
Win32 APIやDLL関数に文字列や文字列バッファを渡すには?
などでどうでしょう。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-19 17:26
こんにちは、IMPREZA さん。

引用:

IMPREZAさんの書き込み (2005-10-19 16:11) より:

APIのコードを見つけたのですが、それをVB.NETで動かす方法がわかりません。
見つけたのは下記のコードです。

上記のココと書いているところをVB.NET用に変換するとどのようになるのか分かりますか?
LenB→Len、StrPrt→Strではダメですよね〜?


その前に定義から見るに全くこのままでは駄目なので、
とりあえず、定義だけは変換しておきました。

コード:

Private Structure ProcessInformation
   Public hProcess    As System.IntPtr
   Public hThread     As System.IntPtr
   Public dwProcessId As Integer
   Public dwThreadId  As Integer
End Structure

<StructLayout(LayoutKind.Sequential)> _
Private Structure StartupInfo
    Public cb              As Integer
    Public lpReserved      As String
    Public lpDesktop       As String
    Public lpTitle         As String
    Public dwX             As Integer
    Public dwY             As Integer
    Public dwXSize         As Integer
    Public dwYSize         As Integer
    Public dwXCountChars   As Integer
    Public dwYCountChars   As Integer
    Public dwFillAttribute As Integer
    Public dwFlags         As Integer
    Public wShowWindow     As Short
    Public cbReserved2     As Short
    Public lpReserved2     As Integer
    Public hStdInput       As Integer
    Public hStdOutput      As Integer
    Public hStdError       As Integer
End Structure

<DllImport("ADVAPI32.DLL", CharSet:=CharSet.Auto)> _
Private Shared Function CreateProcessWithLogonW( _
    ByVal userName           As String, _
    ByVal domain             As String, _
    ByVal password           As String, _
    ByVal logonFlags         As System.UInt32, _
    ByVal applicationName    As String, _
    ByVal commandLine        As String, _
    ByVal creationFlags      As System.UInt32, _
    ByVal environment        As System.UInt32, _
    ByVal currentDirectory   As String, _
    ByRef startupInfo        As StartupInfo, _
    ByRef processInformation As ProcessInformation) As Boolean
End Function

<DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)]
Private Shared Function CloseHandle( _
    ByVal hObject As System.IntPtr) As Boolean
End Function



引用:

StrPtr(lpUsername), _ --------------------------→ココ


GCHandle.Alloc から AddrOfPinnedObject().ToInt32() ですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
IMPREZA
ベテラン
会議室デビュー日: 2005/07/06
投稿数: 58
投稿日時: 2005-10-20 10:17
たつ64さん
じゃんぬねっとさん

ありがとうございます。

一応、分からないなりに調べてみたのですが・・・やはり動かずです。
じゃんぬねっとさんが記載してくださったソースを少し変更しています。

<DllImport("ADVAPI32.DLL", CharSet:=CharSet.Auto)> _
Private Shared Function CreateProcessWithLogonW( _
ByVal userName As String, _
ByVal domain As String, _
ByVal password As String, _
ByVal logonFlags As Long, _       System.UInt32をLongに
ByVal applicationName As String, _
ByVal commandLine As String, _
ByVal creationFlags As Long, _     System.UInt32をLongに
ByVal environment As Long, _      System.UInt32をLongに
ByVal currentDirectory As String, _
ByRef s_upInfo As StartupInfo, _
ByRef p_Information As ProcessInformation) As Boolean
End Function


lngRet = CreateProcessWithLogonW( _
CStr(lpUsername), _      StrPrtをCStrに
CStr(lpDomain), _       StrPrtをCStrに
CStr(lpPassword), _      StrPrtをCStrに
LOGON_WITH_PROFILE, _
CStr(lpApplicationName), _   StrPrtをCStrに
CStr(lpCommandLine), _     StrPrtをCStrに
CREATE_DEFAULT_ERROR_MODE _
Or CREATE_NEW_CONSOLE _
Or CREATE_NEW_PROCESS_GROUP, _
CInt(0&), _ ByValをCIntに
CStr(lpCurrentDirectory), _  StrPrtをCStrに
StartInfo, _
ProcessInfo)

あとは前回も書いてましたがLenBをLenにしていますが・・・
これは違いますよね〜。。。

実行すると『lngRet = CreateProcessWithLogonW(…』の
lngRet=0になってしまい実行されません。

もう少し試してみますが手助けをしていただけると助かります。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-20 10:44
引用:

IMPREZAさんの書き込み (2005-10-20 10:17) より:

じゃんぬねっとさんが記載してくださったソースを少し変更しています。


すいません、なぜでしょうか?

引用:

VS.NET2002(VB)、WindowsXP SP2、.Net Framework1.1です。


なのですよね?

旧 VB から取ってきた資料をそのまま VB.NET には適用できません。
それは、型がまったく異なるからです。
たとえば、旧 VB の Long は VB.NET では Integer (System.Int32) です。
いえ、その前に、たつ64さんが提示してくださった、
リンク先に目を通していないのでしょうか?

また、StrPtr ですが、私は先の書き込みで既に触れています。

LenB はバイト数を求めるのでしょうか?
Encoding から GetByteCount メソッドで求めれます。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌

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