I am developing an Windows CE 3.0 app using eVC. I am using OutputDebugString to send diagnostic messages while running in the eVC development environment via an Ethernet port.
Is there anyway to capture these messages while NOT running in the eVC development environment?? Is there a way to use WinDbg to capture these messages, or is there an utility that comes with Platform Builder??
I am using OutputDebugString to send diagnostic info while running my app under the eVC debugger. The target is running CE 3.0 and uses an Ethernet connection for debugging. Is there anyway to capture the output of OutputDebugString without using the debugger?? Are there utilities that can do this with the Ethernet connection (WinDbg, DBMON, etc.). Is there an easy way to make these work without having to jump thru the multitude of development hoops inherent to Windows CE?
> I am using OutputDebugString to send diagnostic info while running > my app under the eVC debugger. The target is running CE 3.0 and > uses an Ethernet connection for debugging. Is there anyway to > capture the output of OutputDebugString without using the > debugger?? Are there utilities that can do this with the Ethernet > connection (WinDbg, DBMON, etc.). Is there an easy way to make > these work without having to jump thru the multitude of development > hoops inherent to Windows CE?
You can open a UDP socket for output. Here is an example:
// bind the log socket to a specific port. static bool wsa_bind(unsigned short port) { SOCKADDR_IN addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_ANY); int r=bind(wsa_socket,(sockaddr*)&addr,sizeof(addr)); if (r==0) theLogPort=port; return (r==0);
}
// initialize everything, if the socket isn't open. static bool wsa_init() { if (wsa_socket != INVALID_SOCKET) return true; int r; WSADATA wd; BOOL bc=true;
if (0 != WSAStartup(0x101, &wd)) goto error; wsa_socket=socket(PF_INET, SOCK_DGRAM, 0); if (wsa_socket == INVALID_SOCKET) goto error; r=setsockopt(wsa_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc, sizeof(bc)); if (r!=0) goto error; if (wsa_bind(9998)) return true; // bind to default port. error: if (wsa_socket != INVALID_SOCKET) closesocket(wsa_socket); if (debug_mode) OutputDebugString(TEXT("nclog: TCP/IP Problem")); return false;
}
// can be called externally to select a different port for operations bool set_nclog_port(unsigned short x) { return wsa_bind(x); }
if (SOCKET_ERROR == sendto(wsa_socket,x,strlen(x), 0, (sockaddr*) &sa, sizeof(sa))) { if (debug_mode) OutputDebugString(TEXT("nclog: Send Error")); }
}
// format input, convert to 8-bit and send. void nclog (const wchar_t *fmt, ...) { va_list vl; va_start(vl,fmt); wchar_t buf[1024]; // to bad CE hasn't got wvnsprintf wvsprintf(buf,fmt,vl); wsa_init(); char bufOut[512]; WideCharToMultiByte(CP_ACP,0,buf,-1,bufOut,400, NULL, NULL); wsa_send(bufOut);
}
// finalize the socket on program termination. struct _nclog_module { ~_nclog_module() { if (wsa_socket!=INVALID_SOCKET) { nclog("nclog goes down\n"); shutdown(wsa_socket,2); closesocket(wsa_socket); } }
};
static _nclog_module module;
--- END FILE nclog.cpp ---
How to use? You simply put netcat.cpp and netcat.h in your project and you go. Use it like printf:
nclog(L"The Window Handle is: %x\n",hwnd);
On your desktop, you need netcat to capture the output from your program, i.e. you open a console and type:
netcat -lup 9998
This will instruct netcat to show you everything that comes to your UDP socket 9998 (which is the default for netcat). Since nclog opens the socket in broadcast mode, you don't have to give an target adress. (Be sure to select a port which does not interfer with the network you are living in)
If you have a "tee" Utility (for example from the cygwin tools), you can also capture the output:
netcat -lup 999 | tee logfile
I don't use OutputDebugString anymore. This approach is much more flexible. For example, I can filter the output with grep and have multiple netcat's open to show me the output from different threads:
In one terminal: netcat -lup 9998 | grep "[xy thread]"
In another netcat -lup 9998 | grep "[main thread]"
just prefix your output and you can filter on it.
Or I can see how two different programs interact, by using different port numbers. etc.pp.
Sorry: I copied the code from an exisiting file which had additional functionality. You need to define a bool debug_mode which decides if errors are reported via OutputDebugString. I hope you can get it to run. -- Marco
> Sorry: I copied the code from an exisiting file which had additional > functionality. You need to define a bool debug_mode which decides if > errors are reported via OutputDebugString. I hope you can get it to run. > -- > Marco
> > Sorry: I copied the code from an exisiting file which had additional > > functionality. You need to define a bool debug_mode which decides if > > errors are reported via OutputDebugString. I hope you can get it to run. > > -- > > Marco
> BTW: how do you make it work for the x86em platform?
I don't use the emulator.
a) It is too unstable. My installation of the Pocket Emulator dies with an error in shell32.exe when I try to start the calendar or to show the today screen. After the crash I casually have to logout to get rid of the pieces.
b) It doesn't emulate properly. For my Projects, I've written a library which allows me to code without including <windows.h> anymore. An Application uses *exactly* the same code for Win32 and WinCE (no #ifdef UNDER_CE anymore). I am testing against: Windows NT, Cassiopeia, Journada, iPAQ. Casually also against a PalmPC 2.11 device. It always works, but *never correctly* in the Emulator. Lots of subtle thing happen there, windows receive button down events, but not the button up event that follows etc.pp.
c) It does not support networking et. al. (thats why nclog doesn't work)
d) Too much to hassle to get it together with ADOCE or SQL Server CE and other addons
If you have a network card, forget the emulator, it sucks. They or somebody else should make an emulator which really emulates hardware and runs an actual Windows CE image. (which would be a great thing for the Platform Builder users as well, if they could configure an emulator for their hardware to test-drive their images)
If your code isn't too CE specific, then maintain the code to run under the Desktop. (Which is also very valuable, because you learn about the API differences).
> > BTW: how do you make it work for the x86em platform?
> I don't use the emulator.
> a) It is too unstable. My installation of the Pocket Emulator dies with > an error in shell32.exe when I try to start the calendar or to show the > today screen. After the crash I casually have to logout to get rid of > the pieces.
> b) It doesn't emulate properly. For my Projects, I've written a library > which allows me to code without including <windows.h> anymore. An > Application uses *exactly* the same code for Win32 and WinCE (no #ifdef > UNDER_CE anymore). I am testing against: Windows NT, Cassiopeia, > Journada, iPAQ. Casually also against a PalmPC 2.11 device. It always > works, but *never correctly* in the Emulator. Lots of subtle thing > happen there, windows receive button down events, but not the button up > event that follows etc.pp.
> c) It does not support networking et. al. (thats why nclog doesn't work)
> d) Too much to hassle to get it together with ADOCE or SQL Server CE and > other addons
> If you have a network card, forget the emulator, it sucks. They or > somebody else should make an emulator which really emulates hardware and > runs an actual Windows CE image. (which would be a great thing for the > Platform Builder users as well, if they could configure an emulator for > their hardware to test-drive their images)
> If your code isn't too CE specific, then maintain the code to run under > the Desktop. (Which is also very valuable, because you learn about the > API differences).