Ayrıcalıklar yalnızca gerektiğinde nasıl yükseltilir?


85

Bu soru Windows Vista için geçerlidir!

Normalde yönetici ayrıcalıkları olmadan çalışan bir uygulamam var. Yönetici ayrıcalığına ihtiyaç duyan bir etkinlik var, ancak çoğu zaman kullanıcının bu özelliği kullanmayacağını bildiğimde uygulamanın kendisini daha yüksek ayrıcalıklarla başlatmak istemiyorum.

Bazı olaylarda uygulama ayrıcalıklarını yükseltebileceğim belirli bir yöntemi düşünüyorum (bir düğmeye basmak gibi). Misal:

Kullanıcı bu düğmeyi tıklarsa, UAC iletişim kutusu veya onayı ile istenir. Bunu nasıl yapabilirim?

Yanıtlar:


58

Şu anda devam eden süreci yükseltmenin mümkün olduğuna inanmıyorum. Windows Vista'da, anladığım kadarıyla, başlatma sırasında bir işleme yönetici ayrıcalıklarının verildiği yerleşiktir. UAC kullanan çeşitli programlara bakarsanız, her bir yönetimsel eylemin gerçekleştirilmesi gerektiğinde aslında ayrı bir işlem başlattıklarını görmelisiniz (Görev Yöneticisi biri, Paint.NET diğeridir, ikincisi aslında bir .NET uygulamasıdır. ).

Bu sorunun tipik çözümü, yükseltilmiş bir işlemi başlatırken komut satırı argümanlarını belirlemektir (abatishchev'in önerisi bunu yapmanın bir yoludur), böylece başlatılan işlem yalnızca belirli bir iletişim kutusunu görüntülemeyi bilir ve bu işlem tamamlandıktan sonra çıkılır. Tamamlandı. Bu nedenle, yeni bir işlemin başlatıldığı ve ardından çıkıldığı kullanıcıya neredeyse hiç fark edilmemeli ve aynı uygulama içinde yeni bir iletişim kutusu açılmış gibi görünmelidir (özellikle de ana pencereyi yapmak için bir bilgisayar korsanlığınız varsa) yüksek süreç, ana sürecin bir alt öğesi). Yükseltilmiş erişim için UI'ye ihtiyacınız yoksa, daha da iyisi.

Vista'da UAC'nin tam bir tartışması için, konuyla ilgili makaleyi tam olarak görmenizi tavsiye ederim (kod örnekleri C ++ 'dadır, ancak C #' da çoğu şeyi yapmak için WinAPI ve P / Invoke kullanmanız gerekeceğinden şüpheleniyorum. neyse). UAC uyumlu bir program tasarlamak önemsiz olmaktan uzak olsa da, umarım şimdi en azından doğru yaklaşımı görüyorsunuz ...


4
Windows 7'de herhangi bir değişiklik var mı veya "hayır, yeni işlem kullan" yanıtı geçerli mi? Teşekkürler ...
Radim Vansa

2
Windows 7'de değişiklik yok, üzgünüm. (Bildiğim kadarıyla ve
Win7'de

2
Görev yöneticisi bunu tam olarak böyle yapar. Tüm kullanıcılara görevleri göstermek için düğmeye tıkladığınızda, mevcut görev yöneticisi vardır ve ardından yönetici haklarına sahip başka bir görev yöneticisini çağırır.
Natalie Adams

3
@NathanAdams Teknik olarak önce yeni görev yöneticisini açar. Aksi takdirde, açılış ne yapıyor? :-)
wizzwizz4

16

Orada söylendiği gibi :

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

kayıt defterinde ihtiyacınız olan her şeyi yapmak için işlemi yönetici olarak çalıştıracak, ancak normal ayrıcalıklarla uygulamanıza dönecektir.


Bu, yeni bir süreci kapsamayı içerir. sağ? Mevcut sürecin kendisinin ayrıcalıklarını yükseltmeyi arıyordum.
Hemant

Process.GetCurrentProcess () için kullanmayı deneyin
abatishchev

27
Şu anda çalışan bir işlemi yükseltemezsiniz.
Jacob Proffitt

1
Bu doğru değil. Sürecin Sahibini değiştirebilir ve kullanıcıya yönetici yetkileri vererek DACL ve ACL değerlerini ayarlayabilirsiniz ....
Nightforce2

4
@ nightforce2: elbette bu sadece yönetici haklarına sahipseniz (yani zaten yükselmişseniz) işe yarar. Aksi takdirde AdjustTokenPrivileges vb. Basitçe başarısız olur, değil mi?
Ben Schwehn

13

Aşağıdaki 981778 MSDN KB makalesi, bir uygulamanın nasıl 'kendi kendine yükseltileceğini' açıklar:

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

Visual C ++, Visual C #, Visual Basic.NET'te indirilebilir örnekler içerir.

Bu yaklaşım, ayrı bir işlem başlatma ihtiyacını ortadan kaldırır, ancak gerçekte, yükseltilmiş bir kullanıcı olarak çalışan, yeniden başlatılan orijinal uygulamadır. Yine de bu, kodu ayrı bir yürütülebilir dosyada çoğaltmanın pratik olmadığı bazı bağlamlarda yine de çok yararlı olabilir.

Yüksekliği kaldırmak için uygulamadan çıkmanız gerekir.


1
Bir düğme için kullanışlı, ancak bir menü öğesi için aynısını istediğinizde, gerçekten karmaşık bir karmaşa içindesiniz.
Nyerguds


Yanıtlayanın bağlantısı kesildi ve yorumun bağlantısı 2608 öğelik bir listeye işaret ediyor.
DonBoitnott



2

Belki birileri işe yarar bu basit örnek:

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);
            }
        }

    }
}

1

Bunun eski bir gönderi olduğunu biliyorum, ancak bu, MarcP'nin önerisiyle karşılaşan herhangi birine yanıt olarak. Başvurduğu msdn gönderisi gerçekten de tüm kod örneklerindeki uygulamaları yeniden başlatıyor. Kod örnekleri runas, diğer önerilerde zaten önerilen fiili kullanır .

Emin olmak için kodu indirdim, ancak bu orijinal msdn makalesinden:

4. Yükseltmeyi onaylamak için Evet'e tıklayın. Ardından, orijinal uygulama, yükseltilmiş bir yönetici olarak çalışarak yeniden başlatılır.
5. Uygulamayı kapatın.


1
Söz konusu MSDN bağlantısını ekleyebilir misiniz? MarcP adında bir kullanıcı bulamıyorum.
Alf
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.