私たちが作成した一部のクライアント ソフトウェアで一般的に使用するプロセスは、次のようになります。
- 昇格したプロセスを開始して、レジストリ キーを設定しようとします。
- プロセスが完了するか、例外がスローされるまで待ちます。
- 予期されるキーの読み取りを試行して、レジストリ キーが設定されたことを検証します (管理者以外でも実行できます)。
- キーが設定されていない場合は、フォールバック メソッドを実行します (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