Description of the issue
There was a change made in the MSI-based installers for the .NET Framework 2.0 SP2 and 3.0 SP2 that causes the default repair that happens when you use the Add/Remove Programs entry for these products to not actually repair anything.  For example, if you end up with an out-of-date version of c:\windows\system32\mscoree.dll or if any of the files or registry values in the .NET Framework 2.0 SP2 or 3.0 SP2 are missing entirely, the repair from Add/Remove Programs will not restore the files or registry keys.
Because this issue only affects the MSI-based installers for 2.0 SP2 and 3.0 SP2, you will only encounter this issue on Windows XP and Windows Server 2003.  On Windows Vista and Windows Server 2008, the .NET Framework 2.0 SP2 and 3.0 SP2 are installed as OS update packages instead of as MSIs.
How to work around the issue
If you need to repair the MSI-based version of the .NET Framework 2.0 SP2 or 3.0 SP2 on Windows XP or Windows Server 2003, you must run the following command lines instead of using the repair option from Add/Remove Programs:
.NET Framework 2.0 SP2 - silent repair
msiexec /fpecmsu {C09FB3CD-3D0C-3F2D-899A-6A1D67F2073F} REINSTALL=ALL /l*v %temp%\netfx20sp2_repair_log.txt /qb
.NET Framework 3.0 SP2 - silent repair
msiexec /fpecmsu {A3051CD0-2F64-3813-A88D-B8DCCDE8F8C7} REINSTALL=ALL /l*v %temp%\netfx30sp2_repair_log.txt /qb
Behind-the-scenes details if you are interested
There is a difference in the command line switches being passed in to trigger the repair of 2.0 SP2 and 3.0 SP2 compared to 2.0 SP1 and 3.0 SP1.  Here are a couple of specific examples:
.NET Framework 2.0 SP2 - silent repair
msiexec /fpecmsu {C09FB3CD-3D0C-3F2D-899A-6A1D67F2073F} REINSTALL=ALL /l*v %temp%\netfx20sp2_repair_log.txt /qn
.NET Framework 2.0 SP1 - silent repair
msiexec /i {B508B3F1-A24A-32C0-B310-85786919EF28} /l*v %temp%\netfx20sp1_repair_log.txt /qn
The reason that these command lines need to be different (aside from the product codes changing between SP1 and SP2) is that the REINSTALL=ALL property no longer gets set by default in the MSI-based .NET Framework 2.0 SP2 or 3.0 SP2 repair processes.  There is a custom action in .NET Framework 2.0 SP1, 2.0 SP2, 3.0 SP1 and 3.0 SP2 setup that sets the REINSTALL=ALL property during repair scenarios.  However, the condition for that custom action was changed in 2.0 SP2 and 3.0 SP2 setup such that it will never evaluate to true, and the REINSTALL=ALL property no longer gets automatically set.  As a result, you have to manually pass in the REINSTALL=ALL property in order to perform a full repair of the .NET Framework 2.0 SP2 and 3.0 SP2.