Я считаю, что единственный практический способ - вручную определить некую «маску» для каждой кодовой страницы; структура, которая определяет все значения символов, которые вы считаете допустимыми для каждой из ваших кодовых страниц.
Затем вы можете проверить, содержит ли страница какие-либо символьные значения, которые не содержались в этой маске.
Создание маски потребует немалых ручных усилий. Создайте страницу с каждым символом, затем отобразите ее, используя соответствующую кодовую страницу, а затем посмотрите, какие из них не отображаются «красиво». Это разовое действие для каждой кодовой страницы, поэтому, возможно, оно того стоит.
Конечно, если бы был способ разобрать кодовую страницу, вы могли бы сгенерировать эту маску автоматически ... Хм ... Вернемся немного назад.
Попробуйте этот фрагмент кода. Он проверяет символы 32-255 на каждой известной кодовой странице.
StringBuilder source = new StringBuilder();
for (int ix = 0; ix < 224; ix++)
{
source.Append((char)(ix + 32));
}
EncodingInfo[] encs = Encoding.GetEncodings();
foreach (var encInfo in encs)
{
System.Console.WriteLine(encInfo.DisplayName);
Encoding enc = Encoding.GetEncoding(encInfo.CodePage);
var result = enc.GetBytes(source.ToString().ToCharArray());
for (int ix = 0; ix < 224; ix++)
{
if (result[ix] == 63 && source[ix] != 63)
{
// Code page translated character to '?'
System.Console.Write("{0:d}", source[ix]);
}
}
System.Console.WriteLine();
}
Я смотрел в отладчике и заметил, что '?' используется в качестве запасного символа, если исходный символ не включен в кодовую страницу. Проверяя на «?» (и гарантируя, что это не «?» для начала), код предполагает, что кодовая страница не может его обработать.
Кодовым страницам DBCS может потребоваться немного больше внимания, я не смотрел. Но попробуйте это как отправную точку.
Я бы использовал подобный код для создания начальной «маски», как я описывал ранее, а затем вручную настраивал эту маску на основе того, что выглядело хорошо, а что нет.