2009-09-08 15 views
5

में मैंने यह पूछा है कि मैंने CreateDesktop() with Vista UAC (C Windows) में यह एक बाउंटी सेट किया है, लेकिन केवल जवाब देने का प्रयास करने में "स्वीकृति" गलती से दबाया गया था (मैं जाग गया हूं 48 एचएस से अधिक)। तो मैं इसे फिर से पूछ रहा हूँ।विस्टा और यूएसी (सी, विंडोज़)

मैं एक अस्थायी डेस्कटॉप जहां एक आवेदन चलेंगे बनाने के लिए CreateDesktop() का उपयोग कर रहा है, एक सफाई क्रिया को निष्पादित (रास्ते से बाहर रहते हुए) और समाप्त। आवेदन समाप्त होने के बाद मैं उस डेस्कटॉप को बंद कर रहा हूं। Windows XP और यहां तक ​​कि Vista का उपयोग करते समय सब कुछ ठीक है। समस्या तब उत्पन्न होती है जब आप (परेशान) यूएसी सक्षम करते हैं।

सब कुछ ठीक है जब आप एक डेस्कटॉप बनाने के लिए, लेकिन जब आप CreateProcess फोन() कि डेस्कटॉप यह User32.dll पर एक अपवाद के साथ दुर्घटना के लिए खोला आवेदन का कारण बनता है पर एक कार्यक्रम को खोलने के लिए।

मैं विंडोज पर विभिन्न डेस्कटॉप और परतों और स्मृति के प्रतिबंध के बारे में एक बहुत कुछ पढ़ रहा है। हालांकि, अधिकांश कार्यक्रम जो मैं खोलता हूं (परीक्षण परिदृश्य के रूप में) ठीक है, लेकिन कुछ (जैसे आईई, नोटपैड, कैल्क और मेरा स्वयं का एप्लीकेशन) दुर्घटना का कारण बनता है।

किसी को भी कोई विचार है कि यह यूएसी के साथ Vista पर क्यों होता है, या विशेष रूप से उन विशिष्ट कार्यक्रमों के लिए? और इसे कैसे ठीक करें?

किसी को भी कैसे एक डेस्कटॉप बना सकते हैं और पर यूएसी के साथ विस्टा के अंतर्गत यह पर स्विच किए बिना वहाँ एक आवेदन को खोलने के लिए पर एक अच्छा ठोस उदाहरण है?

कोड की सराहना की जाती है।

धन्यवाद

इस्तेमाल किया कोड

SECURITY_ATTRIBUTES sa; 

HDESK dOld; 
HDESK dNew; 

BOOL switchdesk, switchdesk2, closedesk; 
int AppPid; 

sa.bInheritHandle = TRUE; 
sa.lpSecurityDescriptor = NULL; 
sa.nLength = sizeof(SECURITY_ATTRIBUTES); 

//Get handle to current desktop 
dOld = OpenDesktopA("default", 0, TRUE, DESKTOP_SWITCHDESKTOP| 
             DESKTOP_WRITEOBJECTS| 
             DESKTOP_READOBJECTS| 
             DESKTOP_ENUMERATE| 
             DESKTOP_CREATEWINDOW| 
             DESKTOP_CREATEMENU); 
if(!dOld) 
{ 
    printf("Failed to get current desktop handle !!\n\n"); 
    return 0; 
} 

//Make a new desktop 
dNew = CreateDesktopA("kaka", 0, 0, 0, DESKTOP_SWITCHDESKTOP| 
              DESKTOP_WRITEOBJECTS| 
              DESKTOP_READOBJECTS| 
              DESKTOP_ENUMERATE| 
              DESKTOP_CREATEWINDOW| 
              DESKTOP_CREATEMENU, &sa); 

if(!dNew) 
{ 
    printf("Failed to create new desktop !!\n\n"); 
    return 0; 
} 

AppPid = PerformOpenApp(SomeAppPath); 
if(AppPid == 0) 
{ 
    printf("failed to open app, err = %d\n", GetLastError()); 
} 
else 
{ 
    printf("App pid = %d\n", AppPid); 
} 


closedesk = CloseDesktop(dNew); 

if(!closedesk) 
{ 
    printf("Failed to close new desktop !!\n\n"); 
    return 0; 
} 


return 0; 
+0

क्या आप इसे यूआई थ्रेड में कर रहे हैं? – Isaac

+0

मतलब? मेरा मतलब है, मैं एप्लिकेशन के मुख्य धागे से CreateDesktop को कॉल कर रहा हूं – wonderer

+0

एक स्टैक ट्रेस भी बहुत मददगार होगा – jcopenha

उत्तर

4

आप IE में एक बग भर में आ गए हैं करने के लिए के रूप में यह यूएसी साथ सूचना का आदान दिखाई देते हैं। यदि संरक्षित मोड आपके लिए सेट है, तो डिफ़ॉल्ट को छोड़कर किसी भी डेस्कटॉप में IE को सामान्य उपयोगकर्ता के रूप में नहीं चलाया जा सकता है। एक वैकल्पिक डेस्कटॉप में आईई चलाने के लिए आपको व्यवस्थापक के रूप में चलाना होगा या संरक्षित मोड को बंद करना होगा। यह Vista, W2K8 और Win7 के लिए सच है।

अन्य प्रोग्रामों के रूप में जिन्हें आप नहीं चला सकते हैं, दुर्भाग्य से मैं कुछ भी पुष्टि नहीं कर सकता। मैंने नोटपैड, कैल्क, सभी ऑफिस ऐप्स, विजुअल स्टूडियो 2005, 2008 और 2010, एमएसडीएन सहायता और कई अन्य लोगों सहित तीस अलग-अलग कार्यक्रमों की कोशिश की और सभी आईई के उल्लेखनीय अपवाद के साथ अपेक्षित काम करते थे। क्या आपके ऐप के बारे में कुछ सचमुच असामान्य है जो इसे अप्रत्याशित तरीके से व्यवहार कर सकता है?

एक नोट - यदि आप इस तरह के किसी एप्लिकेशन को चलाने की कोशिश करते हैं जिसके लिए ऊंचाई (जैसे regedit, आदि) की आवश्यकता है तो यह अंतिम त्रुटि सेट ERROR_ELEVATION_REQUIRED पर CreateProcess में विफल हो जाएगी।

आपके संदर्भ के लिए, मामले मैं कुछ आप से अलग कर रहा हूँ में, कोड मैं प्रयोग किया जाता है:

#ifndef _WIN32_WINNT   // Specifies that the minimum required platform is Windows Vista. 
#define _WIN32_WINNT 0x0600  // Change this to the appropriate value to target other versions of Windows. 
#endif 

#include <stdio.h> 
#include <tchar.h> 

#include "windows.h" 

HANDLE PerformOpenApp(TCHAR* appPath); 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HDESK dNew; 
    BOOL closedesk; 
    HANDLE hApp; 

    //Make a new desktop 
    dNew = CreateDesktop(_T("kaka"), 0, 0, 0, DESKTOP_SWITCHDESKTOP| 
               DESKTOP_WRITEOBJECTS| 
               DESKTOP_READOBJECTS| 
               DESKTOP_ENUMERATE| 
               DESKTOP_CREATEWINDOW| 
               DESKTOP_CREATEMENU, NULL); 

    if(!dNew) 
    { 
     _tprintf(_T("Failed to create new desktop !!\n\n")); 
     return 0; 
    } 

    TCHAR path[MAX_PATH]; 
    _putts(_T("Enter the path of a program to run in the new desktop:\n")); 
    _getts(path); 

    while(_tcslen(path) > 0) 
    { 
     hApp = PerformOpenApp(path); 
     if(hApp == 0) 
     { 
      _tprintf(_T("Failed to open app, err = %d\n"), GetLastError()); 
     } 
     else 
     { 
      _tprintf(_T("App pid = %d\n"), GetProcessId(hApp)); 
      _putts(_T("Press any key to close the app.\n")); 
      _gettchar(); 
      TerminateProcess(hApp, 0); 
      CloseHandle(hApp); 
     } 
     _putts(_T("Enter the path of a program to run in the new desktop:\n")); 
     _getts(path); 
    } 

    closedesk = CloseDesktop(dNew); 

    if(!closedesk) 
    { 
     _tprintf(_T("Failed to close new desktop !!\n\n")); 
     return 0; 
    } 
    return 0; 
} 

HANDLE PerformOpenApp(TCHAR* appPath) 
{ 
    STARTUPINFO si = {0}; 
    PROCESS_INFORMATION pi; 

    si.cb = sizeof(si); 
    si.lpDesktop = _T("kaka"); 

    BOOL retVal = CreateProcess(NULL, appPath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, 
     NULL, &si, &pi); 

    if (retVal) 
    { 
     CloseHandle(pi.hThread); 
    } 
    return pi.hProcess; 
} 
+0

यह अजीब बात है क्योंकि मुझे विंडोज 7 के साथ कोई समस्या नहीं है, आईई नहीं, मेरा ऐप – wonderer

+0

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

+0

बस पूर्णता के लिए इस प्रश्न को स्वचालित रूप से उत्तर दिया गया था। यह एक जवाब नहीं है। मैंने इसे जवाब के रूप में सेट नहीं किया। – wonderer

9

सही समाधान ऊपर ChristianWimmer द्वारा एक लघु टिप्पणी के रूप में दिया जाता है:

डेस्कटॉप में एक सुरक्षा डिस्क्रिप्टर होना चाहिए जो आईई जैसे कम अखंडता स्तर तक पहुंच की अनुमति देता है। अन्यथा जीयूआई डेस्कटॉप तक नहीं पहुंच सकता है।- ChristianWimmer जुला 22 '10 17:00

पर के बाद से इस सवाल का जवाब एक छोटा सा छिपा हुआ है और वहाँ कोई स्रोत कोड उदाहरण है, मुझे यह स्पष्ट रूप से यहाँ राज्य करते हैं:

आईई तो सुरक्षित मोड में चलाता है ब्राउज़र टैब कम अखंडता प्रक्रियाओं के रूप में बनाए जाते हैं। कम अखंडता टैब प्रक्रिया प्रारंभ करने में विफल हो जाएगी यदि डेस्कटॉप में कम अखंडता अनिवार्य लेबल नहीं है।

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

मैंने डिफ़ॉल्ट डेस्कटॉप के अखंडता स्तर की जांच की, और वास्तव में मैं यह सत्यापित करने में सक्षम था कि डिफ़ॉल्ट डेस्कटॉप में कम अखंडता स्तर है! इसलिए समस्या का सबसे आसान समाधान है (1) नया डेस्कटॉप बनाएं, (2) डिफ़ॉल्ट डेस्कटॉप से ​​अनिवार्य लेबल प्राप्त करें, और (3) इसे नए डेस्कटॉप में कॉपी करें। सही समाधान करने के लिए संकेत प्रदान करने के लिए धन्यवाद: के लिए (2) और (3), तो आपको निम्न कोड का उपयोग कर सकते

PACL pSacl; 
PSECURITY_DESCRIPTOR pSecurityDescriptor; 
DWORD dwResult; 

dwResult = GetSecurityInfo(hDefaultDesktop, SE_WINDOW_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, &pSacl, &pSecurityDescriptor); 

if (dwResult == ERROR_SUCCESS) { 
    if (pSacl != NULL) { 
     dwResult = SetSecurityInfo(hNewDesktop, SE_WINDOW_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl); 

     if (dwResult != ERROR_SUCCESS) 
      _tprintf(_T("SetSecurityInfo(hNewDesktop) failed, error = %d"), dwResult); 
    } 

    LocalFree(pSecurityDescriptor); 
} else { 
    _tprintf(_T("GetSecurityInfo(hDefaultDesktop) failed, error = %d"), dwResult); 
} 

@CristianWimmer। यह मेरे बहुत समय बचाया !!

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