3

ユーザーがライセンス キーを入力する必要がある場合、できる場合は HKLM に入力し、できない場合は HKCU に入力します。HKLM にある場合は、コンピューター上のすべてのユーザーがライセンスを所有しており、それぞれがライセンスを入力する必要はありません。

私たちは Office へのアドオンであるため、Office の権利で実行されます。通常、これは管理者権限ではありません (UAC がオフになっている場合を除きます)。そのため、WindowsPrincipal.IsInRole(Administrator) は、ユーザーが何を実行できるかに関係なく、false を返します。

ユーザーがローカル管理者権限を持っている場合は、runas=admin を持つアプレットを起動して、HKLM で設定できるようにします。ただし、ローカルの管理者権限がない場合は、HKCU に配置します。

それで... ユーザーが runas=admin を実行できるかどうかを判断するにはどうすればよいですか? .net 3.5 を使用しています。

ありがとう - デイブ

4

1 に答える 1

2

私たちが作成した一部のクライアント ソフトウェアで一般的に使用するプロセスは、次のようになります。

  1. 昇格したプロセスを開始して、レジストリ キーを設定しようとします。
  2. プロセスが完了するか、例外がスローされるまで待ちます。
  3. 予期されるキーの読み取りを試行して、レジストリ キーが設定されたことを検証します (管理者以外でも実行できます)。
  4. キーが設定されていない場合は、フォールバック メソッドを実行します (HKCU への書き込みなど)。

このような昇格したコードを実行するためのヘルパー関数があります (VB.Net)。昇格したプロセスを実行するためにコマンド ライン フラグを指定した同じアプリケーションを使用しているだけなので、プロセス名に現在のアセンブリを使用していることがわかります。特定のプロセスに置き換えることができます。

Private Function RunElevated(commandLine As String, Optional ByVal timeout As Integer = 0) As Boolean
    Dim startInfo As New ProcessStartInfo
    startInfo.UseShellExecute = True
    startInfo.WorkingDirectory = Environment.CurrentDirectory
    Dim uri As New Uri(Assembly.GetEntryAssembly.GetName.CodeBase)
    startInfo.FileName = uri.LocalPath
    startInfo.Verb = "runas"
    startInfo.Arguments = commandLine

    Dim success As Boolean
    Try
        Dim p As Process = Process.Start(startInfo)
        ' wait thirty seconds for completion
        If timeout > 0 Then
            If Not p.WaitForExit(30000) Then
                ' did not complete in thirty seconds, so kill
                p.Kill()
                success = False
            Else
                success = True
            End If
        Else
            p.WaitForExit()
            success = True
        End If
    Catch ex As Win32Exception
        success = False
    Catch ex As Exception
        MsgBox("Error occurred while trying to start application as administrator: " & ex.Message)
        success = False
    End Try
    Return success
End Function

上記のコードでは、例外を失敗コードとして処理し、環境では実行を 30 秒に制限しています。あなたのケースでは時間制限を設けたくないかもしれないので、コードのその部分を削除するだけです。

管理者モードのプロセスでは、最初にこのヘルパー関数を使用して、自分が実際に管理者であることを再確認します。

Public Function IsAdmin() As Boolean
    Dim id As WindowsIdentity = WindowsIdentity.GetCurrent
    Dim p As New WindowsPrincipal(id)
    Return p.IsInRole(WindowsBuiltInRole.Administrator)
End Function

自分が管理者であることを確認したら、先に進み、レジストリ キーを設定して戻ります。次に、呼び出し元プログラムは、キーが正常に設定されたことを検証して、フォールバック プロシージャを実行する必要があるかどうかを判断します。これはRunElevated、サブプロセスが完了し、キーの設定が成功または失敗したため、呼び出し元に戻るときです。そのコードは次のようになります。

Public Function UpdateSettings(...) As Boolean
    Dim success As Boolean
    Try
        If Not IsAdmin() Then
            ' try to create the registry keys as administrator
            success = RunElevated(Command() & " /admin", 30000)
        Else
            ' if we're already admin, then just update directly
            success = UpdateSettingsAdmin(...)
        End If
        success = success And ValidateUpdateSettings(...)
    Catch ex As Exception
        success = False
    End Try
    Return success
End Function
于 2012-04-25T22:09:26.913 に答える