c# - व्यवस्थापक विशेषाधिकारों के साथ प्रक्रिया से व्यवस्थापक विशेषाधिकारों के बिना एक नई प्रक्रिया कैसे शुरू करें?




windows administrator (6)

आप CreateProcessWithLogonW फ़ंक्शन या समान CreateProcessAsUser और CreateProcessWithTokenW उपयोग कर सकते हैं।

मैं एक आवेदन के लिए एक स्वचालित अद्यतनकर्ता बना रहा हूँ। एप्लिकेशन उपयोगकर्ता द्वारा शुरू किया गया है, और व्यवस्थापक विशेषाधिकारों के बिना चलता है। ऑटोपॉटर प्रशासक विशेषाधिकारों के साथ शुरू किया गया है, और नई फ़ाइलों को डाउनलोड करने से पहले एप्लिकेशन को मार देता है।

समस्या तब आती है जब मैं ऑटोपॉटर समाप्त होने के बाद अद्यतन एप्लिकेशन शुरू करना चाहता हूं। अगर मैं नियमित सिस्टम का उपयोग करता हूं। डायग्नोस्टिक्स.प्रोसेस.स्टार्ट (फ़ाइल), एप्लिकेशन प्रशासक विशेषाधिकारों के साथ भी शुरू होता है, और इसे मौजूदा उपयोगकर्ता को इरादे के अनुसार काम करने के लिए चलाना पड़ता है।

तो, मैं autoupdater को व्यवस्थापक के बजाय वर्तमान उपयोगकर्ता के रूप में एप्लिकेशन कैसे शुरू कर सकता हूं?

मैंने निम्नलिखित का उपयोग करने का प्रयास किया है:

var pSI = new ProcessStartInfo() { 
    UseShellExecute = false, 
    UserName = Environment.UserName, 
    FileName = file 
};
System.Diagnostics.Process.Start(pSI);

लेकिन यह त्रुटि "अवैध उपयोगकर्ता नाम या पासवर्ड" फेंकता है। मैंने जांच की है कि उपयोगकर्ता नाम सही है, और मैं समझता हूं कि पासवर्ड शायद अमान्य है, क्योंकि मैंने इसे शामिल नहीं किया है। लेकिन उपयोगकर्ता को अपना पासवर्ड इनपुट करने का यह विकल्प नहीं है, क्योंकि एप्लिकेशन को स्वचालित रूप से शुरू करने का पूरा कारण उपयोगकर्ता के लिए इसे आसान बनाना है।

कोई सुझाव?


उन्नत माता-पिता प्रक्रिया से डिफ़ॉल्ट खोल अनुमतियों के साथ प्रक्रिया शुरू करने के लिए व्यावहारिक VB.NET कोड

#Region "References"

Imports System.Runtime.InteropServices

#End Region

Public Class LaunchProcess

#Region "Native Methods"

    <DllImport("User32.dll", SetLastError:=True)> Private Shared Function GetShellWindow() As IntPtr
    End Function

    <DllImport("advapi32.dll", SetLastError:=True)> Private Shared Function OpenProcessToken(ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As IntPtr) As Boolean
    End Function

    <DllImport("user32.dll", SetLastError:=True)> Private Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessId As IntPtr) As Integer
    End Function

    <DllImport("kernel32.dll")> Private Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandle As Boolean, ByVal dwProcessId As IntPtr) As IntPtr
    End Function

    <DllImport("advapi32.dll", SetLastError:=True)> _
    Private Shared Function DuplicateTokenEx( _
    ByVal ExistingTokenHandle As IntPtr, _
    ByVal dwDesiredAccess As UInt32, _
    ByRef lpThreadAttributes As SECURITY_ATTRIBUTES, _
    ByVal ImpersonationLevel As Integer, _
    ByVal TokenType As Integer, _
    ByRef DuplicateTokenHandle As System.IntPtr) As Boolean
    End Function

    <DllImport("advapi32.dll", SetLastError:=True)> Private Shared Function LookupPrivilegeValue(lpSystemName As String, lpName As String, ByRef lpLuid As LUID) As Boolean
    End Function

    <DllImport("advapi32.dll", SetLastError:=True)> _
    Private Shared Function AdjustTokenPrivileges( _
    ByVal TokenHandle As IntPtr, _
    ByVal DisableAllPrivileges As Boolean, _
    ByRef NewState As TOKEN_PRIVILEGES, _
    ByVal BufferLengthInBytes As Integer, _
    ByRef PreviousState As TOKEN_PRIVILEGES, _
    ByRef ReturnLengthInBytes As Integer _
  ) As Boolean
    End Function

    <DllImport("advapi32", SetLastError:=True, CharSet:=CharSet.Unicode)> Private Shared Function CreateProcessWithTokenW(hToken As IntPtr, dwLogonFlags As Integer, lpApplicationName As String, lpCommandLine As String, dwCreationFlags As Integer, lpEnvironment As IntPtr, lpCurrentDirectory As IntPtr, ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As PROCESS_INFORMATION) As Boolean
    End Function

#End Region

#Region "Structures"

    <StructLayout(LayoutKind.Sequential)> Private Structure SECURITY_ATTRIBUTES

        Friend nLength As Integer
        Friend lpSecurityDescriptor As IntPtr
        Friend bInheritHandle As Integer

    End Structure

    Private Structure TOKEN_PRIVILEGES

        Friend PrivilegeCount As Integer
        Friend TheLuid As LUID
        Friend Attributes As Integer

    End Structure

    Private Structure LUID

        Friend LowPart As UInt32
        Friend HighPart As UInt32

    End Structure

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> Private Structure STARTUPINFO

        Friend cb As Integer
        Friend lpReserved As String
        Friend lpDesktop As String
        Friend lpTitle As String
        Friend dwX As Integer
        Friend dwY As Integer
        Friend dwXSize As Integer
        Friend dwYSize As Integer
        Friend dwXCountChars As Integer
        Friend dwYCountChars As Integer
        Friend dwFillAttribute As Integer
        Friend dwFlags As Integer
        Friend wShowWindow As Short
        Friend cbReserved2 As Short
        Friend lpReserved2 As Integer
        Friend hStdInput As Integer
        Friend hStdOutput As Integer
        Friend hStdError As Integer

    End Structure

    Private Structure PROCESS_INFORMATION

        Friend hProcess As IntPtr
        Friend hThread As IntPtr
        Friend dwProcessId As Integer
        Friend dwThreadId As Integer

    End Structure

#End Region

#Region "Enumerations"

    Private Enum TOKEN_INFORMATION_CLASS

        TokenUser = 1
        TokenGroups
        TokenPrivileges
        TokenOwner
        TokenPrimaryGroup
        TokenDefaultDacl
        TokenSource
        TokenType
        TokenImpersonationLevel
        TokenStatistics
        TokenRestrictedSids
        TokenSessionId
        TokenGroupsAndPrivileges
        TokenSessionReference
        TokenSandBoxInert
        TokenAuditPolicy
        TokenOrigin
        TokenElevationType
        TokenLinkedToken
        TokenElevation
        TokenHasRestrictions
        TokenAccessInformation
        TokenVirtualizationAllowed
        TokenVirtualizationEnabled
        TokenIntegrityLevel
        TokenUIAccess
        TokenMandatoryPolicy
        TokenLogonSid
        MaxTokenInfoClass

    End Enum

#End Region

#Region "Constants"

    Private Const SE_PRIVILEGE_ENABLED = &H2L
    Private Const PROCESS_QUERY_INFORMATION = &H400
    Private Const TOKEN_ASSIGN_PRIMARY = &H1
    Private Const TOKEN_DUPLICATE = &H2
    Private Const TOKEN_IMPERSONATE = &H4
    Private Const TOKEN_QUERY = &H8
    Private Const TOKEN_QUERY_SOURCE = &H10
    Private Const TOKEN_ADJUST_PRIVILEGES = &H20
    Private Const TOKEN_ADJUST_GROUPS = &H40
    Private Const TOKEN_ADJUST_DEFAULT = &H80
    Private Const TOKEN_ADJUST_SESSIONID = &H100
    Private Const SecurityImpersonation = 2
    Private Const TokenPrimary = 1
    Private Const SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege"

#End Region

#Region "Methods"

    Friend Shared Sub LaunchFile(ByVal FilePath As String, ByVal IsWaitToFinish As Boolean)

        Try

            'Enable the SeIncreaseQuotaPrivilege in current token
            Dim HPrcsToken As IntPtr = Nothing
            OpenProcessToken(Process.GetCurrentProcess.Handle, TOKEN_ADJUST_PRIVILEGES, HPrcsToken)

            Dim TokenPrvlgs As TOKEN_PRIVILEGES
            TokenPrvlgs.PrivilegeCount = 1
            LookupPrivilegeValue(Nothing, SE_INCREASE_QUOTA_NAME, TokenPrvlgs.TheLuid)
            TokenPrvlgs.Attributes = SE_PRIVILEGE_ENABLED

            AdjustTokenPrivileges(HPrcsToken, False, TokenPrvlgs, 0, Nothing, Nothing)

            'Get window handle representing the desktop shell
            Dim HShellWnd As IntPtr = GetShellWindow()

            'Get the ID of the desktop shell process
            Dim ShellPID As IntPtr
            GetWindowThreadProcessId(HShellWnd, ShellPID)

            'Open the desktop shell process in order to get the process token
            Dim HShellPrcs As IntPtr = OpenProcess(PROCESS_QUERY_INFORMATION, False, ShellPID)
            Dim HShellPrcSToken As IntPtr = Nothing
            Dim HPrimaryToken As IntPtr = Nothing

            'Get the process token of the desktop shell
            OpenProcessToken(HShellPrcs, TOKEN_DUPLICATE, HShellPrcSToken)

            'Duplicate the shell's process token to get a primary token
            Dim TokenRights As UInteger = TOKEN_QUERY Or TOKEN_ASSIGN_PRIMARY Or TOKEN_DUPLICATE Or TOKEN_ADJUST_DEFAULT Or TOKEN_ADJUST_SESSIONID
            DuplicateTokenEx(HShellPrcSToken, TokenRights, Nothing, SecurityImpersonation, TokenPrimary, HPrimaryToken)

            Dim StartInfo As STARTUPINFO = Nothing
            Dim PrcsInfo As PROCESS_INFORMATION = Nothing

            StartInfo.cb = Marshal.SizeOf(StartInfo)
            Dim IsSuccessed As Boolean = CreateProcessWithTokenW(HPrimaryToken, 1, FilePath, "", 0, Nothing, Nothing, StartInfo, PrcsInfo)

            If IsSuccessed = True Then

                If IsWaitToFinish = True Then

                    Try

                        Dim Prcs As Process = Process.GetProcessById(PrcsInfo.dwProcessId)
                        Prcs.WaitForExit()

                    Catch ex As Exception
                    End Try

                End If

            Else

                'Could not launch process with shell token may be the process needs admin rights to launch, we will try to launch it with default parent process permissions.

                Dim Prcs As New Process
                Prcs.StartInfo.FileName = FilePath
                Prcs.Start()

                If IsWaitToFinish = True Then Prcs.WaitForExit()

            End If

        Catch ex As Exception
        End Try

    End Sub

#End Region

End Class

लॉन्चप्रोसेस क्लास उपयोग

LaunchProcess.LaunchFile("C:\Program Files\Test\text.exe", False)

आप कोड को C # http://converter.telerik.com/ कनवर्ट करने के लिए टेलीरिक कोड कनवर्टर का उपयोग कर सकते हैं


जैसा कि लेखक का वर्णन है कि इस समस्या का समाधान नहीं हुआ है। मुझे अब भी यही समस्या है, मैं यह बताना चाहता हूं कि मैंने इसे कैसे हल किया।

जैसा कि आप जानते हैं कि यह इतना आसान नहीं है लेकिन सबसे अच्छा समाधान यह है कि आप किसी अन्य गैर-व्यवस्थापक प्रक्रिया द्वारा "* .exe" फ़ाइल शुरू करने के लिए कंप्यूटर को मजबूर करते हैं। मैं जो करता हूं वह without Highest Privilege पैरामीटर्स के without Highest Privilege कार्य शेड्यूलर पर एक कार्य बना रहा था, इसका मतलब है कि समय बनाना या मैन्युअल रूप से यह कार्य चलाएं।

यह बेवकूफ लगता है लेकिन ऐसा लगता है कि कोई रास्ता नहीं है।

आप यह लिंक देख सकते हैं जो वर्णन करता है कि विंडोज़ कार्य शेड्यूलर पर नया कार्य कैसे बनाएं /


जो आप प्राप्त करने की कोशिश कर रहे हैं वह बहुत आसानी से नहीं किया जा सकता है और समर्थित नहीं है। हालांकि, हैकिंग के एक मोडिकम का उपयोग करना संभव है। हारून मार्गोसिस ने एक तकनीक का वर्णन करने वाला एक article लिखा था।

प्रासंगिक खंड को उद्धृत करने के लिए, आपको इन चरणों को पूरा करने की आवश्यकता होगी:

  1. अपने वर्तमान टोकन में SeIncreaseQuotaPrivilege को सक्षम करें
  2. डेस्कटॉप खोल का प्रतिनिधित्व करने वाला एक HWND प्राप्त करें (GetShellWindow)
  3. उस विंडो से जुड़े प्रक्रिया की प्रक्रिया आईडी (पीआईडी) प्राप्त करें (GetWindowThreadProcessId)
  4. उस प्रक्रिया को खोलें (ओपनप्रोसेस)
  5. उस प्रक्रिया से एक्सेस टोकन प्राप्त करें (OpenProcessToken)
  6. उस टोकन के साथ प्राथमिक टोकन बनाएं (डुप्लिकेट टोकनएक्स)
  7. उस प्राथमिक टोकन के साथ नई प्रक्रिया शुरू करें (CreateProcessWithTokenW)

आलेख में कुछ डेमो सी ++ स्रोत के लिए एक डाउनलोड लिंक शामिल है, जिससे इसे सी # में अनुवाद करने के लिए पर्याप्त सरल होना चाहिए।


यह मानते हुए कि आप इसे समाप्त करने के बजाए साफ-सफाई बंद करने के लिए एप्लिकेशन को सिग्नल कर रहे हैं, और यदि आप अभी भी अपने अपडेटर को रिहा करने से पहले एप्लिकेशन में बदलाव करने में सक्षम हैं, तो एक साधारण समाधान यह होगा कि एप्लिकेशन बाहर निकलने से पहले अंतरिम प्रक्रिया शुरू करे। आप एक अस्थायी स्थान में अंतरिम प्रक्रिया के लिए निष्पादन योग्य बना सकते हैं। जब अपडेट समाप्त हो जाता है, तो अनुप्रयोग को फिर से लॉन्च करने और बाहर निकलने के लिए अंतरिम प्रक्रिया को सिग्नल करें। इस तरह, सबकुछ स्वाभाविक रूप से होता है और आपको इसके बारे में गड़बड़ नहीं करना पड़ता है।

इसे मारने से पहले एप्लिकेशन की सुरक्षा टोकन की एक प्रति प्राप्त करने के लिए OpenProcess , OpenProcessToken टोकन और DuplicateToken टोकन का उपयोग करने का एक और विकल्प होगा। फिर आप मूल संदर्भ में एप्लिकेशन को पुन: लॉन्च करने के लिए CreateProcessAsUser का उपयोग कर सकते हैं।

इन दोनों दृष्टिकोणों को काम करना चाहिए भले ही अद्यतनकर्ता एक अलग खाते के तहत चल रहा हो और / या आवेदन के लिए एक अलग सत्र में।


यह वास्तव में एक पुराना सवाल है जिसे मैंने कई साल पहले देखा था और अब फिर से संशोधित किया है। चूंकि इसका पहला Google खोज परिणाम है ... मैं अपना उत्तर यहां पोस्ट करूंगा।

मेरे द्वारा मिले सभी समाधान बेहद जटिल और हास्यास्पद हैं। पिछले कुछ सालों में मैंने एक ऐसे समाधान पर ठोकर खाई है जिसे मैंने कहीं भी दस्तावेज नहीं देखा है, और अब तक वास्तव में साझा नहीं किया है।

कोड बहुत आसान है ... अनिवार्य रूप से हम जिस प्रक्रिया को आप चाहते हैं, उसके निष्पादन योग्य के नाम / पथ के साथ एक बैच फ़ाइल लिख रहे हैं, जो भी आप चाहते हैं। फिर हम बैच फ़ाइल के पथ के साथ explorer.exe प्रक्रिया को जन्म देते हैं ...

File.WriteAllText(@"C:\test.bat", @"C:\test.exe -randomArgs");

var proc = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "explorer.exe",
        Arguments = @"C:\test.bat",
        UseShellExecute = true,
        Verb = "runas",
        WindowStyle = ProcessWindowStyle.Hidden
    }
};
proc.Start();

एक्सप्लोरर प्रक्रिया जिसे हम पैदा करते हैं, तुरंत ऑपरेटिंग सिस्टम द्वारा बंद कर दिया जाता है, हालांकि! चल रही रूट explorer.exe प्रक्रिया बैच फ़ाइल चलाती है! आप explorer.exe को अपने निष्पादन योग्य नाम दे सकते हैं और यह वही काम करेगा, हालांकि यह विधि तर्कों का समर्थन नहीं करती है।

सभी के लिए मुझे पता है कि यह एक बग या अनियंत्रित सुविधा है। हालांकि मैं कल्पना नहीं कर सकता कि इसका दुर्भावनापूर्ण रूप से उपयोग कैसे किया जा सकता है, क्योंकि यह अनुमतियों को अपरिवर्तित करने की अनुमति देता है ... यह विंडोज 7/8 / 8.1 / 10 में काम करता है।





administrator