自身を昇格して再実行する #uwsc

2013/04/23
書き直した!
スクリプトがネットワークドライブにあると昇格後に再実行出来ないのでそれに対応
ネットワークドライブはUNCパスに変換するようにしました
あと、実行ユーザが管理者権限持ってるかどうかも確認するようにしたよ

module UAC

    procedure Elevate(arg = "")
        if ! IsUserAnAdmin() then
            UWSC_DIR  = NetworkDriveToUnc(GET_UWSC_DIR)
            CUR_DIR   = NetworkDriveToUnc(GET_CUR_DIR)
            UWSC_NAME = GET_UWSC_NAME

            if pos(".exe", UWSC_NAME) then
                exe = UWSC_NAME
                dir = CUR_DIR
            else
                exe = "UWSC.exe"
                dir = UWSC_DIR
                arg = "<#DBL>" + CUR_DIR + "\" + UWSC_NAME + "<#DBL> " + arg
            endif
            sh = CreateOleObj("Shell.Application")
            sh.ShellExecute(exe, arg, dir, "runas", 1)
            exitexit
        endif
    fend
    
    function NetworkDriveToUnc(path)
        result = format(chr(0), 256)
        size = lengthb(result)
        if WNetGetUniversalNameA(path, UNIVERSAL_NAME_INFO_LEVEL, result, size) then
            result = path
        endif
    fend

    DEF_DLL IsUserAnAdmin():bool:shell32.dll
    def_dll WNetGetUniversalNameA(string, long, {var string}, var long):long:mpr
    const UNIVERSAL_NAME_INFO_LEVEL = $1

endmodule

1行目に書いておくと必要であれば昇格するので便利です

UAC.Elevate()
id = exec("mmc.exe")
msgbox( status(id, ST_TITLE) )

本当はPARAM_STRも勝手に渡せるようにしたかったけど、どうも関数内じゃ参照出来ない(仕様ですって!)ので止めました
やりようはあるんだけど、まぁJoin()してElevate()に渡すだけなので別にいいよね


以下古いの

UWSCを「管理者として実行」しないと対象の操作が出来なさそうだなー
って時に使うよ
UAC制御下でも泣き言を言わないためのtips

id = exec("mmc.exe")

if id < 0 then
    msgbox("mmc.exeの起動に失敗しました<#CR>昇格ダイアログが表示され再実行されます")
    UacElevate()
else
    msgbox( status(id, ST_TITLE) )
endif

procedure UacElevate(arg = "")
    if pos(".exe", GET_UWSC_NAME) then
        exe = GET_UWSC_NAME
        dir = GET_CUR_DIR
    else
        exe = "UWSC.exe"
        dir = GET_UWSC_DIR
        arg = "<#DBL>" + GET_CUR_DIR + "\" + GET_UWSC_NAME + "<#DBL> " + arg
    endif
    sh = CreateOleObj("Shell.Application")
    sh.ShellExecute(exe, arg, dir, "runas", 1)
fend

操作対象ウィンドウを持つプロセスが昇格実行されてるかどうか?
って判定はほんとはもっとちゃんとやったほうがいいんだけど

引数argはUacElevate()で再実行されたよーっていう印をつけるのに使ったら便利かなーって
こんな感じで

if length(PARAM_STR) then
    if PARAM_STR[0] = "みなもちゃんかわいい!" then
        msgbox("管理者として実行されました")
    else
        msgbox("不正な引数です<#CR>" + PARAM_STR[0])
    endif
else
    msgbox("昇格して再実行しますよ")
    UacElevate("みなもちゃんかわいい!")
endif

元々のコマンドライン引数を渡すのにも使える
joinして渡す

UacElevate(join(PARAM_STR))
広告

自身を昇格して再実行する #uwsc」への5件のフィードバック

  1. 今更なのですが、exe自身の昇格実行って出来なくなっていませんか?
    exeダブルクリックでUACウィンドウを出そうとしたのですが、なんかShellExecute実行が出来ません。名前違いのexeを2つ用意すれば動くのですが・・WINDOWS UPDATEでUACの制限が変わったりしたのか又は私の環境だけなのか・・?

    • すいません!遅くなってしまいましたがexe化して試してみました
      昇格後に動作しない、ということでしたら僕のところでも再現しました
      これはどうやらexe化の際に「多重起動を許さない」を有効にしているかどうかによるようです
      有効にしているとShellExecute()の時点でまだ呼び出し元のプロセスが生きているので多重起動に引っかかる、ということなのだと思います
      でも以前はこれでも動いていたと思うので、対策を考えてみます

      昇格ダイアログ自体が出てこない、ということでしたら再現出来てないのでなんとも言えないです…手元の環境(Win7、8.1)では昇格ダイアログは毎回表示されていたのでその点では問題ありませんでした

      • こちらもすいません!もっと遅くなってしまいました><
        そうですね正確には「昇格後に動作しない」でした。
        多重起動禁止フラグ外したら動きました。なるほどそういうことでしたか。コンテキスト実行なのでレジストリの起動オプションなどすっかり忘れていました。。
        対策見つかりそうですか?とりあえず動いたので私は満足してます。ありがとうございました^^

      • 今考えてるのは、自身がexeだった場合に
        ・自身を再実行するvbsファイルを書き出して実行
        ・vbsで元々のexeが終了するを待って、exe再実行
        ・vbsは自分を削除して完了
        といった感じです
        多重起動が禁止されているかどうかの確認まで含めるか?がちょっと悩ましいですね (実現可能かどうかから調べないと…!)

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中