реальная версия хранится в блоке PEB с информацией о процессе.
Образец для приложения Win32 (Delphi Code)
unit RealWindowsVerUnit;
interface
uses
Windows;
var
//Real version Windows
Win32MajorVersionReal: Integer;
Win32MinorVersionReal: Integer;
implementation
type
PPEB=^PEB;
PEB = record
InheritedAddressSpace: Boolean;
ReadImageFileExecOptions: Boolean;
BeingDebugged: Boolean;
Spare: Boolean;
Mutant: Cardinal;
ImageBaseAddress: Pointer;
LoaderData: Pointer;
ProcessParameters: Pointer; //PRTL_USER_PROCESS_PARAMETERS;
SubSystemData: Pointer;
ProcessHeap: Pointer;
FastPebLock: Pointer;
FastPebLockRoutine: Pointer;
FastPebUnlockRoutine: Pointer;
EnvironmentUpdateCount: Cardinal;
KernelCallbackTable: PPointer;
EventLogSection: Pointer;
EventLog: Pointer;
FreeList: Pointer; //PPEB_FREE_BLOCK;
TlsExpansionCounter: Cardinal;
TlsBitmap: Pointer;
TlsBitmapBits: array[0..1] of Cardinal;
ReadOnlySharedMemoryBase: Pointer;
ReadOnlySharedMemoryHeap: Pointer;
ReadOnlyStaticServerData: PPointer;
AnsiCodePageData: Pointer;
OemCodePageData: Pointer;
UnicodeCaseTableData: Pointer;
NumberOfProcessors: Cardinal;
NtGlobalFlag: Cardinal;
Spare2: array[0..3] of Byte;
CriticalSectionTimeout: LARGE_INTEGER;
HeapSegmentReserve: Cardinal;
HeapSegmentCommit: Cardinal;
HeapDeCommitTotalFreeThreshold: Cardinal;
HeapDeCommitFreeBlockThreshold: Cardinal;
NumberOfHeaps: Cardinal;
MaximumNumberOfHeaps: Cardinal;
ProcessHeaps: Pointer;
GdiSharedHandleTable: Pointer;
ProcessStarterHelper: Pointer;
GdiDCAttributeList: Pointer;
LoaderLock: Pointer;
OSMajorVersion: Cardinal;
OSMinorVersion: Cardinal;
OSBuildNumber: Cardinal;
OSPlatformId: Cardinal;
ImageSubSystem: Cardinal;
ImageSubSystemMajorVersion: Cardinal;
ImageSubSystemMinorVersion: Cardinal;
GdiHandleBuffer: array [0..33] of Cardinal;
PostProcessInitRoutine: Cardinal;
TlsExpansionBitmap: Cardinal;
TlsExpansionBitmapBits: array [0..127] of Byte;
SessionId: Cardinal;
end;
//Get PEB block current win32 process
function GetPDB: PPEB; stdcall;
asm
MOV EAX, DWORD PTR FS:[30h]
end;
initialization
//Detect true windows wersion
Win32MajorVersionReal := GetPDB^.OSMajorVersion;
Win32MinorVersionReal := GetPDB^.OSMinorVersion;
end.
Как сказал Мэтт, Spark - это хорошо, но для некоторых простых шаблонов это может быть излишним, а если вы не используют его в MVC.
Я лично добился большого успеха с NVelocity, и я также публикую простой пример / оболочку по его использованию: http://simpable.com/code/simpletemplate/
Кроме того, вся тематическая система GraffitiCMS работает на NVelocity (хотя я бы использовал Spark, если бы он был доступен для этой задачи).
-Scott
Один из способов сделать это - создать XSL-файл в качестве шаблона, сериализовать свой customDataObject
как XML, а затем выполнить преобразование для генерации необходимого HTML.
Обновить. : Хотя мне нравится (и я использую) метод замены строк, предложенный здесь другими людьми, существует определенная гибкость в использовании XML / XSL. Предположим, у вашего объекта есть свойство, которое является списком, например, объект заказа со списком объектов строки, вам в значительной степени нужно встроить в свой код логику, которая должна отображать элементы строки.
С XSL все вы do передает XML сериализованного объекта заказа в XSL и позволяет XSL обрабатывать любой HTML, который ему необходимо сгенерировать. Это означает, что вы часто можете редактировать XSL на месте или иметь варианты (сводка заказа, подробный порядок и т. д.) без добавления дополнительного кода в ваше приложение со всеми дополнительными хлопотами, связанными с перестройкой / развертыванием.
Но тогда все зависит от сложности того, что вам нужно визуализировать, для некоторых заданий замена строки более очевидна, для других XSL - это способ. Как я уже сказал, мы используем оба.
Вот код, который иллюстрирует довольно простой способ выполнить то, что вы пытаетесь сделать:
using System;
using System.IO;
public class HtmlTemplate
{
private string _html;
public HtmlTemplate(string templatePath)
{
using (var reader = new StreamReader(templatePath))
_html = reader.ReadToEnd();
}
public string Render(object values)
{
string output = _html;
foreach (var p in values.GetType().GetProperties())
output = output.Replace("[" + p.Name + "]", (p.GetValue(values, null) as string) ?? string.Empty);
return output;
}
}
public class Program
{
void Main()
{
var template = new HtmlTemplate(@"C:\MyTemplate.txt");
var output = template.Render(new {
TITLE = "My Web Page",
METAKEYWORDS = "Keyword1, Keyword2, Keyword3",
BODY = "Body content goes here",
ETC = "etc"
});
Console.WriteLine(output);
}
}
Используя это, все, что вам нужно сделать, это создать несколько шаблонов HTML и заполнить их заменяемыми токены, такие как [TITLE], [METAKEYWORDS] и т. д. Затем передайте анонимные объекты, которые содержат значения для замены токенов. Вы также можете заменить объект значения словарем или чем-то подобным.
Ознакомьтесь с документом . Он использует механизм представления Spark для визуализации шаблонного HTML из консольного приложения. Довольно просто.
Другой вариант вместо использования XSLT, как предлагает Кев, - использовать форматирование именованных строк. Используя код , как в этом примере Фила Хаака.
Здесь вы можете иметь свой шаблон в виде строки (возможно, прочитать из файла) и отформатировать его с помощью данного объекта.
Теперь вы можете сделать что-то вроде этого:
var person = new { FirstName = "rune", LastName = "grimstad" };
string template = "<html><body><h1>Hello {FirstName} {LastName}</h1></body></html>";
string html = NamedFormat(template, person);