.NET versioning

H

harvey.kwok

Hi all,

We have delivered a product with version 2.0.0.66 to our customers.
This product includes product.exe and library.dll. Then, the
development is continued. Now, we are at the version of 2.0.0.77. We
are not ready to ship this version to our customers but we have started
another product called tools.exe which also need the assembly
library.dll. We want to ship tools.exe to our customer. However, as
the library.dll is too large, we want to just ship the tools.exe with
version 2.0.0.77 only. Customers can install tools.exe only if they
have product.exe and library.dll installed and the tools.exe will only
be installed in the same folder as product.exe.

As I build my tools.exe with library.dll v2.0.0.77, if customer just
installs tools.exe, it cannot find the correct library. Is there any
way to let my tools.exe always loading the library.dll on the same
folder regardless what its version is?

Thanks in advance.

- harvey
 
F

Frans Bouma [C# MVP]

Hi all,

We have delivered a product with version 2.0.0.66 to our customers.
This product includes product.exe and library.dll. Then, the
development is continued. Now, we are at the version of 2.0.0.77. We
are not ready to ship this version to our customers but we have
started another product called tools.exe which also need the assembly
library.dll. We want to ship tools.exe to our customer. However, as
the library.dll is too large, we want to just ship the tools.exe with
version 2.0.0.77 only. Customers can install tools.exe only if they
have product.exe and library.dll installed and the tools.exe will only
be installed in the same folder as product.exe.

As I build my tools.exe with library.dll v2.0.0.77, if customer just
installs tools.exe, it cannot find the correct library. Is there any
way to let my tools.exe always loading the library.dll on the same
folder regardless what its version is?

Yes, that's called a policy file. Please check the .NET documentation
about policy files. Basicly it comes down to you define a policy dll
with a xml file which is installed in the GAC and which redirects calls
from one version to the other.

You have to consider a couple of other options as well. I have the
feeling that 2.0.0.66 and 2.0.0.77 are functionally the same and have
the same interfaces, correct? It's just that 2.0.0.66 doesn't contain
bugfixes which are present in 2.0.0.77 ?

If that's the case, you could try to use assembly FILE versions
instead. This is also the technique Microsoft uses for hotfixes and
service packs on .NET: the version is the same (2.0.0.0) but the file
version value in the assemblyfileversion attribute changes. You can
install a file with a newer FILE version in the GAC even if it has the
same assembly version.

The advantage is of course that if you have a bugfix release, you can
simply hand out a new build, and no recompiles have to take place nor
do you have to update policy files.

FB

--
 
H

harvey.kwok

Thanks Frans,

You are correct. 2.0.0.77 includes some bug fixes but the interface is
the same as 2.0.0.66. I have tried policy file actually. The problem
now is that

1) My supervisor doesn't want to release the library.dll v2.0.0.77. He
just wants to release tools.exe v2.0.0.77 and he thinks we should be
able to whatever library.dll installed on the customer's machine.

2) If I use policy file, I need to redirect them to use 2.0.0.66
explicitly. The problem is some of our customers are actually using
2.0.0.70.

I know it is a mess. Is there any way telling .NET to forget version
checking?

- HK
 
F

Frans Bouma [C# MVP]

Thanks Frans,

You are correct. 2.0.0.77 includes some bug fixes but the interface
is the same as 2.0.0.66. I have tried policy file actually. The
problem now is that

1) My supervisor doesn't want to release the library.dll v2.0.0.77.
He just wants to release tools.exe v2.0.0.77 and he thinks we should
be able to whatever library.dll installed on the customer's machine.

What people want is sometimes not relevant. If he wants X but X is
impossible, he can keep on wanting X but if that's impossible, it will
never happen.

If tools.exe v2.0.0.77 references library.dll v2.0.0.77, he can
release tools.exe v77 but that will never run on systems with
library.dll v66.
2) If I use policy file, I need to redirect them to use 2.0.0.66
explicitly. The problem is some of our customers are actually using
2.0.0.70.

I know it is a mess. Is there any way telling .NET to forget version
checking?

Your policy file should simply do something like:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="library"
publicKeyToken="xxxxxxxxxxxxx"/>
<bindingRedirect oldVersion="2.0.0.0-2.0.0.76"
newVersion="2.0.0.77"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

so all references to versions below v77 will be redirect to use dll
v77.

So application.exe v66 which references dll version 66 will then use
dll v77 without problems. No recompile needed :)

Frans




--
 
R

Richard Grimes

Frans said:
If that's the case, you could try to use assembly FILE versions
instead. This is also the technique Microsoft uses for hotfixes and
service packs on .NET: the version is the same (2.0.0.0) but the file
version value in the assemblyfileversion attribute changes. You can
install a file with a newer FILE version in the GAC even if it has the
same assembly version.

This will work with hotfixes, because Microsoft know what they are
doing, and anyway, they control the operating system. You *should not*
do this yourself because it is a return to Win32 DLL Hell.

The reason is that the new version will overwrite the old version. The
GAC recognises *only* the .NET version, not the version in the
VERSIONINFO unmanaged resource, so gacutil just thinks you are inserting
the same assembly into the GAC and hence it overwrites what's there.
(When you use gacutil it will put the file in a special folder with a
name constructed line this: <.net version>_<culture>_<publickeytoken>
and since these will be the same for both versions, the later one will
over write the former.)

So you have two assemblies installed into the GAC and two uninstall
processes, and yet there is only one physical file in the GAC. This
means that after the first uninstall has been run *all* applications
that remain that use this library will stop working. You can get around
this issue with GAC references.

However, since this is just DLL Hell being applied to .NET, I would
recommend that this 'solution' should not be used.

Richard
 
F

Frans Bouma [C# MVP]

Richard said:
This will work with hotfixes, because Microsoft know what they are
doing, and anyway, they control the operating system. You *should
not* do this yourself because it is a return to Win32 DLL Hell.

The reason is that the new version will overwrite the old version.
The GAC recognises only the .NET version, not the version in the
VERSIONINFO unmanaged resource, so gacutil just thinks you are
inserting the same assembly into the GAC and hence it overwrites
what's there. (When you use gacutil it will put the file in a
special folder with a name constructed line this: <.net
version>_<culture>_<publickeytoken> and since these will be the same
for both versions, the later one will over write the former.)

Isn't that the intention? You have version 1.0.0.0 and you have a
bugfix release. So you release a new version of the dll, same assembly
version. You copy the file into the gac, it overwrites the old one and
all your apps using the 1.0.0.0 version use now the bugfixes.

I said 'bugfixes' thus not new features.
So you have two assemblies installed into the GAC and two uninstall
processes, and yet there is only one physical file in the GAC. This
means that after the first uninstall has been run all applications
that remain that use this library will stop working. You can get
around this issue with GAC references.

No install processes, you copy the files.

Uninstalling indeed removes the file, but that's not the point here.
The point is that with a bugfix you otherwise have to produce policy
files and / or recompiles.
However, since this is just DLL Hell being applied to .NET, I would
recommend that this 'solution' should not be used.

That's great but what's your 'solution' then? It's always nice to see
people saying "I Don't recomment this!!" and at the same time they
don't have an answer to the question: what to do instead?

Because if you sign your assemblies, and you simply use buildnumbers
for bugfixes, you have to use policy files to be sure everything keeps
on working, OR Recompile everything else.

policy files require an installer, while with fileversions you can
just drag/n/drop the dll into the gac and be done with it: for example
in the situation where you leave it to the user to store the dlls in
the GAC or keep them local to the application. So, for the users who
want the dlls in the gac (or need to, because of some issues with
fusion's loader, like Oracle's ODP.NET dlls can confuse the loader and
it suddenly forgets probing paths) they can simply add them to the gac,
and for the people who don't want to do that, they can simply avoid the
GAC altogether. After all, Microsoft themselves state that if you can
avoid the GAC you should.

FB



--
 
D

David Levine

Frans Bouma said:
Isn't that the intention? You have version 1.0.0.0 and you have a
bugfix release. So you release a new version of the dll, same assembly
version. You copy the file into the gac, it overwrites the old one and
all your apps using the 1.0.0.0 version use now the bugfixes.

I said 'bugfixes' thus not new features.

If this isn't dll hell then it's awfully close. What would you then do if it
turned out that the "bugfixed" version was buggy itself, but with different
bugs? You could not roll it back because the original version was
overwritten.

This also creates a situation where different versions of the same dll can
exist without any way to tell them apart (well, any good way). Relying on
the timedate stamp or the VERSIONINFO block to tell them apart it is not a
good way to handle it either. Typically the assembly version and the
VERSIONINFO contain the same version number, but the runtime does not
evaluate the VERSIONINFO information for binding purposes, so the app will
bind to the copy of the file that runtime evaluates first. A support person
will have a hard time distinguishing between the different versions of the
same assembly, and this really isn't a story I'd want to tell a customer
("yes I know it 'says' its the same version, but trust me, it's a different
version...")

Even if using publisher policy is ugly (I don't like it much myself) it is
still better then this.

No install processes, you copy the files.

Are you suggesting that an install program manually copy the new "fixed"
versions directly over the existing files in the GAC? whew...

This is really going to get even more complicated when 64 bit gacs are in
used, along with other variants of the gac, along with all the distinctions
in naming conventions used for the subdirectories. There are already
multiple system gacs installed on systems. Also, how will this work on a
system with both v1.1 and v2.0 installed? Which gac will you overwrite?

I think that bypassing the GAC install/uninstall APIs is not a good way to
go...
Uninstalling indeed removes the file, but that's not the point here.
The point is that with a bugfix you otherwise have to produce policy
files and / or recompiles.

That's exactly the point. Even an update that contains only bugfixes is
still a new assembly that may destabilize applications that use them. I've
experienced far too many updates that did more damage then they fixed to be
willing to overwrite a previous version...I may need it back again.

That's great but what's your 'solution' then? It's always nice to see
people saying "I Don't recomment this!!" and at the same time they
don't have an answer to the question: what to do instead?

For assemblies in the GAC use publisher policy or recompile...this does not
seem to be any worse then your proposal, and I think it is better in many
respects. An even better solution is to avoid using the GAC whevever
possible.

I prefer to avoid using the system GAC. I wrote my own version of a local
GAC that is deployed with my app and is xcopy deployable; it's mainly a
mechanism to ensure that shared assemblies get loaded correctly. It doesn't
do all the things that the global GAC does, but it does not need to. Updates
will only affect that application.

I think the natural tendency will be to make the system GAC become a dumping
ground for assemblies that really ought to be private but are public and
global. There will be many reasons for this, some good and some not so good.
IMO, over time the GAC will become the same sort of management nightmare
that the registry turned into.


Because if you sign your assemblies, and you simply use buildnumbers
for bugfixes, you have to use policy files to be sure everything keeps
on working, OR Recompile everything else.
agreed.


policy files require an installer, while with fileversions you can
just drag/n/drop the dll into the gac and be done with it: for example
in the situation where you leave it to the user to store the dlls in
the GAC or keep them local to the application. So, for the users who
want the dlls in the gac (or need to, because of some issues with
fusion's loader, like Oracle's ODP.NET dlls can confuse the loader and
it suddenly forgets probing paths) they can simply add them to the gac,
and for the people who don't want to do that, they can simply avoid the
GAC altogether. After all, Microsoft themselves state that if you can
avoid the GAC you should.

Writing a simple program that invokes the GAC API is fairly trivial, and you
can install and remove assemblies from the GAC quite easily.

Versioning and compatibility is an extremely difficult problem. What .net
offers is not the end of the story, there's a lot more work that needs to be
done.
 
F

Frans Bouma [C# MVP]

David said:
same >> for both versions, the later one will over write the former.)

If this isn't dll hell then it's awfully close. What would you then
do if it turned out that the "bugfixed" version was buggy itself, but
with different bugs? You could not roll it back because the original
version was overwritten.

Agreed, but you take it out of context. My context was clearly
defined:
1) above all: keep the dlls locally to the application, so you have
xcopy deployment, which thus means avoid the GAC if possible.
2) if required, and if you really have to, copy the files to the GAC.

As microsoft states: the GAC should be avoided if possible.
This also creates a situation where different versions of the same
dll can exist without any way to tell them apart (well, any good
way). Relying on the timedate stamp or the VERSIONINFO block to tell
them apart it is not a good way to handle it either. Typically the
assembly version and the VERSIONINFO contain the same version number,
but the runtime does not evaluate the VERSIONINFO information for
binding purposes, so the app will bind to the copy of the file that
runtime evaluates first. A support person will have a hard time
distinguishing between the different versions of the same assembly,
and this really isn't a story I'd want to tell a customer ("yes I
know it 'says' its the same version, but trust me, it's a different
version...")

so, you're hereby claiming that what Microsoft is doing with their
service packs for .NET is bad practise? hmm.
Even if using publisher policy is ugly (I don't like it much myself)
it is still better then this.

strange, MS doesn't use that feature themselves, even if they can
perfectly do so.

The resemblance of DLL hell is not going away with a policy file btw.
There you too direct calls to one single dll, for all versions of the
range defined in the policy file. DLL hell is the phenomenon where you
install an app and it overwrites an existing dll with an OLDER version
(or different version) and existing applications which expect a newer
version (because the dll overwritten contains a COM object not defined
in the now existing dll). That can't happen here, as the GAC prevents
that. Unless you do a bad job versioning your interfaces of course (by
adding a lot of code and not increasing the assembly version).
Are you suggesting that an install program manually copy the new
"fixed" versions directly over the existing files in the GAC? whew...

No, I suggest that you should read better. I defined a context in
which I suggested a manually copy. Manual copy: you put the files in
the GAC. I also stated that the GAC should be avoided, because MS says
so themselves. IF possible, keep the files locally to the application.
This is really going to get even more complicated when 64 bit gacs
are in used, along with other variants of the gac, along with all the
distinctions in naming conventions used for the subdirectories. There
are already multiple system gacs installed on systems. Also, how will
this work on a system with both v1.1 and v2.0 installed? Which gac
will you overwrite?

Why would I care? The user puts the files in the gac
(c:\windows\assembly) and not something/one else. Keep the files
locally to the application, not in the GAC and you don't have this mess.
I think that bypassing the GAC install/uninstall APIs is not a good
way to go...

I think using the GAC in general is not a good way to go.
That's exactly the point. Even an update that contains only bugfixes
is still a new assembly that may destabilize applications that use
them. I've experienced far too many updates that did more damage then
they fixed to be willing to overwrite a previous version...I may need
it back again.

That's up to the developer and the software vendor. If a version has a
spec and the spec says "if you specify 'true' for that parameter, ABC
happens" and just AB happens, it's a bug. If the user of that version
RELIES on the fact AB happens and not ABC, who's fault is that? The
vendor can't withhold a bugfix so fixes it, and by kicking the version
number, the vendor REQUIRES a policy file.

Now, what will that do to 'xcopy deployment' ? You can't simply upload
a new assembly to the website's bin folder and be done with it, you
have to recompile everything, OR use a redirect in your own .config
file.

OR you have to use the GAC. Which Microsoft says you should avoid, and
you perhaps need to avoid because you don't have access to the gac
(shared hosting environments for example)
For assemblies in the GAC use publisher policy or recompile...this
does not seem to be any worse then your proposal, and I think it is
better in many respects. An even better solution is to avoid using
the GAC whevever possible.

the assembly file version doesn't require a recompile nor a policy
file. Just a new dll. With xcopy deployment, that's the most efficient
way to do it.

I agree with avoiding the GAC, which is also what MS states and what I
also said in my posting and which you apparently ignored.
I prefer to avoid using the system GAC. I wrote my own version of a
local GAC that is deployed with my app and is xcopy deployable; it's
mainly a mechanism to ensure that shared assemblies get loaded
correctly. It doesn't do all the things that the global GAC does, but
it does not need to. Updates will only affect that application.

so to solve it is to re-invent the wheel? I prefer spending time on
solving other problems than to re-solve problems which are already
solved.
I think the natural tendency will be to make the system GAC become a
dumping ground for assemblies that really ought to be private but are
public and global. There will be many reasons for this, some good and
some not so good. IMO, over time the GAC will become the same sort
of management nightmare that the registry turned into.

it already is, though often it's not a big problem: avoid it.

It also depends on your release policy of course. We have a release
often/release plenty policy because we don't want our customers to wait
3/4 months for a bugfix rollup. So if builds increase each time, you
have a bit of a problem with that policy. I'm not sure if you use a lot
of 3rd party gui controls, but it can be a real pain if controls are
updated regularly with different buildnumbers each time and vs.net
doesn't update the licenses.licx file etc.
Writing a simple program that invokes the GAC API is fairly trivial,
and you can install and remove assemblies from the GAC quite easily.

I don't want to store stuff in the gac, though I do provide signed
assemblies. We don't install our runtimes in the GAC because microsoft
states you should avoid the GAC. I also want to avoid that our
customers have to recompile their code or have to fiddle around with
assembly redirects when a new build is released, because it will affect
THEIR customers as well.

So, signed assembly, not using a GAC and you don't want to make your
customers' life a nightmare, what is YOUR solution to that problem?
(besides writing your own GAC system...)
Versioning and compatibility is an extremely difficult problem. What
.net offers is not the end of the story, there's a lot more work that
needs to be done.

Yes, but that's not solving today's problems.

FB

--
 
R

Richard Grimes

Frans said:
Agreed, but you take it out of context. My context was clearly
defined:
1) above all: keep the dlls locally to the application, so you have
xcopy deployment, which thus means avoid the GAC if possible.
2) if required, and if you really have to, copy the files to the GAC.

3) do not introduce DLL Hell. It will bite you in the butt in the
future.

Seriously, LoadLibrary would be a good way to share DLLs if people stuck
to the rules, COM was a great way to share code if people stuck to the
rules. But the problem is that people like you do not stick to the rules
and this produced DLL Hell. Fusion was created to try and make it easy
to stick to the rules even if you hadn't a clue what you were doing, but
now you have come up with a scheme to make it break. Shame on you.
so, you're hereby claiming that what Microsoft is doing with their
service packs for .NET is bad practise? hmm.

If you remember a few posts back, I said that Microsoft own the
operating system and they own the .NET framework. Yes, they are breaking
the rules, yes, what they are doing is bad practice. However, you will
not uninstall a hotfix on its own, if you are likely to uninstall a
hotfix it will be as part of uninstalling the entire framework. It works
in this specific case, but that does not mean that it is a good way to
solve the problem.
The resemblance of DLL hell is not going away with a policy file btw.
There you too direct calls to one single dll, for all versions of the
range defined in the policy file. DLL hell is the phenomenon where you

Hold on, in the rest of this paragraph you say that Fusion prevents the
problems of DLL, but in this first sentence you say that it does not
solve DLL Hell. You're not being consistent.
install an app and it overwrites an existing dll with an OLDER version
(or different version) and existing applications which expect a newer
version (because the dll overwritten contains a COM object not defined
in the now existing dll).

Yup, DLL Hell is nasty isn't it, wouldn't it be good to get rid of it?
That can't happen here, as the GAC prevents
that. Unless you do a bad job versioning your interfaces of course (by
adding a lot of code and not increasing the assembly version).

So you agree that Fusion prevents DLL Hell? You are right that a
publisher policy file could redirect to an incompatible version,
however, Microsoft specifically says that you should only use a
publisher policy file to redirect to a new version that has security
fixes. And if the policy file breaks the app then you can always roll
back to the previous version because the previous version is still in
the GAC. (And in 1.0, 1.1 there is even a wizard to help you do this.)
If a user follows your advice then the previous version would have been
overwritten. Microsoft says that any fixes other than important security
fixes require a rebuild. As I said earlier, if you follow the rules then
..NET will work well for everyone.
No, I suggest that you should read better. I defined a context in
which I suggested a manually copy. Manual copy: you put the files in
the GAC. I also stated that the GAC should be avoided, because MS says
so themselves. IF possible, keep the files locally to the application.

If the new version introduces a bug it means that you have no mechanism
to go back to the previous, working version. You *really* ought to think
this through.

Richard
 
F

Frans Bouma [C# MVP]

Richard said:
but >> with different bugs? You could not roll it back because the
original >> version was overwritten.

3) do not introduce DLL Hell. It will bite you in the butt in the
future.

Seriously, LoadLibrary would be a good way to share DLLs if people
stuck to the rules, COM was a great way to share code if people stuck
to the rules. But the problem is that people like you do not stick to
the rules and this produced DLL Hell. Fusion was created to try and
make it easy to stick to the rules even if you hadn't a clue what you
were doing, but now you have come up with a scheme to make it break.
Shame on you.

yeah yeah, it's very easy to say 'shame on you'. Which part of "store
the assemblies locally with the app" don't you understand?

I never said to use the GAC. If you don't use the GAC, your proposed
'solutions' are meaningless.
If you remember a few posts back, I said that Microsoft own the
operating system and they own the .NET framework. Yes, they are
breaking the rules, yes, what they are doing is bad practice.

So, what MS does is bad practise? Perhaps they do it for a reason
which YOU find irrelevant but others don't find that irrelevant.
However, you will not uninstall a hotfix on its own, if you are
likely to uninstall a hotfix it will be as part of uninstalling the
entire framework. It works in this specific case, but that does not
mean that it is a good way to solve the problem.

The key part here is 'installer'. I don't install stuff with an
installer in the GAC: I don't use the GAC nor use an installer for the
particular dlls, as they are supposed to be used locally with the app,
not stored in the GAC _unless the user has to_. (e.g. ODP.NET makes
fusion forget probing paths in some situations and the only way to
solve that is to use the gac unfortunately)
Yup, DLL Hell is nasty isn't it, wouldn't it be good to get rid of it?

Yes, that's why I said: store the dll locally with the app. How many
times do I have to repeat that?
So you agree that Fusion prevents DLL Hell? You are right that a
publisher policy file could redirect to an incompatible version,
however, Microsoft specifically says that you should only use a
publisher policy file to redirect to a new version that has security
fixes. And if the policy file breaks the app then you can always roll
back to the previous version because the previous version is still in
the GAC. (And in 1.0, 1.1 there is even a wizard to help you do
this.) If a user follows your advice then the previous version would
have been overwritten. Microsoft says that any fixes other than
important security fixes require a rebuild. As I said earlier, if you
follow the rules then .NET will work well for everyone.

yeah, great on paper, bad in practise.
A policy file is only for security fixes? Where is that stated?
A new version number in a signed assembly breaks every app used by
that version. So it REQUIRES recompiles and thus re-installations of
those applications: unless their .config file gets an assembly redirect
OR unless a policy file is installed in the gac AND the assembly is
added to the gac.

So this evolves in what Microsoft preaches as well: release fixes only
once a year or never at all. Because if you DO release fixes: a version
number is increased which causes a recompile of all the software that
has been written with that dll in mind, OR the application config file
of those software has to contain a redirect OR a policy file has to be
released.

You want an example? Take any 3rd party ADO.NET provider. Say they use
for every bugfix release a new version. Take any data-access library
which utilizes that 3rd party ADO.NET provider (and which is thus
referencing a given version). Now, NOTHING changes in that data-access
library, but that given 3rd party ADO.NET provider has a new bugfix
release, and the version number increases. Say no policy file is used,
because according to you, that's only for security fixes. So the
customers/users of that data-access library download that new ADO.NET
provider version.

*BOOM*. It doesn't work anymore. The data-access library has to be
recompiled against the new ADO.NET provider dll. OR the developer using
the data-access library has to add an assembly redirect to the .config
file of the application.

Though what happens if the data-access library vendor DOES recompile
against the new version of the ADO.NET provider assembly? All users of
that new version have to upgrade to the new ADO.NET provider assembly,
because the data-access library references that. What if that isn't
possible?

You think I make this up? You don't have to believe me, but this is
cold hard reality. That's the real world situation where you have to
rely on other assemblies which are installed in the GAC and using a
policy file.

So even if the data-access library isn't updated with ANY code,
recompiles are required, and thus new versions, simply because the
references to 3rd party assemblies are updated.

And now I hear you saying: "but why is that your problem, the
developer using the data-access library can simply add the assembly
redirect to the config file of his app?". I know, but not a lot of
other people out there know. And the sad part is that for libraries,
there's no .config file, so you have to explain that in documentation,
which is often overlooked.

Again, those are probably not your problems you ahve to deal with but
others do. In the clean-room situation you're sitting in, it might be
perfectly reasonable to do it otherwise and I agree with that. In
reality however, things are slightly different, especially for people
who happen to write software which is distributed in a library, not as
a .exe.

So, sorry I have to say it, but unless you have a clean, solid,
solution which solves this problem for all of us library vendors out
there, without putting the requirement on our customers/users to wade
through complex .config file modifications, I think you should think
twice before telling me "shame on you". Don't you think I've spend a
lot of time trying to solve this? Don't you think I'm the only one with
this problem?
If the new version introduces a bug it means that you have no
mechanism to go back to the previous, working version. You really
ought to think this through.

That's why the GAC should be avoided and libraries should be kept
locally. At the moment there's no clear solution without policy files
or redirects or even recompiles. And don't think this is just a minor
issue. You don't have to deal with customers asking for help because
your application suddenly doesn't work anymore because they've
installed an update of the ADO.NET provider for the database they use
and the vendor apparently messed up with the policy file or didn't
include a policy file at all.

FB

--
 
D

David Levine

Frans Bouma said:
Agreed, but you take it out of context. My context was clearly
defined:
1) above all: keep the dlls locally to the application, so you have
xcopy deployment, which thus means avoid the GAC if possible.
2) if required, and if you really have to, copy the files to the GAC.

My statement is completely within the context of your proposal, as your
restatement makes clear; you propose overwriting assemblies in the GAC when
you think it is warranted. It is correct to try to keep DLLs local to the
app, but you immediately follow that by stating that if required (and who
determines when that is, and what criteria do they use?) you will overwrite
DLLs in the GAC, and without even going through the GAC API.

It is my position that this is worse then not fixing the bug; at least then
you know what you are dealing with. If you overwrite assemblies in the GAC
then there is no easy way to determine which version of the assembly you are
dealing with; this would quickly turn into a support nightmare. You would
need to examine something other then the assembly's baked-in version number
to determine the "real" version of the assembly. This is something no one
with any .net experience would be expecting, it is arcane and not obvious,
and there is no guarantee that any method you used to mark the assemblies
(such as set the VERSIONINFO to a different value) would be handled
correctly, or even consistently, between multiple sub-versions of the
assembly version. Would the info in the VERSIONINFO field be correct and
different? Would we compare the file size or time-date stamps? Inspect it to
look at the mvid? A combination of all these?

There's nothing in your proposal that indicates this would be limited to a
single assembly; presumably you could have many assemblies that have been
updated in this manner. This creates a situation that becomes increasingly
difficult to support, because if a customer has a problem you may need to
duplicate their environment...how do you do that? The number of different,
untested combinations of assemblies will increase exponentially.

Automated tools would not be expecting this, so it would be difficult or
impossible to use management tools to help you manage these assemblies. For
example, I've written a small app that compares the contents of the GAC on
different machines and allows you to copy assemblies from one machine to
another; this would confuse it because it would think the assemblies were
identical when in fact they were different.

What would happen when that assembly had been processed by ngen.exe? Would
the system use the new version or the ngen'd version?

This will also affect applications that were using that assembly but which
did not experience a problem - you may now break apps that were working just
fine.

I really think you ought to reconsider your prosal.
As microsoft states: the GAC should be avoided if possible.

We are in complete agreement on this.
so, you're hereby claiming that what Microsoft is doing with their
service packs for .NET is bad practise? hmm.

There are vast differences between your proposal and a service pack. If you
update the entire GAC to a new, known-good configuration I would be less
opposed (still oppposed but not as much). One of the problems with your
proposal is that it is piecemeal...update an assembly here, try it out,
ooops that wasn't it, try another one, etc. When MSFT does a service pack
they update the entire operating system to that service pack level, and when
it is done all files are working with other files that they have been tested
with.

I made no claims about how good or bad previous practice has been; don't put
words in my mouth.
strange, MS doesn't use that feature themselves, even if they can
perfectly do so.

They update the entire runtime, not one assembly at a time. Just because
they have not already done so does not mean that they will never do so.
The resemblance of DLL hell is not going away with a policy file btw.
There you too direct calls to one single dll, for all versions of the
range defined in the policy file. DLL hell is the phenomenon where you
install an app and it overwrites an existing dll with an OLDER version
(or different version) and existing applications which expect a newer
version (because the dll overwritten contains a COM object not defined
in the now existing dll). That can't happen here, as the GAC prevents
that. Unless you do a bad job versioning your interfaces of course (by
adding a lot of code and not increasing the assembly version).

Agreed. Any code change at all should result in a new version number.
No, I suggest that you should read better. I defined a context in
which I suggested a manually copy. Manual copy: you put the files in
the GAC. I also stated that the GAC should be avoided, because MS says
so themselves. IF possible, keep the files locally to the application.

Seems to me like I read it just fine. You want it both ways; avoid the GAC
(which we agree on) but abuse it when it suits your purpose.
Why would I care? The user puts the files in the gac
(c:\windows\assembly) and not something/one else. Keep the files
locally to the application, not in the GAC and you don't have this mess.
You need to care; the point is that the user wont know which GAC to put the
files into. You can either not use the gac at all, or you can use it
correctly. You are trying to fix one problem but you are creating a far
worse problem in its place.

That's up to the developer and the software vendor. If a version has a
spec and the spec says "if you specify 'true' for that parameter, ABC
happens" and just AB happens, it's a bug. If the user of that version
RELIES on the fact AB happens and not ABC, who's fault is that? The
vendor can't withhold a bugfix so fixes it, and by kicking the version
number, the vendor REQUIRES a policy file.

This does not address my statement.
Now, what will that do to 'xcopy deployment' ? You can't simply upload
a new assembly to the website's bin folder and be done with it, you
have to recompile everything, OR use a redirect in your own .config
file.

I use xcopy deployment and if I needed to I could install an updated
assembly in the gac as well as a policy file. I don't use click-once, I
wrote my own.
OR you have to use the GAC. Which Microsoft says you should avoid, and
you perhaps need to avoid because you don't have access to the gac
(shared hosting environments for example)
I do have access to the gac, but I still avoid it because I think the gac is
more trouble then it is worth, not because I can't write code to access it.
the assembly file version doesn't require a recompile nor a policy
file. Just a new dll. With xcopy deployment, that's the most efficient
way to do it.

No it is not, it gets you right back in the mess we had before .net
versioning. Creating a different mess does not clean up the original mess.
I agree with avoiding the GAC, which is also what MS states and what I
also said in my posting and which you apparently ignored.

I did not ignore it, I resonded to your proposal about when you do use it.
so to solve it is to re-invent the wheel? I prefer spending time on
solving other problems than to re-solve problems which are already
solved.

No, I invented a mechanism that solved the problem I had to deal with and
for which MSFT did not provide a solution. It's called engineering.

Click-once works only with a limited set of applications, it does not solve
the general problem of installing applications. It also requires the 2.0
runtime.
It also depends on your release policy of course. We have a release
often/release plenty policy because we don't want our customers to wait
3/4 months for a bugfix rollup. So if builds increase each time, you
have a bit of a problem with that policy. I'm not sure if you use a lot
of 3rd party gui controls, but it can be a real pain if controls are
updated regularly with different buildnumbers each time and vs.net
doesn't update the licenses.licx file etc.

We do use 3rd party controls and libraries; I can't think of a serious
development effort that doesn't.
I don't want to store stuff in the gac, though I do provide signed
assemblies. We don't install our runtimes in the GAC because microsoft
states you should avoid the GAC. I also want to avoid that our
customers have to recompile their code or have to fiddle around with
assembly redirects when a new build is released, because it will affect
THEIR customers as well.

So, signed assembly, not using a GAC and you don't want to make your
customers' life a nightmare, what is YOUR solution to that problem?
(besides writing your own GAC system...)

I did write my own gac system (lgac)...we never install assemblies into the
gac. All our assemblies are signed.

For our assemblies we follow these rules:
1. If a type is shared then the assembly it is defined in must be in the
local gac (a common folder). If a type is not shared then one or more copies
of it can be placed into subdirectories as needed (e.g. a plugin's folder).
This also puts restrictions on these assemblies such that they must be
uniquely named so there is no confusion about it.
2. All assemblies that reference it will always be redirected to the current
version in the lgac; this allows them to share types within the
application's process space.
3. All shared assemblies ***must*** always be backwardly compatible with
previous versions.
4. The application controls which version of the assembly is in the lgac -
it cannot be a later version then the one the main application was compiled
against. If a plugin needs a later version then either the main application
must be updated or the plugin will not be used. If the application does not
use it, then the plugins can update the assembly.

These are some of the rules - there are others. These are restrictive and
will not work for all apps, but we were not trying to create a general
system, only one that suits our own purposes.


MSFT is good at creating a system that is good enough that people want to
use it, but which has warts, limitations, etc.,and the tools to manage it
are never good enough. This creates problems but it also creates
opportunities for 3rd parties to plug the gaps. Part of the problem is that
this is still a fairly new environment and we are still going through its
shakedown period, finding out what works and what doesn't, and what else is
needed.

Here are some ideas:
Create a gac management tool that allows you to explore the gac in great
detail, filter and sort it, etc., allows comparisons between gacs on
different machines, copy assemblies around, make the GAC's equal, etc. As I
mentioned, I wrote a simple crude app 1 or 2 years ago (it's in the got dot
net sample area) that does some of this.

There should be a way (a class, assembly, or application block) that allows
you to create a local gac, one that can be deployed along with an
application using xcopy deployment. I wrote the equivalent of one, but it is
non-trivial.

Other then system libraries (the BCL) assemblies should never (or rarely) be
shared. I don't care if it solves the deployment problems of component
vendors, the ruler of the software jungle should be the application, not the
component. The application should be able to control its own environment. If
all assemblies are local then only that app will be affected by changes to
the assemblies it is using. Hard disk space due to duplicated assemblies is
not a valid issue - if you have to ask, get a bigger hard drive.

Never (or rarely) update assemblies piecemeal; it should be all or none, so
that when the update is done the system has a collection of assemblies that
have been tested against each other. In essence, all updates should be the
equivalent of a service pack.

A lot more theoretical work needs to be done on the versioning problem
space. There probably needs to be distinctions made between types of
assembles and how they are used. It short, a taxonomy of software; you can't
figure out how to deal with it unless you know what the hierarchal
relationship is. The control and deployment mechanisms need to be different
based on their differing requirements. Currently all .net assemblies are
treated equally, and that is part of the problem.

This leads directly to addressing the issues of compatiblity, both forward
and backward. Versioning is the mechanism by which we attempt to control
this. A lot more work needs to be done in this area as well.

These are extremently difficult problems to solve, especially given the wide
variance in requirements between component vendors, application developers,
users, support personnel, etc.

Dave
 
R

Richard Grimes

Frans said:
yeah yeah, it's very easy to say 'shame on you'. Which part of "store
the assemblies locally with the app" don't you understand?

No, throughout this discussion I have been referring to your suggestion
of overwriting a GAC version with another version that has the same .NET
name but different VERSIONINFO. Yes, using private assemblies is the
best situation in most cases, I never said anything against that. Of
course anyone reading the archives will see that.
I never said to use the GAC. If you don't use the GAC, your proposed
'solutions' are meaningless.

No. We were talking about you're incorrect, and dangerous 'solution' to
the original poster's problem. Don't try to change the subject.
So, what MS does is bad practise? Perhaps they do it for a reason
which YOU find irrelevant but others don't find that irrelevant.

<sheesh> you do find it difficult to grasp a concept, don't you? Just
read through the posts in this thread and you'll find I have been
consistent. You've been wandering around aimlessly.
The key part here is 'installer'. I don't install stuff with an
installer in the GAC: I don't use the GAC nor use an installer for the

Gosh, you've got a huge ego haven't you? I have been consistent in
talking about the OP's problem and correcting your reply. Frankly I
don't really care what *you* do. (Judging by your arguments, I would not
have too much confidence in your code anyway.)
Yes, that's why I said: store the dll locally with the app. How many
times do I have to repeat that?

Go on, you enjoy it don't you? Repeat it again, just for me. I love the
way that you say it said:
yeah, great on paper, bad in practise.
A policy file is only for security fixes? Where is that stated?

It's generally known. But for your benefit, here's something from Alan
Shi:

http://blogs.msdn.com/alanshi/archive/2004/03/28/100765.aspx
A new version number in a signed assembly breaks every app used by
that version. So it REQUIRES recompiles and thus re-installations of
those applications: unless their .config file gets an assembly
redirect OR unless a policy file is installed in the gac AND the
assembly is added to the gac.

Yup. That's right. See Alan's blog entry.
So this evolves in what Microsoft preaches as well: release fixes only
once a year or never at all. Because if you DO release fixes: a
version number is increased which causes a recompile of all the
software that has been written with that dll in mind, OR the
application config file of those software has to contain a redirect
OR a policy file has to be released.

Yup. You're learning.
release, and the version number increases. Say no policy file is used,
because according to you, that's only for security fixes. So the

No, according to Microsoft, as stated by Alan Shi.
through complex .config file modifications, I think you should think
twice before telling me "shame on you". Don't you think I've spend a
lot of time trying to solve this? Don't you think I'm the only one
with this problem?

No. Your problem was suggesting a hack that would bring back DLL Hell.

Richard
 
F

Frans Bouma [C# MVP]

Richard said:
No. We were talking about you're incorrect, and dangerous 'solution'
to the original poster's problem. Don't try to change the subject.

But my solution is one to solve a real world problem, which you cut
away in your reply and you didn't address it at all. THATs the issue.
There is a real world problem, but all you keep on doing is running in
circles with the same sentences. I _KNOW_ what's best in theory, yet it
won't help with the real world problem you ignored completely.
<sheesh> you do find it difficult to grasp a concept, don't you? Just
read through the posts in this thread and you'll find I have been
consistent. You've been wandering around aimlessly.

huh? I just say something can be not so irrelevant for others as it is
for you, as in: a real world problem to which assemblyfileversion is
'a' solution but if you simply IGNORE the problem, then yes, it seems
irrelevant.
Gosh, you've got a huge ego haven't you? I have been consistent in
talking about the OP's problem and correcting your reply. Frankly I
don't really care what you do. (Judging by your arguments, I would
not have too much confidence in your code anyway.)

Sure Richard, personal attacks really help you in your arguments. So
this is your argument? "Shame on you", my code sucks etc. ? Isn't that
a little childish? And who's having a big ego here?
Go on, you enjoy it don't you? Repeat it again, just for me. I love
the way that you say it <g>. Pratt.

I'm not a native english speaker so what 'pratt' means I don't know
but I guess it's not a compliment. Again a personal attack.

What you apparently fail to understand is that the TS hinted at a real
world problem I described again in an example and which you ignore
completely. Pointing to the theory doesn't help, I know the theory
behind singed assemblies and what not but others out there don't. So
relying on them to have that knowledge is not helping because they'll
come to the vendors of the libraries which rely on THEM to have the
knowledge to find out assembly redirects in their own code.

You can keep on insulting ME till you see blue in the face, Richard,
fact is that whatever you have proposed here doesn't solve the problem
I described.

Which is sad, because no-one is helped by insulting others, but by
using solutions for problems at hand. So, what will it be, Richard,
what's the solution to the 3-assembly chain versioning problem?
It's generally known. But for your benefit, here's something from
Alan Shi:

http://blogs.msdn.com/alanshi/archive/2004/03/28/100765.aspx

ah, a 1.5 year old blogpost. Of course! essential part of the
reference documentation!

You really expect people to wade through all the msdn.com blogs for
info not in the docs? And besides that, you thus hereby declare that
for example Oracle and IBM use policy files completely for the wrong
reasons?

Well, I can tell you, Richard, because they DO use policy files, a LOT
of developers don't have to deal with problems caused by an increased
version number on the ado.net provider assemblies when a bugfix was
released by either of the two.

Oracle even redirects 9.2.x.x to 10.1.x.x, because it's just one code
base.

But, following your reasoning, Oracle shouldn't do this. They
shouldn't release policy files for their ODP.NET assemblies. So, when
they released 9.2.0.401 and people compiled against that version, those
developers should be stuck with that version and when 9.2.0.701 came
out, all those developers should simply go back to their vs.net and
recompile every code they have because of the version increase of
ODP.NET with essential bugfixes?

Oh no, wait! they should go into reflector, find out the public
keytoken from the Oracle.DataAccess.dll and construct an assembly
redirect in their own *.config files!

And if they happen to write assemblies which are used by yet other
people, they are just out of luck and their problems are simply not
existing!

There's a better solution however, Richard. It's that Fusion is
slightly changed. Now a version is 4 different elements (a.b.c.d),
which effectively don't have a separate meaning: change one and the
version changes, even if it's the least significant element.

What if fusion simply would load the version with the highest 'd' ? If
you as an assembly writer require references to the assembly to be
recompiled, you can, by simply changing 'c' to a higher value (or b or
a). 'd' is for bugfixes. If the GAC then would see them still as
different versions, you could install them in the GAC as separate
versions, so you can roll back, and fusion simply loads the highest
version, so no recompiles required, no policy files required and no
config file crap required.

Oh, and no assemblyfileversion required. That would solve the
middle-man assembly writer's problem (A<--B<--C. A gets a new version
nr. Without a policy file, B fails to load. C therefore has to have a
config file assembly redirect, or B has to be recompiled. Though if A
and B are from different vendors, C is in trouble. )
No. Your problem was suggesting a hack that would bring back DLL Hell.

a hack, using an attribute which is precisely there for the purpose it
is used for, used in exactly the same context as Microsoft uses it for.

As you cleverly cut away the problem example I gave, I don't expect an
answer for that problem from you, although I did expect you could gave
me and others reading this thread one.

That's the sad part of this thread: you end up personally insulting
me, while at the same time not addressing a problem that's there. In
fact, by stating policy files are only to be used for security fixes,
the problem only gets worse. Truly helpful, Richard, truly helpful.

FB

--
 
R

Richard Grimes

Frans said:
But my solution is one to solve a real world problem, which you cut
away in your reply and you didn't address it at all. THATs the issue.

One that is wrong and bad.
There is a real world problem, but all you keep on doing is running in
circles with the same sentences. I _KNOW_ what's best in theory, yet
it won't help with the real world problem you ignored completely.

The OP should recompile, period. Your 'solution' is bad and will cause
problems.
Sure Richard, personal attacks really help you in your arguments. So
this is your argument? "Shame on you", my code sucks etc. ? Isn't that
a little childish? And who's having a big ego here?

Well, at least I know that I am not 'advising' someone to do something
that is bad and will break.
You can keep on insulting ME till you see blue in the face, Richard,
fact is that whatever you have proposed here doesn't solve the problem
I described.

No. I said the OP has no choice but to recompile. Your 'solution' is bad
and will break.
ah, a 1.5 year old blogpost. Of course! essential part of the
reference documentation!

Oh come on, it is just as relevant now as it was then. How old do you
think the documentation is at msdn.microsoft.com/library?
You really expect people to wade through all the msdn.com blogs for
info not in the docs? And besides that, you thus hereby declare that
for example Oracle and IBM use policy files completely for the wrong
reasons?

Now you are straying from the point again. I never mentioned Oracle, not
IBM. Nor did I say that people should wade through MSDN blogs.
a hack, using an attribute which is precisely there for the purpose it
is used for, used in exactly the same context as Microsoft uses it
for.

No. VERSIONINFO is for unmanaged files, the strong name is for managed
files. Yes, a managed file is a PE file and can have unmanaged
resources, but as far as .NET ignores the unmanaged VERSIONINFO
resource. That makes sense because the two resources have equivalent
items and so you will get problems if the two get out of sync.

Keep unmanaged resources in the unmanaged world, and managed resources
in the managed world.
That's the sad part of this thread: you end up personally insulting
me, while at the same time not addressing a problem that's there. In
fact, by stating policy files are only to be used for security fixes,
the problem only gets worse. Truly helpful, Richard, truly helpful.

I do not want to get off topic, if you want to talk about another topic
then start a new thread.

Richard
 
F

Frans Bouma [C# MVP]

Richard said:
The OP should recompile, period. Your 'solution' is bad and will
cause problems.

Ok, let's get one thing straight first: I don't *like* the 'solution'
I proposed any more than you do. However there's a problem and if
you're confronted with that problem (and doing a search on
assemblyfileversion or assembly versioning on google reveals I'm
definitely not alone) you want to solve it.

I'll briefly describe it here and I hope you then understand that 'you
should recompile' isn't an option.

Library A, which is signed. A is referenced by library B, also signed.
A and B are from different vendors. Application C is written by
referencing B. All are version 1.0.0.0.

The developer of C discovers that B behaves weird. This developer
contacts the developer of B and explains the behavior. It turns out the
bug is in A. The developer of A is contacted and A is updated to
v1.0.0.1.

Ok, now your proposed situation: no policy files. The developer of C
installs A v1.0.0.1. Nothing works anymore, because B can't load A
v1.0.0.1. B has to be updated as well to refer to this new reference
version. So B is recompiled as well to v1.0.0.1.

Now the developer of C recompiles his application with the new B and
it now works again.

Though, B is updated. The latest build of B is now 1.0.0.1. Perhaps
the vendor of B has thousands of customers. This opens up a big problem:
B v1.0.0.0 works with A v1.0.0.0
B v1.0.0.1 works with A v1.0.0.1

B perhaps uses other 3rd party libraries as well. This increases this
list.

Ok, the vendor of B is of course not perfect and discovers a bug in B
as well. This is fixed. B v1.0.0.2 is released.

Which version of A does B v1.0.0.2 reference?
Pretty unclear from the position of the developer of C.

Ok, now WITH policy files.
A gets a policy file, because it is always installed in the GAC. Due
to the bugfix, v1.0.0.1 is released and a new policy file which
redirects 1.0.0.0 references to 1.0.0.1.

No B recompilation has to be performed, as installing the bugfix
version of A (v1.0.0.1) is enough to fix the problem for C. C also
doesn't have to be recompiled, as C references the same B. This is
fortunate for the developer of C, because C is distributed to thousands
of customers and they can now simply update a KB article and refer to
the update of A.

As stated above, B also contains a bug and gets a bugfix. But because
B isn't installed in the GAC, it doesn't have a policy file as well.
Furthermore, because it's a library, it doesn't have a .config file as
well with accompanying assembly redirects.

So let's follow your policy again: no assemblyfileversion. B gets
version 1.0.0.1. The developer of C runs into the bug in B so the
developer of B has to use the new B. He copies the new B into the C's
bin folder and C fails to start... it can't load the assembly. The
developer of C scratches his head and asks B what's wrong? B's
developer tells the developer of C to put an assembly redirect in the
config file of C. This is new stuff for the developer of C so he needs
some guidance. As B has thousands of customers, this will give a lot of
problems for the support department of B, even with a KB article and
proper documentation.

What if B did use a file version? B then got a new assemblyfileversion
but kept its assembly version. C simply kept on running without a
problem. The developer of C doesn't have to recompile.

Now, I'm in the position of B. And with me a lot of other people. In
2003 we were confronted with the problem in the context of the first
example, namely we did use strong names and increasing build versions.
This became a maintenance nightmare for customers and ourselves because
which version references what exactly? This becomes complex when you
reference multiple 3rd party assemblies as we do. (3 oracle, 1 ibm, 1
corelab mysql, 1 firebird)

We first tried to tell our customers indeed, to recompile or to use an
assembly redirect. Now, the idea is of course OK in theory, but in
practise this doesn't work for several reasons, one being that people
simply don't read docs/KB's. Another reason is that it's
counter-intuitive: an application developer wants to just deal with the
problems writing the application, not with versioning problems inside a
3rd party dll used in the application.

The problems were gone since we kept our signed assembly version to a
static version per 'major version' (like 1.0.2005.1) and increase the
file version with each build.

It has disadvantages too, like click-once-esk technology doesn't work
and indeed, if you want to store the assembly in the gac (that's 'if',
not 'when') you can't have multiple versions inside the GAC. Though
because the GAC should be avoided anyway, the problems are really minor
compared to the problems with the alternative.

Now, you can say "you have to recompile", but that's easy from a
position where you don't have to deal with this problem. If you look at
the problem description above, you'll understand why Microsoft also
doesn't increase the version number with a hotfix. This is also how I
found out that assemblyfileversion was an option for dealing with the
problem, because I wondered how MS could update .net assemblies without
breaking compiled applications, which was exactly what we wanted to do
as well.

In the real world, if you're not writing the end application, you
can't simply state: "recompile". Well, you can, but it's likely that it
isn't an option for the person you're telling it to.

That's also why this whole strict assembly loading system is flawed to
the bone. In theory I fully agree with you and if I had a chance, I
definitely would do it differently, but I can't and with me a lot of
other people who write libraries which are effectively 'in the middle'.
If you always use an installer and always install your 'B' in the GAC,
you can use a policy file and be done with it. If you're not doing
that, you're effectively 'screwed'. As I said in my previous post: it
would be better if fusion would load the 'latest' build of a major
version. Major version being a.b.c and build being 'd' in a.b.c.d. Now
b and c and also d have semantical meaning but technically no meaning.
Well, at least I know that I am not 'advising' someone to do
something that is bad and will break.

Please read the problem description above and then re-state what
you're proposing isn't 'breaking' anything.
No. I said the OP has no choice but to recompile. Your 'solution' is
bad and will break.

my solution will keep applications up and running when a bugfix or
non-breaking change is made to 'B'. And the developer of B has always
the choice of issuing a new version if required (which then does
require a recompile).
Oh come on, it is just as relevant now as it was then. How old do you
think the documentation is at msdn.microsoft.com/library?

That's not the point. In general, people go to the msdn lib on their
HDD and check what's said in there. If some blogpost somewhere on the
web claims another thing than what's in the MSDN library on most dev's
HDDs, that's great, but IMHO not something you should consider
'essential material'.
Now you are straying from the point again. I never mentioned Oracle,
not IBM. Nor did I say that people should wade through MSDN blogs.

I mentioned them because they use policy files to solve the same
problem, i.e.: an example of how policy files for BUGFIX redirections
simply work IF the assembly is always (!) in the GAC. If they don't use
policy files, it would be a big problem for a lot of developers.
No. VERSIONINFO is for unmanaged files, the strong name is for
managed files. Yes, a managed file is a PE file and can have
unmanaged resources, but as far as .NET ignores the unmanaged
VERSIONINFO resource. That makes sense because the two resources have
equivalent items and so you will get problems if the two get out of
sync.

not entirely true: if you copy an assembly to the GAC and the assembly
you're trying to copy has a lower fileversion, it's not overwriting an
existing assembly with the same assemblyversion. Though if it has a
higher file version it IS overwriting the assembly in the GAC. So IMHO
that means the assemblyfileversion IS used by the GAC and IMHO thus by
..NET. NO, of course not by fusion.
Keep unmanaged resources in the unmanaged world, and managed
resources in the managed world.

I wished I could solve it differently. Though because MS uses the
exact same mechanism, something tells me the only way out of this mess
is sadly enough through assemblyfileversion, for the time being. I saw
in vs.net 2005 yesterday that there's a property for a reference so you
can state if it's an exact reference or not. As I couldn't find ANY
documentation on it I don't know what it does exactly. I hope it does
what I think it does, but as documentation is lacking, I don't know.

This whole problem is a truly sad part of the versioning system in
..NET. IMHO the designers of the system haven't thought long enough to
address this problem as well, but have simply assumed that it either
won't happen or that everyone would keep track of a myriad of version
dependencies in assembly redirects, either in .NET config settings set
by a sysadmin or in a .config file (as policy files are apparently also
off limits according to MS).

I get the feeling you think too light about this problem and what the
consequences are of 'recompiling', especially if you're B in an A<-B<-C
chain. But I disgress. Too much time wasted on this already, and this
discussion isn't going to solve it also.

FB

--
 

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