Click here to Skip to main content
15,891,951 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
hi i need to post a message to a process from another process. i've written both processes. both are win32 console applications. for this purpose i need to use PostThreadMessage function.
1. is there another method for this purpose?
2. how can i know the thread id which i must provide for the function? i can provide the process id, but:
3. how can i obtain a thread id from a process id?
4. are they the same?
5. what happens if i use the process id as the thread id?
i tried to ask accurately. please give accurate answers (by numbers).
thx
Posted
Comments
CPallini 28-Sep-11 8:48am    
Did you create message queues?
Please have a look at:
http://blogs.msdn.com/b/oldnewthing/archive/2006/02/21/536055.aspx

Its impossible. You can only post messagees to threads they have a message queue. A process can have many threads - but threads have no names to distinguish them. So far as i know there isnt any function to enumerate all threads of a process - if there is one, to which thread you want to post the message?
Best solution (by my opinion) is to create an invisible dummy window. Then you can broadcast a registered message to communicate with the other process(es).
Regards.

[Edit]
apllication 1
C++
// application 1
void main()
{
  int    mterm = RegisterWindowMessage("MyTermMessage");
  HWND  hwnd = CreateWindowEx(0,__T("STATIC"),__T(""),0,0,0,0,0,0,0,0,0);
  for(MSG m;GetMessage(&m,0,0,0);DispatchMessage(&m))
  {
    if(mterm==m.message)
      PostQuitMessage(0);
  }
  DestroyWindow(hwnd);
}

application 2
C++
// application 2
void main()
{
  int            mterm = RegisterWindowMessage("MyTermMessage");
  unsigned long  to = BSM_APPLICATIONS;

  BroadcastSystemMessage(BSF_IGNORECURRENTTASK|BSF_POSTMESSAGE,&to,mterm,0,0);
}

You need a dummy window to receive the broadcasted message(s) - thats because you cannot post messages to unknown threads. As i explained - there is no function to get a thread id from another process.
Regards.
 
Share this answer
 
v2
Comments
Albert Holguin 28-Sep-11 13:58pm    
I do this frequently for different purposes (make dummy windows that can be used as messaging targets). +5
[no name] 29-Sep-11 5:00am    
There is no need to create a hidden window. Any thread is promoted to a GUI thread as soon as it makes a GDI call. One caveat though... you will need to manually pump the message queue just like you do in a pure Win32 project.
mbue 29-Sep-11 6:41am    
Broadcasted messages are only sent to windows, not to threads.
Regards.
[no name] 29-Sep-11 8:21am    
Yep, you are of course correct. I was referring to the PostThreadMessage function which is what the OP said he was using. You can use this to post thread messages to console applications without the need for a window.
ilostmyid2 29-Sep-11 9:15am    
hithank u for the solution. i think it's not a good idea to create a window and register a message for just sending a message to a thread. besides, since this message is broadcasted, it will be received by all windows in the system. i just need to know the thread id, so that i may call PostThreadMessage to send a specified msg to it.
I will suggest to use CreateNamedPipe to communicate with another non-windowed process rather than using the current design with PostThreadMessage. PostThreadMessage is helpful only inside a single process.
You can find more info from this MSDN page for CreateNamedPipe [^]and an example here[^].
 
Share this answer
 
i wrote the program like this:
C++
void main()
{
	MSG msg;
	while (GetMessage(&msg, 0, 0, 0))
	{
		TranslateMessage(&msg);
		if (msg.message == 101)
		{
			cout << "i got my msg!" << endl;
			PostQuitMessage(0);
		}
		else
			DispatchMessage(&msg);
	}
}

as u see it's a Win32 console application containing a msg loop. i think it consists of only one thread, the main thread. am i right? i need another process to post msg 101 to this process. that's all.
now what can i do? how the invisible window may help me?!
my solution so far has been to write the thread id by the process that wants to receive the msg to a file! like this code:
C++
DWORD thId = GetCurrentThreadId();
fprintf(fp, "%ld", thId);

then i run the process that wants to send the message. then it uses fscanf to read the thread id from the file and knows to what thread it has to post the msg, then calls PostThreadMessage!
any better suggestion? :)
i think PostThreadMessage, as Madhu said, is designed for sending msgs between threads inside a single process. but it's weird that there's no way to enumerate threads or get the main thread of a process!
 
Share this answer
 
Comments
[no name] 29-Sep-11 2:45am    
A console application does not have a message queue! You will need to perform some hacktastic wizardry to force the NT kernel into calling PsConvertToGuiThread() You can accomplish this by invoking a win32k syscall with an index greater or equal to the NtGdiAbortDoc index. After you make the syscall the kernel will promote your main thread into a GUI thread, increase the stack size and give your thread a message queue.
ilostmyid2 29-Sep-11 3:05am    
oh! there's no need for such a robust complicated method!
i just did it and it worked properly. i could get the output "i got my msg!" from this small program without doing it to give a GUI to it.
please re-read the text and try to re-think about it with this knowledge.
thx
[no name] 29-Sep-11 3:47am    
Actually you are doing exactly as I described. When you call GetMessage() it invokes NtUserGetMessage which internally invokes a win32k syscall above 0x1000. But I guess that is besides the point. I apologize for complicating the issue, I did not fully read your question. I will try to answer all points:

1.) Yes.. there are many IPC techniques... pipes, memory maps... mailslots... sockets and the message subsystem are a few. Pick your poison.
2.) GetCurrentThreadId will get the current thread ID but it looks like you already know this. If you have a window handle and want to know both the thread ID and process id use GetWindowThreadProcessId()
3.) A process *can* have more than 1 thread. When the other program sends you a message... use GetWindowThreadProcessId to get both the thread ID and process ID from the window handle.
4.) No, a thread ID is not the same as a process ID.

Best Wishes,
-David Delaune
ilostmyid2 29-Sep-11 4:11am    
thank u 4 ur reply,
let me concentrate on the original questions:
1. are console applications multi-threaded by default while i've not created any additional thread in them? (yes/no)!
2. how can i know the thread id of the process i have its id if it's single-threaded?
thx
[no name] 29-Sep-11 4:41am    
1.) No, a process begins as a single thread.

2.) The question itself is nonsensical. A better question would be how to enumerate all threads belonging to the process. You could do something like:

#include <tlhelp32.h>
DWORD dwYourPIDToCompare = 0;
THREADENTRY32 te32;
te32.dwSize = sizeof(THREADENTRY32);

HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
if(INVALID_HANDLE_VALUE != hThreadSnap)
{
if(Thread32First(hThreadSnap, &te32))
{
do
{
if(te32.th32OwnerProcessID == dwYourPIDToCompare)
{
//This thread belongs to the process
}
} while(Thread32Next(hThreadSnap, &te32));
CloseHandle(hThreadSnap);
}
}
Another solution:
C++
void PostMessageToProcessThreads(HANDLE hprocess,int msg)
{
  unsigned long  id = GetProcessId(hprocess);
  HANDLE        hs = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD,id);
  if(INVALID_HANDLE_VALUE!=hs)
  {
    THREADENTRY32  te = { sizeof(THREADENTRY32),0 };
    if(Thread32First(hs,&te))
    {
      do
      {
        if(id==te.th32OwnerProcessID)
        {
          if(te.th32ThreadID)
          {
            PostThreadMessage(te.th32ThreadID,msg,0,0);
          }
        }
      } while(Thread32Next(hs,&te));
    }
    CloseHandle(hs);
  }
}

Good luck.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900