web-dev-qa-db-ja.com

必要な場合にのみ特権を昇格させる方法は?

この質問はWindows Vistaに適用されます!

通常、管理者権限なしで動作するアプリケーションがあります。管理者特権を必要とするアクティビティが1つありますが、ほとんどの場合、ユーザーがその機能を使用しないことを知っているときに、より高い特権でアプリケーション自体を起動したくありません。

何らかのイベント(ボタンを押すなど)でアプリケーションの特権を昇格できる特定の方法を考えています。例:

ユーザーがこのボタンをクリックすると、UACダイアログまたは同意が求められます。これどうやってするの?

82
Hemant

現在実行中のプロセスを昇格させることができるとは思わない。私が理解しているように、起動時にプロセスに管理者権限が与えられるのはWindows Vistaに組み込まれています。 UACを利用するさまざまなプログラムを見ると、管理アクションを実行する必要があるたびに個別のプロセスが実際に起動することがわかります(タスクマネージャーは1つ、Paint.NETはもう1つ、後者は実際には.NETアプリケーションです) )。

この問題の一般的な解決策は、昇格したプロセスを起動するときにコマンドライン引数を指定することです(abatishchevの提案はこれを行う方法の1つです)。これにより、起動したプロセスは特定のダイアログボックスのみを表示し、このアクションが終了した後に終了する完了しました。したがって、新しいプロセスが起動されて終了したことはユーザーにはほとんど気付かれず、同じアプリ内の新しいダイアログボックスが開かれたように見えます(特に、ハッカーがメインウィンドウを作成する場合上位プロセスは親プロセスの子)。昇格したアクセスにUIが必要ない場合は、さらに良いでしょう。

VistaでのUACの完全な議論については、件名に これは非常に記事を通して を参照することをお勧めします(コード例はC++ですが、WinAPIとP/Invokeを使用して、とにかくC#でほとんどのことを行います)。 UAC準拠のプログラムを設計するのは簡単なことではありませんが、少なくとも適切なアプローチをとることができれば幸いです...

56
Noldorin

言われたとおり あり

Process.StartInfo.UseShellExecute = true;
Process.StartInfo.Verb = "runas";

adminとしてプロセスを実行して、レジストリで必要なことは何でも行いますが、通常の権限でアプリに戻ります。

15
abatishchev

次のMSDN KB記事981778は、アプリケーションを「自己昇格」する方法を説明しています。

http://support.Microsoft.com/kb/981778

Visual C++、Visual C#、Visual Basic.NETのダウンロード可能なサンプルが含まれています。

このアプローチは、別のプロセスを開始する必要性を回避しますが、実際には、元のアプリケーションが再起動され、昇格したユーザーとして実行されます。それにもかかわらず、これは、別の実行可能ファイルでコードを複製することが実用的ではない一部のコンテキストでは、依然として非常に便利です。

標高を削除するには、アプリケーションを終了する必要があります。

13
FruitBreak

UACモニカと、昇格されたCOMオブジェクトとして実行するコードが必要です。

この質問を参照してください。

MSDNのドキュメント

4
Richard

おそらく、誰かがこの簡単な例の役に立つでしょう:

using System;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Security.Principal;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    internal static class Program
    {
        private class Form1 : Form
        {
            internal Form1()
            {
                var button = new Button{ Dock = DockStyle.Fill };
                button.Click += (sender, args) => RunAsAdmin();
                Controls.Add(button);

                ElevatedAction();
            }
        }

        [STAThread]
        internal static void Main(string[] arguments)
        {
            if (arguments?.Contains("/run_elevated_action") == true)
            {
                ElevatedAction();
                return;
            }

            Application.Run(new Form1());
        }

        private static void RunAsAdmin()
        {
            var path = Assembly.GetExecutingAssembly().Location;
            using (var process = Process.Start(new ProcessStartInfo(path, "/run_elevated_action")
            {
                Verb = "runas"
            }))
            {
                process?.WaitForExit();
            }
        }

        private static void ElevatedAction()
        {
            MessageBox.Show($@"IsElevated: {IsElevated()}");
        }

        private static bool IsElevated()
        {
            using (var identity = WindowsIdentity.GetCurrent())
            {
                var principal = new WindowsPrincipal(identity);

                return principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
        }

    }
}
2
Konstantin S.

私はこれが古い投稿であることを知っていますが、これはMarcPの提案に出くわした他の誰かへの応答です。彼が実際に参照したmsdnの投稿は、すべてのコード例でアプリケーションを再起動します。コードサンプルでは、​​他の提案で既に提案されているrunas動詞を使用しています。

確認のためにコードをダウンロードしましたが、これは元のmsdn記事からのものです。

4. [はい]をクリックして、標高を承認します。次に、元のアプリケーションが再起動し、管理者特権で実行されます。
5。アプリケーションを閉じます。

1
SpaceGhost440