using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
namespace GuidToType {
public class TypeGuidHelper : IDisposable {
public TypeGuidHelper()
: this(AppDomain.CurrentDomain) {
}
public TypeGuidHelper(AppDomain domain) {
if (ReferenceEquals(domain, null))
throw new ArgumentNullException("domain");
this._domain = domain;
this._type_locker = new ReaderWriterLock();
this._types = new Dictionary<Guid, Type>();
_domain.AssemblyLoad += CurrentDomain_AssemblyLoad;
foreach (Assembly asmb in _domain.GetAssemblies())
ProcessAssemblyTypes(asmb);
}
private AppDomain _domain;
public AppDomain Domain {
get {
return _domain;
}
}
private Dictionary<Guid, Type> _types;
private ReaderWriterLock _type_locker;
private void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args) {
ProcessAssemblyTypes(args.LoadedAssembly);
}
private void ProcessAssemblyTypes(Assembly asmb) {
_type_locker.AcquireWriterLock(-1);
try {
foreach (Type type in asmb.GetTypes()) {
_types[type.GUID] = type;
}
} finally {
_type_locker.ReleaseWriterLock();
}
}
public Type this[Guid id] {
get {
_type_locker.AcquireReaderLock(-1);
try {
return _types[id];
} finally {
_type_locker.ReleaseReaderLock();
}
}
}
public bool TryGetType(Guid id, out Type type) {
_type_locker.AcquireReaderLock(-1);
try {
return _types.TryGetValue(id, out type);
} finally {
_type_locker.ReleaseReaderLock();
}
}
#region IDisposable Members
public void Dispose() {
_domain.AssemblyLoad -= CurrentDomain_AssemblyLoad;
}
#endregion
}
class Program {
class NestedClass {
}
static void Main(string[] args) {
using (TypeGuidHelper helper = new TypeGuidHelper()) {
Type type;
if (helper.TryGetType(typeof(NestedClass).GUID, out type)) {
Console.WriteLine(type);
} else {
Console.WriteLine("Type not found");
}
}
Console.ReadLine();
}
}
}
C# Узнать тип данных по GUID
Имеется файл Data.txt с двоичными данными.
В каждой его строке, начиная со 2й хранится GUID и состветствующая стандартная структура NET.Framework в двоичном(!!!) виде.
Задача:
1) Определить типы структур, зранимых в файле
2) Вывести значения структур, записанных в файле.
P.S. На экзамене в файле будет более 50ти структур для каждого варианта.
Cамое главное на мой взгляд - 1. Зная первое - второе - дело техники потому как все структуры имеют пустой конструктор.
Вот как я действовал:
Код:
static void GetTypeInBinaryFile(String^ path_name)
{
FILE* F = fopen((char*)(void*)Marshal::StringToHGlobalAnsi(path_name),"r");
Guid GUID;
char c;
while(fscanf(F,"%c",&c)>0)
{
fread(&GUID,16,1,F);
Type^ T = Type::GetTypeFromCLSID(GUID);
Console::WriteLine(T);
}
fclose(F);
}
{
FILE* F = fopen((char*)(void*)Marshal::StringToHGlobalAnsi(path_name),"r");
Guid GUID;
char c;
while(fscanf(F,"%c",&c)>0)
{
fread(&GUID,16,1,F);
Type^ T = Type::GetTypeFromCLSID(GUID);
Console::WriteLine(T);
}
fclose(F);
}
Но все типы определились как __ComObject!
И вот как дальше - моей фантазии не хватает.
В принципе мой препод любит давать то, что невозможно, но тогда для того чтоб не делать невозможное, ему нужно доказать невозможность невозможного.
Поэтому прошу вашей помощи. Что посоветуете?
Цитата: sigmov
все типы определились как __ComObject!
Правильно определились.
CLSID это идентификатор COM-объектов.
Идентификатор типа в CLR совсем другой гуид. С ходу получилось вот что:
Код:
З.Ы. А чего тему то в "Студентах" разместил? Вопрос то не самый тривиальный. :)