How do I re-write an assembly's metadata?

G

Guest

I need to open an assembly, change some custom attribute's values and then re-write the assembly without re-compiling it.

I tried using Reflection.Emit, but I couldn't cast (System.Reflection.)Assembly to (System.Reflection.Emit.)AssemblyBuilder, which is the class where custom attributes are writeable (in System.Reflection.Assembly they're just readable) and has a "save" method. What's the difference between a dynamic assembly and a common one?? I guess a dynamic assembly is one changed using Reflection.Emit, not persisted, and loaded using CreateInstance

A friend recommended me to use CodeDom, but that's not what I need, I don't want to depend on the source code and re-compile the assembly, what I want is to change the assembly with no re-compiling.

I also read some info about this IMetaDataImport.IMetaDataAssemblyImport interface which is exposed via IMetaDataDispenser interface, and provides a way to change assembly's metadata and persist this changes, but I do not have enough documentation. I would appreciate some help, source code samples, whatever...

Thanks a lot!

Ricardo Carrasco
 
P

Patrick Steele [MVP]

I need to open an assembly, change some custom attribute's values and then
re-write the assembly without re-compiling it.

Why?

I doubt its possible since this would allow someone to circumvent
security permissions and other things that may be defined in the
metadata.
 
P

Patrick Steele [MVP]

I'm trying to develop a configuration utility to display assembly's
info (like ildasm) and change custom attributes in a similar way
to the Component Services' Component properties dialog.

The purpose of this utility... change custom attributes like
transaction, synchronization, object pooling, or any user
defined attribute.

But attributes are applied for a reason. You can't change a transaction
attribute on a component that was designed from the beginning to be non-
transactional. Likewise for synchronization.

I don't think it's possible and it doesn't sound like a good idea.
 
G

Guest

But attributes are applied for a reason. You can't change a transaction
attribute on a component that was designed from the beginning to be non-
transactional. Likewise for synchronization.

I don't think it's possible and it doesn't sound like a good idea.

Maybe you may want to change the object pooling attribute 'cause a component has a lower workload. You may want to change the connection string stored in the constructor string of a component.

Anyway I'm interested in changing user defined attributes, like a "logging" attribute that could be set to log to event viewer/text file/xml file.

I know it's possible, this can be done at runtime using Reflection.Emit, but I just want to persist this changes and don't know how to do it. I know there's another way using IMetaDataDispenser interface (referencing cor.h), but I need more information, documentation or code samples.

Thanks!
 
G

Guest

I think a better option for you would be to bundle a configuration file with your assembly. Your assembly could the query the config file for the configurable data. I've never heard of anyone modifying the assembly's manifest to change a database connection string before.

Regards,

Les T.
 
R

Richard Grimes [MVP]

Patrick Steele said:
But attributes are applied for a reason. You can't change a transaction
attribute on a component that was designed from the beginning to be non-
transactional. Likewise for synchronization.

I don't think it's possible and it doesn't sound like a good idea.

Well, in general it is possible, because the metadata table format is
published, so you could hack into it. But I agree, you shouldn't do it.

In addition, the OP says that he wants to change enterprise services
attributes like transaction and object pooling. An assembly that uses
enterprise services should have a strong name and when you do this the
compiler will create a hash from the assembly (including the metadata
tables), sign it with your private key and store the signed hash and public
key in the assembly. This hash is checked when the assembly is loaded, and
if the metadata table is changed the hash will change and the assembly will
not load. So the OP, when tampering with the metadata tables, will have to
recreate the signed hash: re-sign the assembly. Creating the hash is easy,
but signing it is impossible if you don't have the private key.

You could use the COM+ catalog objects to change the class's attributes once
the assembly has been added to the COM+ catalog (that's what the attributes
are for - regsvcs reads them and adds values to the COM+ catalog), but
again, this is not recommended because the class writer knows far more about
his/her class than any administrator does!

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top