سؤال

لدي تطبيق يتكون من خدمة وقابلة للتنفيذ. إنه في الأساس تطبيق نماذج مسؤول عن بدء الخدمة وإيقافها في ظل ظروف محددة.

على Windows XP ، يدير التطبيق هذه الغرامة باستخدام الكود التالي:

ServiceController controller = new ServiceController();
controller.MachineName = ".";
controller.ServiceName = "XXXXXXXXXX";
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 10));
controller.Start();

لكن على Windows 7 ، على الرغم من أنني بدأت التطبيق كمسؤول ، أحصل على الاستثناء التالي:

System.InvalidOperationException: Cannot open XXXXXXXXXXXXX service on computer '.'. ---> System.ComponentModel.Win32Exception: Access is denied
   --- End of inner exception stack trace ---
   at System.ServiceProcess.ServiceController.GetServiceHandle(Int32 desiredAccess)
   at System.ServiceProcess.ServiceController.Start(String[] args)
   at System.ServiceProcess.ServiceController.Start()

هل هناك أي شيء يمكنني فعله برمجياً لحل هذا؟

هل كانت مفيدة؟

المحلول

عندما تقول أنك بدأت التطبيق كمسؤول ، هل تقصد بموجب حساب في مجموعة المسؤولين ، أو عبر موجه UAC الذي يطلب بيانات اعتماد المسؤول؟ بدون موجه بيانات اعتماد UAC (أو يتم تشغيله فعليًا كحساب المسؤول ، وليس حسابًا داخل مجموعة المسؤولين) ، فإن التطبيق الخاص بك لا يحتوي على أذونات لتعديل الخدمات ، وبالتالي فإن الاستثناء الذي تراه صحيحًا.

يمكن أن يتحقق هذا الجزء من رمز المثال ما إذا كان تطبيقك يعمل كمسؤول ، وإذا لم يكن الأمر كذلك ، قم بتشغيل موجه UAC.

public static class VistaSecurity
{
    public static bool IsAdministrator()
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();

        if (null != identity)
        {
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        return false;
    }

    public static Process RunProcess(string name, string arguments)
    {
        string path = Path.GetDirectoryName(name);

        if (String.IsNullOrEmpty(path))
        {
            path = Environment.CurrentDirectory;
        }

        ProcessStartInfo info = new ProcessStartInfo
        {
            UseShellExecute = true,
            WorkingDirectory = path,
            FileName = name,
            Arguments = arguments
        };

        if (!IsAdministrator())
        {
            info.Verb = "runas";
        }

        try
        {
            return Process.Start(info);
        }

        catch (Win32Exception ex)
        {
            Trace.WriteLine(ex);
        }

        return null;
    }
}

نصائح أخرى

يمكنك أيضًا محاولة إعداد UAC لتطبيقك إلى "تشغيل كمسؤول" في الكود.

لمعلوماتك ، إذا كنت لا تفهم سبب عدم عملها في Vista أو 7 حتى لو كان المستخدم الحالي في مجموعة المسؤول ، فإليك ما يقوله MSDN

في Windows Vista ، يحدد التحكم في حساب المستخدم (UAC) امتيازات المستخدم. إذا كنت عضوًا في مجموعة المسؤولين المدمجة ، فسيتم تعيين رموز الوصول إلى وقت التشغيل: رمز وصول المستخدم القياسي ورمز وصول المسؤول. بشكل افتراضي ، أنت في دور المستخدم القياسي. عندما تحاول تنفيذ مهمة تتطلب امتيازات إدارية ، يمكنك رفع دورك ديناميكيًا باستخدام مربع الحوار الموافقة. لا يعرض الرمز الذي ينفذ طريقة Isinrole مربع الحوار الموافقة. يعيد الرمز خطأ إذا كنت في دور المستخدم القياسي ، حتى لو كنت في مجموعة المسؤولين المدمجة. يمكنك رفع امتيازاتك قبل تنفيذ الرمز بالنقر بزر الماوس الأيمن على أيقونة التطبيق والإشارة إلى أنك تريد تشغيلها كمسؤول.

أتذكر أنني فوجئت في المركز الأول عند استخدام 7 (لم أستخدم فيستا أبدًا).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top