# Monday, September 20, 2004

A question popped up in a public compact framework newsgroup yesterday. The OP was feeding strings coming from a multiline text box to a web service for storing in the database. To his surprise when he retrieved the strings back (via the same web service) they would display small boxes in place of line breaks.

The symptom is consistent with having just LF (0xa) as a string break instead of required CRLF (0xd0xa) and yet when the data were sent to the web service the CRLFs were there. What happened? The investigation shows that on the web service side the strings are delievered without “CRs“

The answer hides in the SOAP protocol. If you have a web service that has a method Test, taking a single string parameter, the request is passed via HTTP POST request that looks like this:

POST /FormatSvc/svc.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Test"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance 
xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <Test xmlns="http://tempuri.org/"> <s>string</s> </Test> </soap:Body> </soap:Envelope>

The string there is the actual string parameter passed to the method. Naturally, if it contains CRLF inside, the XML parser is going to treat it as a whitespace, which is exactly what's happening. To get around this we need to force some sort of encoding on our parameters or tell XML to preserve whitespace. While there is probably a way of doing it, there seems to be a simpler workaround. A standard, run-of-the-mill web service written in ASP.NET supports several request methods - SOAP, SOAP 1.2, POST and GET. How to select the method to be used? The answer is - you need to use wsdl.exe to generate web service proxy for you.

wsdl.exe http://yourwebserver/yourservice /Protocol:HttpGet
produces yourservice.cs - a web service proxy, that can be placed into your project instead of the web reference. Since in GET request parameters are UrlEncoded, this will preserve the special characters and CRLFs

There is one small catch. By default ASP.NET 1.1 does not accept GET requests for web services. This can be changed in C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config by uncommenting the line that says: <!--<add name="HttpGet"/>-->
This is not the best solution. A better one would be to use POST client. In my experiments for some reason wsdl.exe refused to produce anything when invoked with /Protocol:HttpPost. What I've done is I edited the .cs file produced for /Protocol:HttpGet replacing

System.Web.Services.Protocols.HttpGetClientProtocol

with

System.Web.Services.Protocols.HttpPostClientProtocol

in the class statement, and

[System.Web.Services.Protocols.HttpMethodAttribute(typeof(System.Web.Services.Protocols.XmlReturnReader), typeof(System.Web.Services.Protocols.UrlParameterWriter))]

with

[System.Web.Services.Protocols.HttpMethodAttribute(typeof(System.Web.Services.Protocols.XmlReturnReader), typeof(System.Web.Services.Protocols.HtmlFormParameterWriter))]

on each method.

WSDL.EXE can be found in .NET SDK usually located in <Visual Studio Directory>\Sdk\v1.1\Bin

Monday, September 20, 2004 10:01:44 AM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]  | 
# Wednesday, March 17, 2004

You have probably noticed by now that Pocket PC applications built with .NET Compact Framework 1.0 are single-instance. If you try to launch it while one copy is already running, that copy will be reactivated and brought to foreground. While very convenient and compliant with PPC Design Guidelines, sometimes it is a bit too helpful.

Let's take a look at what happens when you launch your CF application. On the outside a CF application is a standard executable with PE header and entry point. The entry point is a single line of assembly code:

jmp mscoree!__CorExeMain

Upon startup CF implementation of mscoree looks for a window with a class #NETCF_AGL_PARK and title set to the current process executable full path (\Program Files\MyApp\MyApp.exe). If found, the runtime presumes that the current application is already running. In this case it will be reactivated. To do this the abovementioned window is sent a message 0x8001, and then the new instance quits . In the previously active instance upon receiving of the message 0x8001 the WindowProc of #NETCF_AGL_PARK window will perform a series of steps ending with a call to SetForegroundWindow. Notice that the call to SetForegroundWindow is passed the handle of  GetWindow(<#NETCF_AGL_PARK window>, GW_HWNDPREV).
Unfortunately there are cases when you need more than simply reactivate the previous instance. The most notable example is using a CF app as a target for CeLaunchAppAtXXX function. Problem is that the second instance quits before your managed code has a chance to execute, so there is not much you can do even if you would like to implement your own logic for detecting/activating previous instance.
The solution for disabling this "single-instance" behavior is rather obvious from the above description. All we need to do is to rename our #NETCF_AGL_PARK window. The window handle can be located using FindWindow function. The class name is #NETCF_AGL_PARK and the title is identcal to the full assembly module path:
Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedPath. Then we simply use SetWindowText to alter window title.
 
12/20/04: Update
It appears that the name of the window class has changed in SP2. The new name is #NETCF_AGL_PARK (with a trailing underscore). The rest of the informatin above stands.
Wednesday, March 17, 2004 12:37:08 PM (Pacific Standard Time, UTC-08:00)  #    Comments [21]  | 
# Friday, February 13, 2004

Despite the expected context of this blog this is not about Personal Computers. It about being Politically Correct...

Recently Microsoft has issued an update to a Bookshelf Symbol 7 font. The font was found to contain "unacceptable symbols". A press-release with apologies has been promptly issued. The blame went to poor oversight and artist mistake. Apparently what caused the whole thing was a presence of two swasticas in the font. A few things are worth mentioning:

  1. The actual font file has a copyright of Ricoh Corp inside - it seems that it was licensed from Ricoh
  2. The swastika (or swastica) was borrowed by Nazis from ancient India culture as an Arian symbol. Other cultures has also embraced this symbol to some extend. Most notably in Buddhist countries, especially in Japan, this symbol is associated with Good Luck and Prosperity.
  3. The swastika in the font was a part of a range of Japanese (Kanji) characters.
  4. This character (or rather its mirror image is a sign used on maps in Japan to designate the location of Shinto temples (can be seen on Yahoo Maps)
  5. Here are the screen shots of the font before and after:

Before:

After:

Friday, February 13, 2004 10:10:25 AM (Pacific Standard Time, UTC-08:00)  #    Comments [16]  | 
# Wednesday, January 14, 2004

This is something I have seen, while returning from Lake Tahoe this weekend. A sign said: "Such and such, Attorney at Law. Crime Pays." 'nuff said.

Another ad grabbed my attention as I was passing Bay Bridge. It was a Nextel billboard featuring their newest Java phone i730 and saying "If you want a fashion accessory - buy a poodle". I'd say this is somewhat arrogant coming from a company known to offer ugliest phones on the market.

Wednesday, January 14, 2004 10:44:13 AM (Pacific Standard Time, UTC-08:00)  #    Comments [23]  | 
# Friday, January 09, 2004
Someone has pointed me to a (product/project/utility/kit) called Utlimate Boot CD. Highly recommend it. It's an extremely handy collection of tools packed together into a bootable CD image. My favorites are NT password editor and partition resizer. To burn the image I've used ISO Recorder - what did you expect?
Friday, January 09, 2004 12:29:28 PM (Pacific Standard Time, UTC-08:00)  #    Comments [14]  | 
# Tuesday, January 06, 2004
Register solemnly proclaims Windows XP MCE to be a dead product. I would not throw away my MCE machine just yet. I guess, I'll wait and see what Mr. Gates will say tomorrow in his Comdex keynote
Tuesday, January 06, 2004 10:55:14 PM (Pacific Standard Time, UTC-08:00)  #    Comments [14]  | 
In a pile of junk I found today a video tape labeled "Apple's Operating System Strategy. March 1997". Interesting... It's a pity I do not own a VCR anymore...
Tuesday, January 06, 2004 3:23:17 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0]  | 
# Monday, January 05, 2004
It was frequently pointed out that ugly cars have their special kind of charm. One can learn to love Porsche 964. Nissan 280 ZX has quite a following. I own a 1997 Jeep Wrangler SE (no picture is available), which many consider not quite an appealing design. To that I say, that rugged faces are not necessarily beautiful. Suddenly Daimler-Chrysler introduces a Jeep Treo concept - um, interesting...
Monday, January 05, 2004 12:15:35 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0]  | 
Suddenly I realized that the newsgroup postings are not enough. They get trampled all over too easily. I need my personal forum. Wait!.. I have one... What was that password again? Well, it''s been 7 months. How am I supposed to remember it? Fortunately Neil is always there for me and he's got admin rights on this blog server.
Monday, January 05, 2004 11:56:57 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]  |