Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Application behaves differently when launched from a service

Posted on 2004-07-31
8
Medium Priority
?
599 Views
Last Modified: 2013-12-03
I have a program that works great when I test the program by running
it as an application, but when I package it as a service, the feature fails.
In particular the feature is a gui part that supports drag-and-drop allowing
interaction with the user's desktop.

I tried having my service launch the gui feature as a separate application,
but the feature still didn't work when the service launched the application.

I tried using ImpersonateLoggedOnUser before launching the application,
but it still failed to work.

What else could be different that causes the application to succeed when I
run it normally, but fail when the service launches it?
0
Comment
Question by:bjornsone
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
8 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 11685305
A lot of things can go wrong - see http://www.microsoft.com/msj/0398/service2.aspx ("Why Do Certain Win32 Technologies Misbehave in Windows NT Services?"). Hsve you tried making your service a SERVICE_INTERACTIVE_PROCESS?
0
 

Author Comment

by:bjornsone
ID: 11686102
Yes, my service is interactive.  I see the user interface and all other gui functionality
works fine with interacting with the logged in user.  I just have problems with drag-
and-drop not working with explorer or other apps.

I already gave up in having my service work just like an application, but I was at least
hoping that I my service could launch an application that worked fine (this method was
suggested in the article that jkr referenced).

I tried using "system( const char *command )" to launch the application after doing
ImpersonateLoggedOnUser.  Is there a better way that I could launch this other app?  
Should I use CreateProcessEx  using the same token that I used with ImpersonateLoggedOnUser?

I can make some guesses, but if anybody knows how a service can launch an application
that behaves just as if the logged on user had launched the app, then I would much
appreciate your help.
0
 
LVL 86

Accepted Solution

by:
jkr earned 1600 total points
ID: 11686454
That's what I outlined in http:Q_20278299.html

------------------------------->8---------------------------

LogonUser();
ImpersonateLoggedOnUser();

// do stuff

RevertToSelf();

E.g.:

  HANDLE          hToken  =   NULL;

  if  (   !LogonUser  (   ( char*) pszUsername,
                          NULL,
                          ( char*) pszPwd,
                          LOGON32_LOGON_INTERACTIVE,
                          LOGON32_PROVIDER_DEFAULT,
                          &hToken
                      )
      )
      {
          return  (   GetLastError    ());
      }

  if  (   !ImpersonateLoggedOnUser    (   hToken)
      )
      {
          return  (   GetLastError    ());
      }

You alternatively could obtain a token from a process the user is running (explorer.exe is a good choice <s>). You'll nedd the PID to call 'OpenProcess()', then 'OpenProcessToken()' with 'TOKEN_IMPERSONATE' access. See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q175030 ("HOWTO: Enumerate Applications Using Win32 APIs (Q175030)") on how to get that PID - it comes with sample code.

------------------------------->8---------------------------

To obtain a valid token, you could use

HANDLE GetTokenOfLoggedOnUser()
{
HANDLE hToken;
HANDLE hProcess;
DWORD dwPID;
// find PID of 'explorer.exe'
// HOWTO: Enumerate Applications in Win32
// http://support.microsoft.com/support/kb/articles/Q175/0/30.ASP

  hProcess    =   OpenProcess (   PROCESS_ALL_ACCESS,
                                  TRUE,
                                  dwPID
                              );

   if  (   !OpenProcessToken   (   hProcess,
                                  TOKEN_ALL_ACCESS,
                                   &hToken
                              )
      )   return  (   INVALID_HANDLE_VALUE);

return ( hToken);
}

from e.g. http:Q_10223099.html and http:Q_20827986.html

0
Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

 

Author Comment

by:bjornsone
ID: 11686812
I've already found how to get the proper handle to be used for
Impersonation.  Doing impersonation has worked for my service
doing other tasks.  Impersonation, however, does not seem to solve
the problem when I call "system" to launch my other process after
doing ImpersonateLoggedOnUser.

What is the right way for my code to launch a separate application
so that it behaves as if it had been launched by the logged in user.
My current approach does not work.  Will ShellExecute or CreateProcess
work any better?  Why?
0
 
LVL 86

Expert Comment

by:jkr
ID: 11688786
>>What is the right way for my code to launch a separate application

The above worked with 'CreateProcess()'. BTW, what exactly are you using (in terms of technologies) is your application?
0
 
LVL 8

Expert Comment

by:adg080898
ID: 11758859
Is it because the desktop changes? The desktop is explorer, and explorer is responsible for drag-and-drop of files. If the user logs off, explorer exits. Any handles or interfaces you had might be lost. You need to watch for a certain named-event to be pulsed.

WindowStation0 or something....I can't find it right now but it goes something like this:

hEvtDesktopChanged = CreateEvent(NULL, FALSE, FALSE, "WindowStation0");

Then somewhere in your service, wait for that event. When the desktop changes, windows will pulse the event, causing your waiting thread to wake up. You should then be able to reinitialize your OLE interfaces for drag and drop.

0
 
LVL 8

Assisted Solution

by:adg080898
adg080898 earned 400 total points
ID: 11758905
See
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/handling_logoff_events.asp?frame=true

Work through that topic and neighbouring topics to get some insight into your problem. It says clearly that you have to "close all handles to the window station and desktop" when the user logs off.

BTW: I think that event name I mentioned in the previous posting is "WinSta0", but still not 100% sure.
0
 

Author Comment

by:bjornsone
ID: 12217534
Sorry for leaving this open for so long.
It looks like I'll just need to run the part that supports drag-and-drop as
an application.   I'll keep the other part that is always needed as a service.
It'll be more work, but it is good separation anyway to not use the
service to directly do the user interface.
Thanks for your help.
0

Featured Post

Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question