Can multiple ProgIDs point to the same ClsID? - windows

I am working on a set of what are essentially plugins, which are COM servers. Each plugin has a set of configuration data which is managed by another component, the primary key to the configuration data is the plug-in's ProgID. When the plugin needs to access a configuration item, it makes a call and passes in its ProgID and the name of the property required. This is a legacy design and I must maintain backward compatibility.
I now have a requirement to load multiple instances of each plugin, with each instance having a different set of configuration data. The solution I'm considering is to create multiple unique ProgIDs for each plugin, each ProgID would point to the single ClsId for the plugin. Thus, each instance of the plugin would be indentified by its ProgID, the ProgID is still used as the primary key for the configuration data and everything is 100% backward compatible.
So, the questions:
Is this an acceptable technique? (multiple ProgIDs all pointing to a single ClsID).
When my plugin loads, would it be able to tell which ProgID was used to create it?

Prog ids are typically used in two ways: to detect a class id corresponding to a prog id (CLSIDFromProgID() function) - this is used to later call CoCreateInstance() - and to detect a prog id for a given class id - this is usually used to display a human-friendly version of a class id.
Those mappings imply that there's a HKCR{ProgId}\CLSID key with a default value equal to the class id and a HKCR\CLSID{classid}\ProgID key with a default value equal to the ProgId, which means that the mapping is one-to-one. You will just not be able to have more than one prog id under one class id.
A COM component is loaded by calling CoCreateInstance() which is passed a class id - obtained by any means possible, using CLSIDFromProgID() included. There're no ways for a component to tell how the class id was obtained.

Related

OSGi Configuration Admin and MetaType Service

I've been using the OSGi Configuration Admin to implement some basic configuration capability in our program. I now started looking into the MetaType Service specification because I need type information for each configuration property.
It's unclear to me how these two services interact. The Configuration Admin deals with essentially untyped Key/Value pairs. The MetaType Service knows names and types (among other things) of configuration properties, but not their values. My goal is to dynamically generate a configuration/preferences dialog for all components which have a configuration and corresponding metatype information. According to the MetaType Service spec, the service was conceived to cover this exact use case. So I reckon it shouldn't be too difficult
I can retrieve the metatype information with the following the sample code:
ServiceReference metatypeRef = bundleContext.getServiceReference(MetaTypeService.class.getName());
MetaTypeService service = (MetaTypeService) bundleContext.getService(metatypeRef);
MetaTypeInformation information = service.getMetaTypeInformation(myBundle);
After retrieving the MetaTypeInformation object for the required bundle, I have access to all the information contained in the metatype XML definition. In particular, it is possible to access the ObjectClassDefinition:
ObjectClassDefinition ocd = information.getObjectClassDefinition(pid, null);
AttributeDefinition[] attributes = ocd.getAttributeDefinitions(ObjectClassDefinition.ALL);
My questions are:
Given the AttributeDefinition; how can I retrieve the actual value of the underlying property? I know its name, but not its value.
How can I enumerate the metatype information for all components in all bundles that are currently present (active and inactive)? I know how to list all configurations through the Configuration Admin interface. It there perhaps a way to get to the MetaTypeInformation from the Configuration?
The Configuration Admin and MetaType services are separate, but related, specifications. There is no hard link between them, which I think is probably one of the main points that will help to answer your questions.
Essentially Configuration Admin is a store of configuration records. Each configuration record has a unique persistent identifier (PID) and if the configuration record is for a factory configuration then it will also have a Factory PID. The configuration record then also contains a number of key value pairs, where the key is always a String, and the value is one of a limited set of types.
Metatype, on the other hand, is a tool for providing configuration definitions. These describe the expected layout of keys and values in a configuration, including things like the type of the value associated with a given key, a minimum/maximum size for the value, an enumerated list of allowable values, and potentially a default value. Each key/value definition is held in an Attribute Definition, and these are grouped together in an Object Class Definition, which is associated with a PID.
The important difference is that Metatype knows nothing about what the configuration actually is at runtime (it's just information about what shape the configuration should be). Similarly Configuration Admin knows nothing about what shape the configuration should be, it just knows what the values currently are.
Therefore:
Given the AttributeDefinition; how can I retrieve the actual value of the underlying property? I know its name, but not its value.
You need to identify the PID associated with the ObjectClassDefinition containing the Attribute Definition, and then to use this to find the relevant configuration dictionary in Configuration Admin. If the OCD is for a factory PID then you will need to identify which of the configurations for that factory PID you want to look at.
How can I enumerate the metatype information for all components in all bundles that are currently present (active and inactive)? I know how to list all configurations through the Configuration Admin interface. It there perhaps a way to get to the MetaTypeInformation from the Configuration?
The MetaTypeService is a service in the OSGi Service Registry that you can use to ask for the MetaTypeInformation for a given bundle. If you ask for the Metatype Information for each bundle in turn then you will have the information that you are looking for. There is no hard link between Configuration Admin and Metatype, so a Configuration object has no way of knowing whether a meta type exists for it.

How to traverse to a child object from a parent object using in test-complete tool?

I am automating a mobile application using TestComplete tool. I have to get the text of an object from the UI, but the object id keep on changing while change of values. So is there any option in test complete which support -following-sibling or Child Property which exist in selenium tool. So that we can easily traverse from a parent object to track the child or sibling. Please help.
You need to find a property or a set of properties that will uniquely identify the needed object without using its native id. Use these identification criteria to set up the corresponding Name Mapping scheme for this object.
PS. Of course, having a permanent ID for a UI object is the best way to automate tests with the object.

Just what are the conventions of the ODataConventionModelBuilder?

There are lots of examples of using ODataConventionModelBuilder with simple, contrived models, often just a single class.
But there's nothing that actually explains what the conventions are; how to code a model that complies with convention. There's no official documentation for it.
So what's the convention?
From what I've seen so far, the conventions are those used by Entity Framework, as opposed to any new ones for OData. Please correct me if I am wrong.
More on Code-first conventions, below, but there are many more in the Julie Lerman book I have yet I cannot find an exhaustive list of them on the web.
http://blogs.msdn.com/b/efdesign/archive/2010/06/01/conventions-for-code-first.aspx
Update
The EF modelling conventions system is pluggable and each convention is represented by a class encapsulating the behaviour, and those classes are listed here:
http://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.conventions(v=vs.113).aspx
However that doesn't help with which ones are applicable or used by the ODataConventionModelBuilder if any.
AssociationInverseDiscoveryConvention - Provides convention to detect navigation properties to be inverses of each other when only one pair of navigation properties exists between the related types.
AttributeToColumnAnnotationConvention - A general purpose class for Code First conventions that read attributes from .NET properties and generate column annotations based on those attributes.
AttributeToTableAnnotationConvention - A general purpose class for Code First conventions that read attributes from .NET types and generate table annotations based on those attributes.
ColumnAttributeConvention - Represents a convention to process instances of ColumnAttribute found on properties in the model.
ColumnOrderingConvention - Represents a convention to apply column ordering specified via ColumnAttribute or theDbModelBuilder API.
ColumnOrderingConventionStrict - Convention to apply column ordering specified via ColumnAttribute or theDbModelBuilder API. This convention throws if a duplicate configured column order is detected.
ComplexTypeAttributeConvention - Represents the convention to process instances of ComplexTypeAttribute found on types in the model.
ComplexTypeDiscoveryConvention - Represents a convention to configure a type as a complex type if it has no primary key, no mapped base type and no navigation properties.
ConcurrencyCheckAttributeConvention - Represents the convention to process instances of ConcurrencyCheckAttributefound on properties in the model.
Convention - A convention that doesn't override configuration.
DatabaseGeneratedAttributeConvention - Represents a convention to process instances of DatabaseGeneratedAttribute found on properties in the model.
DecimalPropertyConvention - Convention to set precision to 18 and scale to 2 for decimal properties.
DeclaredPropertyOrderingConvention - Represents a convention to move primary key properties to appear first.
ForeignKeyAssociationMultiplicityConvention - Represents a convention to distinguish between optional and required relationships based on CLR nullability of the foreign key property.
ForeignKeyDiscoveryConvention - Represents a base class for conventions that discover foreign key properties.
ForeignKeyIndexConvention - Represents a convention to introduce indexes for foreign keys.
ForeignKeyNavigationPropertyAttributeConvention - Represents a convention to process instances of ForeignKeyAttribute found on navigation properties in the model.
ForeignKeyPrimitivePropertyAttributeConvention - Represents a convention to process instances of ForeignKeyAttribute found on foreign key properties in the model.
IdKeyDiscoveryConvention - Convention to detect primary key properties. Recognized naming patterns in order of precedence are: 1. 'Id' 2. [type name]Id Primary key detection is case insensitive.
IndexAttributeConvention - A convention for discovering IndexAttributeattributes on properties and generatingIndexAnnotation column annotations in the model.
InversePropertyAttributeConvention - Represents a convention to process instances of InversePropertyAttribute found on properties in the model.
KeyAttributeConvention - Convention to process instances ofKeyAttribute found on properties in the model.
KeyDiscoveryConvention - Represents a base class for conventions that discover primary key properties.
ManyToManyCascadeDeleteConvention - Convention to add a cascade delete to the join table from both tables involved in a many to many relationship.
MappingInheritedPropertiesSupportConvention - Convention to ensure an invalid/unsupported mapping is not created when mapping inherited properties
MaxLengthAttributeConvention - Represents a convention to process instances of MaxLengthAttribute found on properties in the model.
NavigationPropertyNameForeignKeyDiscoveryConvention - Convention to discover foreign key properties whose names are a combination of the dependent navigation property name and the principal type primary key property name(s).
NotMappedPropertyAttributeConvention - Represents a convention to process instances of NotMappedAttribute found on properties in the model.
NotMappedTypeAttributeConvention - Represents a convention to process instances of NotMappedAttribute found on types in the model.
OneToManyCascadeDeleteConvention - Provides a convention to enable cascade delete for any required relationships.
OneToOneConstraintIntroductionConvention - Provides a convention to configure the primary key(s) of the dependent entity type as foreign key(s) in a one:one relationship.
PluralizingEntitySetNameConvention - Represents a convention to set the entity set name to be a pluralized version of the entity type name.
PluralizingTableNameConvention - Represents a convention to set the table name to be a pluralized version of the entity type name.
PrimaryKeyNameForeignKeyDiscoveryConvention - Convention to discover foreign key properties whose names match the principal type primary key property name(s).
PrimitivePropertyAttributeConfigurationConvention - Base class for conventions that process CLR attributes found on primitive properties in the model.
PropertyAttributeConfigurationConvention - Base class for conventions that process CLR attributes found on properties of types in the model.
PropertyMaxLengthConvention - Represents a convention to set a maximum length for properties whose type supports length facets. The default value is 128.
RequiredNavigationPropertyAttributeConvention - Convention to process instances ofRequiredAttribute found on navigation properties in the model.
RequiredPrimitivePropertyAttributeConvention - Represents a convention to process instances of RequiredAttribute found on primitive properties in the model.
SqlCePropertyMaxLengthConvention - Represents a convention to set a default maximum length of 4000 for properties whose type supports length facets when SqlCe is the provider.
StoreGeneratedIdentityKeyConvention - Represents a convention to configure integer primary keys to be identity.
StringLengthAttributeConvention - Represents a convention to process instances of StringLengthAttribute found on properties in the model.
TableAttributeConvention - Represents a convention to process instances of TableAttribute found on types in the model.
TimestampAttributeConvention - Represents a convention to process instances of TimestampAttribute found on properties in the model.
TypeAttributeConfigurationConvention - Base class for conventions that process CLR attributes found in the model.
TypeNameForeignKeyDiscoveryConvention - Convention to discover foreign key properties whose names are a combination of the principal type name and the principal type primary key property name(s).
The best explanation I'm aware of, is here
Routing Conventions in ASP.NET Web API 2 Odata
NB this is Odata 3, not odata 4
The conventions used in ODataConventionModelBuilder are described here.
As for how to code a model that complies with the conventions, that is pretty straight forward, or rather you don't need to code a model to the conventions at all. The conventions exist to simplify and standardize how an EF model is expressed in an OData Edm Model. If you find yourself manually enabling features, then you might find there is a convention that can automate this process for you. Understanding what the conventions are might help.
Your answer #LukePuplett describes some of the EF Code First conventions, they don't really apply here, not all directly anyway. I don't want to say you were wrong... ;)
The following is derived from the source code for ConventionModelBuilder.
Type and Property Conventions
NOTE: ordering is important here.
AbstractTypeDiscoveryConvention
configures all structural types backed by an abstract CLR type as abstract.
DataContractAttributeEdmTypeConvention
Configures classes that have the DataContractAttribute to follow DataContract serialization/deserialization rules.
NotMappedAttributeConvention
Ignores properties with the NotMappedAttribute from IEdmStructuredType
NotMappedAttributeConvention MUST run before EntityKeyConvention, or it will allow Keys to be excluded from the model
DataMemberAttributeEdmPropertyConvention
Configures properties that have DataMemberAttribute as optional or required on their edm type.
NOTE: This does not explicitly remove properties that have IgnoreDataMemberAttribute, but it will not explicitly add them either
DerivedTypeConstraintAttributeConvention
Adds Derived Type Constraints to the Model if required
RequiredAttributeEdmPropertyConvention
Marks properties that have RequiredAttribute as non-optional on their edm type.
DefaultValueAttributeEdmPropertyConvention
Sets default value for properties that have DefaultValueAttribute
ConcurrencyCheckAttributeEdmPropertyConvention
Marks properties that have ConcurrencyCheckAttribute as non-optional on their EDM type.
TimestampAttributeEdmPropertyConvention
Annotates a single column in a Type as the Timestamp column, even if multiple columns are annotated with the TimestampAttribute.
This is due to a SQL limitation table (the underlying concept this attribute is bounded to) that only supports one row version column per table.
ColumnAttributeEdmPropertyConvention
Marks properties that have ColumnAttribute as the target EDM type.
KeyAttributeEdmPropertyConvention
Configures properties that have the KeyAttribute as keys in the IEdmEntityType
KeyAttributeEdmPropertyConvention MUST run before EntityKeyConvention
EntityKeyConvention
This convention configures properties that are named 'ID' (case-insensitive) or {EntityName}+ID (case-insensitive) as the key.
ComplexTypeAttributeConvention
Removes primitive properties that are exposed through ComplexType definitions from the IEdmEntityType
This MUST run after Key conventions, basically overrules them if there is a ComplexTypeAttribute
IgnoreDataMemberAttributeEdmPropertyConvention
Removes properties that have IgnoreDataMemberAttribute from their edm type.
If class is a DataContract and DataMemberAttribute is present on this property, then the property will not be removed, DataMemberAttribute takes precedence
NotFilterableAttributeEdmPropertyConvention
Configures a column with fluent IsNotFilterable() if it has a NotFilterableAttribute annotation. This will specify that the property cannot be used in the $filter OData query option.
This is the same implementation as NonFilterableAttribute and its related NonFilterableAttributeEdmPropertyConvention
NonFilterableAttributeEdmPropertyConvention
Configures a column with fluent IsNotFilterable() if it has a NonFilterableAttribute annotation. This will specify that the property cannot be used in the $filter OData query option.
This is the same implementation as NotFilterableAttribute and its related NotFilterableAttributeEdmPropertyConvention;
NotSortableAttributeEdmPropertyConvention
Configures a column with fluent IsNotSortable() if it has a NotSortableAttribute annotation. This will specify that the property cannot be used in the $orderby OData query option.
UnsortableAttributeEdmPropertyConvention
Configures a column with fluent IsNotSortable() if it has a UnsortableAttribute annotation. This will specify that the property cannot be used in the $orderby OData query option.
NotNavigableAttributeEdmPropertyConvention
Configures a column with fluent IsNotNavigable() if it has the NotNavigableAttribute annotation. This will specify that the property cannot be navigated in OData query.
This does not preclude $expand, it means that the propert cannot be used to traverse to the associated resource using an Entity Path, for instance if ProductType had this attribute, and was a navigation property that returned a ProductType reference, the following OData path would not be servived: ~/api/products(112)/ProductType this is a feature from the updates to support Containment.
NotExpandableAttributeEdmPropertyConvention
Configures a column with fluent IsNotExpandable() if it has a NotExpandableAttribute annotation. This will specify that the property cannot be used in the $expand OData query option.
NotCountableAttributeEdmPropertyConvention
Configures a column with fluent IsNotCountable() if it has a NotCountableAttribute annotation. This will specify that the $count cannot be applied on the property.
MediaTypeAttributeConvention
Configures a class with fluent MediaType() which marks this entity type as media type.
AutoExpandAttributeEdmPropertyConvention
Configured the AutoExpand feature of a column when it has the AutoExpandAttribute annotation.
AutoExpandAttributeEdmTypeConvention
When AutoExpandAttribute is placed on a class it can specify all navigation properties are auto expanded.
MaxLengthAttributeEdmPropertyConvention
Configures string or binary properties that have the MaxLengthAttribute annotation.
PageAttributeEdmPropertyConvention
Sets the page size and Max Top of the entity type based on the PageAttribute annotation if present on any of the properties in the class.
There is no added value of supporting this on a property level, but it is offered as a redundancy for poorly configured code.
PageAttributeEdmTypeConvention
Sets the page size and Max Top of the entity type based on the PageAttribute annotation on the class.
ExpandAttributeEdmPropertyConvention
Configures OData $expand query option for navigation columns with ExpandAttribute annotation.
ExpandAttributeEdmTypeConvention
Set the ExpandConfigurations of navigation properties of this structural type based on the ExpandAttribute annotation on the class.
CountAttributeEdmPropertyConvention
Configures the $count OData query options for specific columns with the CountAttribute annotation. The $count OData query option can be explicity enabled or disabled with the CountAttribute annotation.
CountAttributeEdmTypeConvention
Set whether the $count can be applied on the edm type. The $count OData query option can be explicity enabled or disabled with the CountAttribute annotation.
OrderByAttributeEdmTypeConvention
Configures the OData $orderby query option settings for a type based on the OrderByAttribute on the class or on the properties.
When used on a class, the default $orderby value can be specified.
When used on properties it can also prevent that property from being referenced in an $orderby OData query option.
FilterAttributeEdmTypeConvention
Configures the OData $filter query option settings for a type based on the FilterAttribute on the class or properties.
OrderByAttributeEdmPropertyConvention
Configures the OData $orderby query option settings for a type based on the OrderByAttribute on the class or on the properties.
When used on a class, the default $orderby value can be specified.
When used on properties it can also prevent that property from being referenced in an $orderby OData query option.
FilterAttributeEdmPropertyConvention
Configures the OData $filter query option settings for a type based on the FilterAttribute on the class or on the properties.
When used on a class, the default $filter value can be specified.
When used on properties it can also prevent that property from being referenced in an $filter OData query option.
SelectAttributeEdmTypeConvention
For classes that have SelectAttribute, the attribute will list the properties that can be referenced by the $select OData query option for this structural type.
SelectAttributeEdmPropertyConvention
Configures the OData $select query option settings for a type based on the SelectAttribute on the class or on the properties.
When used on a class, the default $select value can be specified.
When used on properties it can also prevent that property from being referenced in an $select OData query option.
INavigationSourceConvention's
SelfLinksGenerationConvention
Generates Item and Edit links in the OData annotations.
NavigationLinksGenerationConvention
Generate links without cast for declared and inherited navigation properties, or with a cast in derived types.
AssociationSetDiscoveryConvention
This convention adds an association set for each EDM navigation property defined in this type, its base types and all its derived types.
The target navigation source chosen is the default navigation source for the navigation property's target entity type.
The default navigation source for an entity type is the navigation source that contains entity of that entity type.
If more than one navigation source match, the default navigation source is none.
If no navigation sources match the default navigation source is the default navigation source of the base type.
IEdmFunctionImportConventions's
ActionLinkGenerationConvention
calls action.HasActionLink(..) if the action binds to a single entity and has not previously been configured.
FunctionLinkGenerationConvention
calls function.HasFunctionLink(..) if the function binds to a single entity and has not previously been configured.
Interesting notes:
I tried to do some research on the history of NotFilterableAttribute vs NonFilterableAttribute but struggled to find a point of divergence in the open source libraries. Both of these attributes exist in the VS 2013 help docs and the System.Web.OData.Query namespace. I assume at one point two different namespaces or libraries were merged together and the attributes were retained for backward compatibility.
What should have happened in the associated commit was that one of these attributes should have been deprecated (annotated with [Obsolete]) and in a future version that deprecated class should have been removed, certainly long before now.
This same situation exists with NotSortableAttribute and UnsortableAttribute...
Some of these conventions have the same implementation in two different convention classes, one mapped to the Entity Type, the other to the Property. At first glance this looks redundant, but it is necessary for attributes that support both class and property annotation. The reason it is necessary is that the presence of the associated attribute triggers the convention to be evaluated at all. The OData conventions do not operate like the EF code first conventions that evaluate all types and properties for a match. The model is iterated, not the conventions. A class level attribute application, like PageAttribute if we want to allow it to be specified on the property it still needs to apply the logic to the Edm Type. The reverse is try to for FilterAttribute that can be declared once on the Edm Type with an array of properties, or you can manage the properties individually, you might even have both, with property level attributes to explicitly prevent $filter access.
I can only speculate that someone decided that this was a necessary performance measure as these conventions are evaluated at runtime, we could measure it later if anyone is interested ;)
For these classes that have multiple similar implementations, I would have designed the logic such that there was a single class that defined the common logic and the concrete types would reference it. This satisfies the DRY principal but also makes the code and patterns like this more discoverable.

Custom model metadata provider caching issue

In order to allow us dynamic control over labels and error messages, we created a custom DataAnnotationsModelMetadataProvider. In a Display attribute we store the key in the Name property and using the custom DataAnnotationsModelMetadataProvider we substitute the key for a string value from our custom CMS. The problem is that we now have two sets of values. One for Web views and one for mobile views. At runtime we check if the client is on a mobile device and substitute the values accordingly.
After test running this setup I came across a strange issue. When the AppDomain is first created and the Name properties of the different data annotations are replaced with the string values, everything works fine. In debug, when I enter the custom DataAnnotationsModelMetadataProvider for a second time, I see the name properties already populated with the values I had substituted the previous run. This was strange to me, since it was my understanding that data annotation propeties could not be chnaged at runtime. It now seems like there is a model metadata cache happening somewhere. Since I based my custom solution on replacing the values each time the DataAnnotationsModelMetadataProvider is called upon, I would like to disable this caching, if possible.
For now I started using the ShortName property as my key storing property and I replace the Name property, and this way I can repopulate the strings on each run. But this was not the initial design and I don't have such a key store property for ValidationAttributes.
So is there a way to disable this cache? I don't need the cache for the sake of caching, since all CMS data is cached in memory in another layer anyway.

Is there a way to rename a COM component without actually recompiling the source code?

I have a legacy system that contains an old COM component running under COM+. We have a need to rename this old component, but we don't have the source code. Is there any way to rename the component (not the application) without recompiling?
The "name" for the COM class is known as ProgID:
A programmatic identifier (ProgID) is a registry entry that can be associated with a CLSID. Like the CLSID, the ProgID identifies a class but with less precision because it is not guaranteed to be globally unique.
The identifier's purpose is to provide a mapping to the primary identifier for the class, CLSID. Hence, you can manually create another/alternate key with another name, mapping ot the same CLSID, and it is going to do the trick in question.
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\<New-ProgID>\CLSID
(default value) = <Same-CLSID>
Keep in mind that the key for 32-bit component on 64-bit system is:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\<New-ProgID>\CLSID
CLSID subkey is the primary of your interest, you will supposedly want to duplicate all subkeys and values from your original ProgID key (in particular VersionIndependentProgID if you have it for your class).
Then, COM+ specific part is ProgID subkey under CLSID, where DCOMCNG (you are referring to in comments as "COM+ Applications | MyApplication | Components") takes names from:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\<Your-CLSID>\ProgID
(default value) = <ProgID>
Renaming this would have effect on COM+ application. The same keys/values are supposedly used in the application itself (this is true for the first two, and I am not sure about the last COM+ specific one).

Resources