0 Comments

Lastly I have shown how to enforce encoding of strings in DBF table by setting up code-page inside its header. I also mentioned it was the easiest way. That’s still true. But sometimes there is no room to be polite and things need to be done little messy in the code (for example when the DBF file is often recreated by 3rd-party tool an can be altered in any way). So each time the string value is loaded try to recover it with those steps.

First get the original bytes stored from loaded *text* (assume that system inappropriately returned Windows-1250 encoded string):

var bytes = Encoding.GetEncoding("Windows-1250").GetBytes(text);

Secondly convert them from correct encoding (it was natively stored as Latin-2 aka CP-852) to UTF-8:

var convertedBytes = Encoding.Convert(Encoding.GetEncoding(852), Encoding.UTF8, bytes);
return Encoding.UTF8.GetString(convertedBytes);

Of course encoding objects can be cached to increase performance.

0 Comments

Recently I had a problem importing data from a 10-years-old set of DBF tables. All was fine until it came to reading texts with polish diacritic marks. It worked fine on 9 out of 10 machines, all with identical configurations (or at least I had hoped they are identical and couldn’t find any differences - Windows 7 x64 PL, .NET 4.5.2, the same regional options). On that single one all special letters got converted into some eye-hurting characters and looked purely wrong.

As it started to reveal, the OleDbConnection class I used to connect (with “Microsoft.Jet.OLEDB.4.0” provider) magically treated strings as Windows-1250 encoded, event though they were CP852 Latin-2. Thanks to this site, helping me to find out about it.

I tried to enforce the encoding by updating 0x1D byte of the DBF header with proper code page. Following is the list of all possible values (I used 0x64), but still it didn’t help much.

 

Value

Description

0x00No codepage defined
0x01Codepage 437 (US MS-DOS)
0x02Codepage 850 (International MS-DOS)
0x03Codepage 1252  Windows ANSI
0x04Codepage 10000  Standard MacIntosh
0x64Codepage 852  Easern European MS-DOS
0x65Codepage 866  Russian MS-DOS
0x66Codepage 865  Nordic MS-DOS
0x67Codepage 861  Icelandic MS-DOS
0x68Codepage 895  Kamenicky (Czech) MS-DOS
0x69Codepage 620  Mazovia (Polish) MS-DOS
0x6ACodepage 737  Greek MS-DOS (437G)
0x6BCodepage 857  Turkish MS-DOS
0x78Codepage 950    Chinese (Hong Kong SAR, Taiwan) Windows
0x79Codepage 949  Korean Windows
0x7ACodepage 936  Chinese (PRC, Singapore) Windows
0x7BCodepage 932  Japanese Windows
0x7CCodepage 874  Thai Windows
0x7DCodepage 1255  Hebrew Windows
0x7ECodepage 1256  Arabic Windows
0x96Codepage 10007  Russian MacIntosh
0x97Codepage 10029  MacIntosh EE
0x98Codepage 10006  Greek MacIntosh
0xC8Codepage 1250  Eastern European Windows
0xC9Codepage 1251  Russian Windows
0xCACodepage 1254  Turkish Windows
0xCBCodepage 1253  Greek Windows
all othersUnknown / invalid

 

Ultimately, the very old Visual FoxPro driver did the trick (with switched provider to “VFPOLEDB.1”) and respected encoding, saving me from manual strings transcoding in my C# application.

 

Now you have seen everything!

0 Comments

In my recent post I have shown, how to track web requests issued against remote server I don’t have a control over. Curious reader could ask at this point – but what have I broken this time? And the answer is as usual – personally did nothing wrong, I was just doing my job. I had to port some HTTP related code from using Windows Runtime-specific HttpClient (i.e. Windows.Web.Http.HttpClient) to also work outside the sandbox on a regular .NET 4.5 desktop version and start using System.Net.Http.HttpClient instead.

Then I noticed that everything worked fine except multipart form-data submissions using POST method that were behaving unexpectedly bad (timeouting or returning an error immediately). There was nothing unusual mentioned on MSDN, so I started to compare sent requests using both implementation. It turned-out of course, the problem lied deeper in the framework in a value serialized as a *boundary* part of the Content-Type field. HttpClient from the System.Net.Http somehow was adding extra quotes around it, while the one from Windows.Web.Http didn’t. Even though server should accept both values (according to RFC2046 section 5.1.1), it actually didn’t and was waiting for correct *boundary*.

Simple fix by manually overwriting the guilty header can look like that:

var request = new HttpRequestMessage(HttpMethod.Post, url);
var boundary = "--" + Guid.NewGuid().ToString("D");
request.Content = new MultipartFormDataContent(boundary);

// fill content
// ...

// update the Content-Type header to be accepted by the server:
request.Content.Headers.Remove("Content-Type");
request.Content.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary);

// send request:
var result = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
result.EnsureSuccessStatusCode();

 

World saved. Job done!

0 Comments

Usually it’s not a big deal, when a HTTP request to a remote server is not working on a desktop Windows machine. There are plenty of useful tools, that could help in the process:

  • one, which work like a proxy and dump the whole traffic, that we might be interested in (Fiddler would be the best example here)
  • others, that interact with the TCP/IP stack itself and look much deeper for sent packets (like WireShark or Microsoft Message Analyzer).

BTW. Do you know, that there is a way to visualize HTTP traffic in Fiddler, that was originally captured by Wireshark or MMA?
Simply export packets from WireShark as pcap file (File –> Export –> Export as .pcap file) and import it directly into Fiddler (File –> Import Session… –> Packet Capture).
Many thanks to Rick Stahl, for showing me this feature.

Mobiles are totally different world. Mostly because applications are running in a dedicated sandbox and there isn’t at all internal or external access on system level. There is not much to do beside debugging of our own code. But if this doesn’t help, it doesn’t mean we stay blind. Take a look at http://httpbin.org/ (project sources available on GitHub). It’s the server you always wanted to write yourself – server that returns info about client accompanied by a list of headers, info about content for all kinds of submitted requests and even some random binary data, if you like. Respective behavior is selected by dedicated path on the httbin.org server and response is of course in JSON format (maybe beside for the binary data request).

Typically request paths:

  • /get
  • /post
  • /put
  • /delete – all of them to know, how the request really looks like
  • /status/<code> – to verify, if the application handles given error respectively
  • /bytes/<size>
  • /stream-bytes/<size> – both to download some random binary block of bytes from server.

It *won’t* simulate your destination server at all nor any more advanced interactions. And you will need to to hack your application to be able to issue requests against this server and dump somewhere the JSON response. Still remember, it’s only during application development and while fighting with a non-working request against remote server you totally have no control over, so additional #ifdef won’t hurt at all ;)

Final thought – the trick described above could be also without any problem used inside desktop or Windows Store application. It’s not only dedicated to mobiles!

0 Comments

Virtual hard-drives used by virtual systems running under Hyper-V on Windows 8 Pro (or later) can very quickly become extremely huge in size. Thankfully there is a nice and easy procedure that I always use to minimize and compact them, which presents as following:

  1. Turn on the system, that is going to be optimized and log in.
  2. Clean the trash bins, clean `temp` folders and remove all other unneeded stuff from the system drive (like: old system restore points), turn off hibernation and finally turn off or reduce the size of paging file.
  3. Defrag if necessary (do it even x3 times, if using Windows XP as guest OS).
  4. *critical* – clean the reclaimed space using sdelete.exe utility from SysInternals (available here).
  5. Turn off the guest system.
  6. Run the Hyper-V management console and optimize the VHD size from there.

Done. Good job!