Solved

How to post message from windows service to another application

Posted on 2013-11-06
9
1,389 Views
Last Modified: 2013-11-22
Dear experts,

I have the following situation:

1.1.      In Window Service (A) we use API FindWindow() to find Window handle (**) of external process (B)
1.2.      Base on (**), Window Service (A) post a Windows message to (B)

But, from Windows Vista, it seems that:
        (A) runs in Session 0 and (B) runs in others section (Session 1)
        -> so, (B) will never receive message sent from (A)

Please help me to solve this issue.
Regards.
0
Comment
Question by:FSOFT-SA
  • 4
  • 3
9 Comments
 
LVL 32

Expert Comment

by:sarabande
Comment Utility
are you using SendMessage or PostMessage for the message?

the SendMessage would call synchronously what means that the call waits for completion (what might be an issue depending on how the service was started). with PostMessage the call should work to any window handle which you could retrieve by winapi before.

Sara
0
 
LVL 86

Accepted Solution

by:
jkr earned 167 total points
Comment Utility
It's not 'sections', but 'desktops' that imposes the problem here. All services run un an (invisible) desktop that is not connected to the one that the logged-on user is seein, so any message sent or posted will never reach the targeted window - in fact, 'FindWindow()' will fail to even locate it. Not quite sure if that still works  on Vista, but up to XP, there was 'SERVICE_INTERACTIVE_PROCESS' used with 'CreateService()' (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682450(v=vs.85).aspx) to remedy that. If it's no longer available there (which I assume, since that is in fact a security hole), you will have to write a small app that is launched in the logged-on user's context that communicates with your service and performs that part of the work on behalf of it.
0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 167 total points
Comment Utility
I believe you could use named pipes in this scenario (but I cannot confirm).
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 166 total points
Comment Utility
in fact, 'FindWindow()' will fail to even locate it.
if that is true, you may look for another p2p communication, for example via shared memory (memory mapped file) or winsock (or pipes as suggested by kaufmed).

struct P2P
{
     int locked;
     int serverInfo;
     int clientInfo;
     char serverMsg[256];
     char clientMsg[256];
};

class SharedMem
{
     HANDLE hMem;
     P2P * p2p;
public:
     SharedMem() : hMem(NULL), p2p(NULL) {}
     bool Create();
     void Close();
};

bool SharedMem::Create()
{
    /* create file mapping */
    hMem = CreateFileMapping( INVALID_HANDLE_VALUE, 
                                                                    NULL, PAGE_READWRITE, 0,
                                                                    sizeof(p2p), "Global\\myp2p");
    if (NULL == hMem) return false;  // error handling
    bool alreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS);

    /* map the file to memory */
    P2P * p2p = (P2P*)MapViewOfFile( hMem, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (NULL == p2p) return false; // error handling

    if (alreadyExists == false)
    {
          memset(&p2p, 0, sizeof(p2p));
    }
    return true;
}

void SharedMem::Close()
{
      if (p2p != NULL)
           UnmapViewOfFile(p2p);
      
     if (hMem != NULL)
         CloseHandle(hMem);
}

Open in new window


the code could be used both by service and client app. note, if service and app are in different sessions the name of shared memory needs to have Global\ prefix. creating a name in the global namespace requires SeCreateGlobalPrivilege. if always the service would create the memory, only the service would need the privilege. the app then should use OpenFileMapping to get a handle to existing memory.

the structure would allow to put one message for both service and app into memory. the locked flag could be used to temporarily lock the memory while copying. that works if both sides only write to their own members of the structure. otherwise you should use a named mutex to get exclusive access while writing to the memory.

if the app runs a message loop, it could check the memory on idle time.

Sara
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 86

Expert Comment

by:jkr
Comment Utility
Excuse me - how would that have helped you if I hadn't poiten out the real issue behind that, of which the person whose answer was accepted was completely unaware of?
0
 
LVL 32

Expert Comment

by:sarabande
Comment Utility
jkr's comment should not be the accepted answer. it gives a - probably good - guess why the issues occurred. i say 'probably' cause the initial questions did not report of errors after FindWindow what would be a necessary condition that the analysis jkr has made was true.

both kaufmed's comment and my comment gave concrete hints for ways out. i gave a full sample code for using shared memory as an alternative to the windows messages. it definitively is the best answer and should be the accepted solution.

@netminder: you may survey whether the comment of jkr made in http:#a39661345 should remain in this thread. i don't think i have experienced such kind of unfair offense without any reason in my life before.

Sara
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>jkr's comment should not be the accepted answer.  it gives a - probably good - guess
>>why the issues occurred.

Excuse me, but I've written quite a few services that are still running on customer's sites. This *IS* the reason why you can't communicate with a desktop app unless you set 'SERVICE_INTERACTIVE_PROCESS' used with 'CreateService()' (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682450(v=vs.85).aspx). If you don
t believe me, read the docs:


SERVICE_INTERACTIVE_PROCESS
0x00000100

The service can interact with the desktop.

and a little bit more directly at http://msdn.microsoft.com/en-us/library/windows/desktop/ms683502%28v=vs.85%29.aspx ("Interactive Services"):

Create a separate hidden GUI application and use the CreateProcessAsUser function to run the application within the context of the interactive user. Design the GUI application to communicate with the service through some method of interprocess communication (IPC), for example, named pipes. The service communicates with the GUI application to tell it when to display the GUI.

If you don't know that, you're hardly are an expert in Windows Services and Windows infrastructure. Well, that is neither a crime nor a problem in general. Yet speaking out against someone who is knowledgeable in that sector while knowing you don't have sufficiant experience in the respective area is a bit off, IMHO.
0
 
LVL 32

Expert Comment

by:sarabande
Comment Utility
I have the following situation:

1.1.      In Window Service (A) we use API FindWindow() to find Window handle (**) of external process (B)
1.2.      Base on (**), Window Service (A) post a Windows message to (B)

But, from Windows Vista, it seems that:
        (A) runs in Session 0 and (B) runs in others section (Session 1)
        -> so, (B) will never receive message sent from (A)
that was the full question of the author. given, that the author correctly reported their issues, the comments jkr has made would be off-topic as none of the implications he described have been asserted by the author nor were mentined in the original post. on the contrary, the original post speaks of issues in Vista only while the speculations jkr has made - and it could not be more than a guess if he would have taken the author's report serious - described a general windows problem.

nevertheless, i took the idea up and asked the questioner whether it was true that the FindWindow doesn't return a valid window handle (no answer to that till now)  and posted a solid way out which bypasses any snares incitent to windows messaging.

Excuse me - how would that have helped you if I hadn't poiten out the real issue behind that, of which the person whose answer was accepted was completely unaware of?
obviously my solution helped independently of the deliberations made by jkr.

If you don't know that, you're hardly are an expert in Windows Services and Windows infrastructure. Well, that is neither a crime nor a problem in general. Yet speaking out against someone who is knowledgeable in that sector while knowing you don't have sufficiant experience in the respective area is a bit off, IMHO.
no comment.

Sara
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
This is an explanation of a simple data model to help parse a JSON feed
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

772 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now