2010-06-27 6 views
10

विंडोज विस्टा/7/2008/2008R2 में, क्या किसी सेवा से उपयोगकर्ता के सत्र में प्रक्रिया शुरू करना संभव है? विशेष रूप से, स्थानीय सत्र सबसे उपयोगी होगा।किसी सेवा से उपयोगकर्ता के सत्र में एक प्रक्रिया लॉन्च करना

जो कुछ भी मैं पढ़ रहा हूं, ऐसा लगता है कि यह संभव नहीं है, लेकिन मुझे लगा कि मैं पूरी तरह से छोड़ने से पहले यहां पूछूंगा।

मैं वीबी.नेट में कोडिंग कर रहा हूं, लेकिन कुछ भी सुझाव लेगा।

+0

जो उपयोगकर्ता के सत्र Win7 और Win10 पर काम करता है सायन? –

+0

स्थानीय इंटरैक्टिव उपयोगकर्ता जो मैं केंद्रित कर रहा हूं। मैं मुख्य रूप से सेवा से वर्कस्टेशन को लॉक करने में रूचि रखता हूं, लेकिन कुछ स्थितियों के आधार पर अन्य कार्यक्रमों को निष्पादित करने की आवश्यकता भी है। – Brad

उत्तर

18

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

वैसे, यदि आप एक ऐसी सेवा लिखते हैं जो Windows XP के अंतर्गत चलती है जो किसी डोमेन में नहीं जोड़ा गया है और तेज़ उपयोगकर्ता स्विचिंग सक्रिय है, तो आपको दूसरी (तीसरी) पर चलने की प्रक्रिया शुरू करने के लिए एक ही समस्या हो सकती है और इतने पर) लॉग इन उपयोगकर्ता डेस्कटॉप।

मुझे आशा है कि आपके पास उपयोगकर्ता टोकन है, जिसे आप प्रतिरूपण के संबंध में उदाहरण के लिए प्राप्त करते हैं या आपके पास dwSessionId सत्र है। आप इसे नहीं है, तो आप इसी उपयोगकर्ताओं सत्र (LsaEnumerateLogonSessionshttp://msdn.microsoft.com/en-us/library/aa378275.aspx देख सकते हैं और LsaGetLogonSessionDatahttp://msdn.microsoft.com/en-us/library/aa378290.aspx देखें) या ProcessIdToSessionId पता लगाने के लिए कुछ WTS-समारोह (दूरस्थ डेस्कटॉप सेवा API http://msdn.microsoft.com/en-us/library/aa383464.aspx, उदाहरण के WTSEnumerateProcesses या WTSGetActiveConsoleSessionId के लिए) या एलएसए-एपीआई का उपयोग कोशिश कर सकते हैं (http://msdn.microsoft.com/en-us/library/aa382990.aspx देखें)।

आप जानता है उन hClient टोकन उपयोगकर्ताओं सत्र के सत्र id dwSessionId प्राप्त करने के लिए पैरामीटर TokenSessionId (देखें http://msdn.microsoft.com/en-us/library/aa446671.aspx) के साथ GetTokenInformation फ़ंक्शन का उपयोग कर सकते हैं।

BOOL bSuccess; 
HANDLE hProcessToken = NULL, hNewProcessToken = NULL; 
DWORD dwSessionId, cbReturnLength; 

bSuccess = GetTokenInformation (hClient, TokenSessionId, &dwSessionId, 
           sizeof(DWORD), &cbReturnLength); 
bSuccess = OpenProcessToken (GetCurrentProcess(), MAXIMUM_ALLOWED, &hProcessToken); 
bSuccess = DuplicateTokenEx (hProcessToken, MAXIMUM_ALLOWED, NULL, 
          SecurityImpersonation, 
          TokenPrimary, &hNewProcessToken); 
EnablePrivilege (SE_TCB_NAME); 
bSuccess = SetTokenInformation (hNewProcessToken, TokenSessionId, &dwSessionId, 
           sizeof(DWORD)); 
bSuccess = CreateProcessAsUser (hNewProcessToken, NULL, szCommandToExecute, ...); 

यह कोड केवल एक स्कीमा है। EnablePrivilegeAdjustTokenPrivileges का उपयोग करने के लिए SE_TCB_NAME विशेषाधिकार सक्षम करने के लिए एक साधारण फ़ंक्शन है (देखें http://msdn.microsoft.com/en-us/library/aa446619.aspx टेम्पलेट के रूप में)। यह महत्वपूर्ण है कि जिस प्रक्रिया से आप एक प्रक्रिया शुरू कर रहे हैं, आपके पास टीसीबी विशेषाधिकार है, लेकिन यदि आपकी सेवा स्थानीय सिस्टम के अंतर्गत चलती है तो आपके पास पर्याप्त अनुमतियां हैं। वैसे, कोड कोड खंड न केवल स्थानीय सिस्टम खाते के साथ काम करता है, लेकिन खाते में मौजूदा टर्मिनल सर्वर सत्र को स्विच करने में सक्षम होने के लिए SE_TCB_NAME विशेषाधिकार होना चाहिए।

एक और टिप्पणी। उपर्युक्त कोड में हम उसी प्रक्रिया के साथ नई प्रक्रिया शुरू करते हैं क्योंकि वर्तमान प्रक्रिया में (उदाहरण के लिए स्थानीय सिस्टम) है। आप दूसरे खाते का उपयोग करने के लिए एक कोड बदलते हैं उदाहरण के लिए उपयोगकर्ता टोकन hClientprimary token होना केवल महत्वपूर्ण है। यदि आपके पास प्रतिरूपण टोकन है तो आप उपरोक्त कोड में जैसे प्राथमिक टोकन में इसे परिवर्तित कर सकते हैं।

CreateProcessAsUser में इस्तेमाल STARTUPINFO संरचना में आप lpDesktop = WinSta0 \ डिफ़ॉल्ट "का उपयोग करना चाहिए।

अपनी आवश्यकताओं को यह भी CreateEnvironmentBlock उपयोग करने के लिए एक नए माहौल ब्लॉक है कि आप नए के लिए गुजर रहा हो जाएगा बनाने के लिए आवश्यक हो सकता है पर निर्भर प्रक्रिया।

मैं तुम्हें सलाह देते हैं भी How to ensure process window launched by Process.Start(ProcessStartInfo) has focus of all Forms? को पढ़ने के लिए है, जहां मैं मजबूर करने के लिए कैसे है कि इस प्रक्रिया उन डेस्कटॉप पर अग्रभूमि में शुरू हो जाएगा का वर्णन।

+0

मैं अभी एक ऐसी समस्या के माध्यम से काम कर रहा हूं जो मुझे एक सेवा के साथ कर रहा था, और यह आपका जवाब यहां मिला ... बहुत उपयोगी। मेरे मामले में, जब मैं अपनी तैयार प्रक्रिया से फ़ाइल-ओपन डायलॉग चलाता था तो मुझे एक परेशान "पहुंच से वंचित" त्रुटि मिल रही थी (अन्यथा संवाद ठीक काम करता था)। 'CreateEnvironmentBlock' को कॉल करना और परिणाम को' CreateProcessAsUser' को पास करना प्रतीत होता है। क्या मुझे वास्तव में अपने 'STARTUPINFO' संरचना के 'lpDesktop' मान को सेट करने की आवश्यकता है? मैंने इसे अभी तक नल के रूप में छोड़ा। साथ ही, यह SE_TCB_NAME विशेषाधिकार को सेट किए बिना काम किया। – paddy

+0

@paddy: क्षमा करें, लेकिन यदि आपके पास कुछ सामान्य मामला है तो सभी चरणों की वास्तव में आवश्यकता है। यदि सेवा कुछ उपयोगकर्ता खाते के तहत चलती है और सिस्टम के रूप में नहीं है तो आपको इंटरैक्टिव उपयोगकर्ता को प्रारंभिक प्रक्रिया की विंडो देखने में सक्षम बनाने के लिए वास्तव में 'टोकन सत्र आईडी' सेट करना होगा। 'TokenSessionId' के साथ 'SetTokenInformation' का उपयोग करने में सक्षम होने के लिए सेवा खाते में वास्तव में' SE_TCB_NAME' विशेषाधिकार होना आवश्यक है और उसे सक्षम करना होगा। यदि स्क्रीन सेवर प्रक्रिया शुरू करने के समय काम करता है तो उसे स्क्रीन सेवर या डिफ़ॉल्ट उपयोगकर्ता डेस्कटॉप के डेस्कटॉप को देखने के लिए 'lpDesktop' सेट करना चाहिए। – Oleg

3

हां, CreateProcessAsUser का उपयोग करके आप यह कर सकते हैं। एमएसडीएन में नमूना लेख हैं, और कुछ चेतावनी हैं।

+0

कृपया उन संस्करणों के साथ एमएसडीएन लिंक पोस्ट न करें जब तक कि उस संस्करण का हमेशा उपयोग करने का कोई कारण न हो। –

+0

क्या करेंगे, जॉन। सुधारों के लिए धन्यवाद। – holtavolt

+0

धन्यवाद, मैं अब .NET के लिए एपीआई घोषणाओं पर काम कर रहा हूं। – Brad

3

यह किया जा सकता है लेकिन उपयोगकर्ताओं के सत्रों के साथ सीधे बातचीत करने के लिए सेवाओं के लिए अच्छा अभ्यास नहीं माना जाता क्योंकि यह गंभीर सुरक्षा छेद बना सकता है।

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

एक बेहतर दृष्टिकोण 2 कार्यक्रम, एक बैकएंड सेवा और एक सामने अंत ग्राहक यूआई कार्यक्रम तैयार करना है। सेवा बैकएंड हर समय चलता है और डब्ल्यूसीएफ (उदाहरण के लिए) का उपयोग करके अपने परिचालन का खुलासा करता है। क्लाइंट प्रोग्राम उपयोगकर्ता के सत्र के स्टार्टअप पर चलाया जा सकता है।

+0

मुझे विश्वास नहीं है कि आपके द्वारा लिंक किए गए लेख की सामग्री अभी भी 2008 (आर 2) के लिए मान्य है। सत्र शून्य अलगाव एट अल ... –

+1

यह वही बात नहीं है। ब्रैड उपयोगकर्ता के प्रमाण-पत्रों के साथ एक/नई/प्रक्रिया बनाने के बारे में पूछ रहा है, सेवा प्रक्रिया के रूप में उपयोगकर्ता के सत्र में इंटरैक्टिव संचालन नहीं कर रहा है। –

+1

उपयोगकर्ता के सत्र में प्रक्रियाओं को लॉन्च करना अभी भी उपयोगकर्ता के डेस्कटॉप से ​​बातचीत कर रहा है। बालों को विभाजित न करें, यह अभी भी अच्छा अभ्यास नहीं है। लिंक सबसे अच्छा मैं सहमत नहीं था :) –

4

यदि यह मदद करता है, मैं एक ऐसी ही समस्या, ख का सामना करना पड़ा एक शुद्ध शक्तिशक्ति समाधान चाहता था।

मैं एक साथ अन्य वेबसाइटों से बिट्स पत्थर है और इस के साथ आया था:

function Invoke-CommandInSession 
{ 
    [CmdletBinding()] 
    param(
     [Parameter(Mandatory = $true)] 
     [ValidateNotNullOrEmpty()] 
     [ScriptBlock] $expression 
    ) 

    $commandLine = “powershell“ 

    ## Convert the command into an encoded command for PowerShell 
    $commandBytes = [System.Text.Encoding]::Unicode.GetBytes($expression) 
    $encodedCommand = [Convert]::ToBase64String($commandBytes) 
    $args = “-Output XML -EncodedCommand $encodedCommand” 


    $action = New-ScheduledTaskAction -Execute $commandLine -Argument $args 
    $setting = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter ([Timespan]::Zero) 
    $trigger = New-ScheduledTaskTrigger -Once -At ((Get-Date) + ([Timespan]::FromSeconds(5))) 
    $task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $setting 
    Register-ScheduledTask "Invoke-CommandInSession - $([Guid]::NewGuid())" -InputObject $task 
} 

हाँ, इसकी एक छोटे से अजीब है, लेकिन यह काम करता है - और सबसे महत्वपूर्ण बात आप ps दूरस्थ भीतर से यह कॉल कर सकते हैं

संबंधित मुद्दे