2010-10-01 21 views
5

HI,विंडोज 7

पर विंडोज़ सेवा से डेस्कटॉप एप्लिकेशन शुरू नहीं कर सकता है। मेरे पास व्यवस्थापक अधिकारों के साथ उपयोगकर्ता के रूप में लॉग इन विंडोज 7 पर सी # डब्ल्यूसीएफ विंडोज सेवा है। सेवा शुरू होने के बाद मैं डेस्कटॉप एप्लिकेशन शुरू करने की कोशिश कर रहा हूं। मुझे मिली सभी चर्चाएं विंडोज स्टेशनों और डेस्कटॉप के बारे में हैं ... मैंने एक अलग धागा बनाया, थ्रेड स्टेशन और डेस्कटॉप सेट किया और डेस्कटॉप एप्लिकेशन शुरू करने की कोशिश की। कोड जब मैं इसे VS2010 से एएसपीनेट विकास सर्वर का उपयोग करके शुरू करता हूं लेकिन कोड से शुरू किया गया था, तो कोई त्रुटि नहीं है लेकिन प्रक्रिया शुरू नहीं हुई थी। मैंने अलग-अलग उपयोगकर्ता के रूप में प्रक्रिया शुरू करने की कोशिश की है और CreateProcessWithLogonW की कॉल करने की कोशिश की है (startInfo.lpDesktop को "winsta0 \ default" से पहले सेट करना; पहले)। दोनों मामलों में मेरे पास प्रक्रिया है ID लौटा लेकिन डेस्कटॉप एप्लिकेशन नहीं देख सकता। क्या कोई मेरी गलती कहां देखने में मदद कर सकता है?

public class ExternalProcess 
{ 
    const int READ_CONTROL = 0x20000; 
    const int WRITE_DAC = 0x40000; 
    const int DESKTOP_WRITEOBJECTS = 0x80; 
    const int DESKTOP_READOBJECTS = 0x1; 

    private Process extProcess; 
    private string sFilePath = ""; 

    [DllImport("user32.dll")] 
    private static extern bool SetThreadDesktop(IntPtr hDesktop); 
    [DllImport("user32.dll")] 
    static extern IntPtr OpenDesktop(string lpszDesktop, uint dwFlags,bool fInherit, uint dwDesiredAccess); 
    [DllImport("user32.dll")] 
    private static extern IntPtr GetProcessWindowStation(); 
    [DllImport("user32.dll")] 
    private static extern IntPtr OpenWindowStation(string lpszWinSta, bool fInherit, ACCESS_MASK dwDesiredAccess); 
    [DllImport("user32.dll")] 
    private static extern IntPtr SetProcessWindowStation(IntPtr hWinsta); 

    public bool StartProcess(string filePath) 
    { 
     sFilePath = filePath; 
     Thread t = new Thread(new ThreadStart(Thread_StartProcess)); 
     t.Start(); 

     return true; 
    } 

    private void Thread_StartProcess() 
    { 
     IntPtr hwinstaSave; 
     IntPtr hwinsta, hwinsta2; 
     IntPtr hdesk; 

     hwinstaSave = GetProcessWindowStation(); 
      System.Console.WriteLine("GetProcessWindowStation Lasterror= " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("GetProcessWindowStation hwinstaSave= " + hwinstaSave.ToString()); 
     //hwinsta = OpenWindowStation("winsta0", false, ACCESS_MASK.GENERIC_EXECUTE | ACCESS_MASK.DESKTOP_CREATEWINDOW | ACCESS_MASK.DESKTOP_CREATEMENU | ACCESS_MASK.DESKTOP_SWITCHDESKTOP | ACCESS_MASK.DESKTOP_WRITEOBJECTS); 
     hwinsta = OpenWindowStation("winsta0", false, ACCESS_MASK.WINSTA_ALL_ACCESS); // when call from windows service OpenWindowStation returns 0 
      System.Console.WriteLine("OpenWindowStation lasterror = " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("OpenWindowStation hwinsta= " + hwinsta.ToString()); 
     hwinsta2 = SetProcessWindowStation(hwinsta); 
      System.Console.WriteLine("SetProcessWindowStation lasterror = " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("SetProcessWindowStation hwinsta2= " + hwinsta2.ToString()); 
     hdesk = OpenDesktop("default", 0, true, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS); 
      System.Console.WriteLine("OpenDesktop lasterror = " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("OpenDesktop hdesk= " + hdesk.ToString()); 
     bool Success = SetThreadDesktop(hdesk); 
      System.Console.WriteLine("SetThreadDesktop lasterror = " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("SetThreadDesktop Success= " + Success.ToString()); 

     try 
     { 
      extProcess = new Process(); 

      extProcess.StartInfo.FileName = sFilePath; 
      extProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal; 

      if (extProcess.Start()) 
       System.Console.WriteLine("Process started "); 
      else 
       System.Console.WriteLine("Not started!"); 
     } 
     catch (Win32Exception e) 
     { 
      System.Console.WriteLine("Start {0} failed. Error: " + e.Message); 
     } 
    } 

} 
+0

इसके बारे में काम कर रहे पूर्ण स्रोत कोड नमूने के साथ कोई अंतिम समाधान? – Kiquenet

उत्तर

1

इस Perhapse मदद करता है: http://msdn.microsoft.com/en-us/library/ms683502%28VS.85%29.aspx

hth

मारियो

+0

Thx, मैंने पहले ही इसे पढ़ लिया है, सेवाओं में चेक बॉक्स को चेक करने की कोशिश करने की कोशिश की है, सेवाओं में चेक बॉक्स को बदलें, सेवा चलाने वाले उपयोगकर्ता को बदलें ..., विशिष्ट उपयोगकर्ता के लिए चेक बॉक्स को अनुमति नहीं है, मैंने सेट करने की कोशिश की यह मैन्युअल रूप से रजिस्ट्री में है लेकिन परिणाम के बिना ... – Jovan

+0

मैं इस कथन का अधिक जिक्र कर रहा था: "महत्वपूर्ण सेवाएं सीधे विंडोज विस्टा के रूप में उपयोगकर्ता के साथ बातचीत नहीं कर सकती हैं। इसलिए, इंटरएक्टिव सेवा का उपयोग करने वाले शीर्षक में वर्णित तकनीकों का उपयोग नहीं किया जाना चाहिए नए कोड में। " - ऐसा लगता है कि विंडोज विस्टा से शुरू होने वाले उपयोगकर्ता के साथ एक सेवा शुरू करने के लिए अब यह संभव नहीं है (इसका मतलब है, Vista, 7, और सर्वर 2008 मुझे लगता है!)। यह डीबगर में काम कर रहा है क्योंकि डीबगर वास्तविक सेवा नहीं है! –

+0

अच्छी तरह से हाँ, मैं उस हिस्से से डरता था। इसका मतलब है कि विभिन्न डिजाइनों को आजमाएं। बहुत बहुत धन्यवाद। – Jovan

4

इंटरएक्टिव विंडोज सेवा Windows Vista में एक सुरक्षा केंद्रित बदलाव का स्वागत किया। सेवाएं अब अलग "सत्र 0" में चलती हैं और इंटरैक्टिव उपयोगकर्ता सत्रों में आसानी से खिड़कियां इंजेक्ट नहीं कर सकती हैं। उपरोक्त आपका कोड सत्र 0 में जीयूआई तत्व बनाएगा, जो किसी भी उपयोगकर्ता के डेस्कटॉप पर नहीं दिखाए जाते हैं, यहां तक ​​कि "डेस्कटॉप से ​​बातचीत करने की अनुमति दें" के साथ भी चेक किया गया है।

विंडोज सेवा प्रतिबंधों के बारे में अधिक जानकारी this technical document from Microsoft में हैं।

0

मैं अभी इस बीच के बीच में हूं, मुझे पता है कि अल्ट्रावीएनसी ऐसा करता है इसलिए मैं कोड को देखता हूं। मैं इस पल में उत्तर का 100% निश्चित नहीं हूं, जब मुझे लगता है कि मैं इस पोस्ट को अपडेट करूंगा।

यह बात यह है कि आप CreateProcessAsUser करते हैं, तो प्रक्रिया को तब OpenTputDesktop को एक SetThreadDesktop करना पड़ सकता है, लेकिन जैसा कि मैं इसे अभी तक काम नहीं कर सकता।

1

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

Possible to launch a process in a user's session from a service?

असीम