Isso pode ser devido a como o .NET localiza assemblies, documentados aqui:
Como o .NET Runtime localiza Assemblies
link
Observe o seguinte:
"O compilador registra referências estáticas nos metadados do manifesto do assembly no momento da compilação. As referências dinâmicas são construídas dinamicamente como resultado da chamada de vários métodos, como System.Reflection.Assembly.Load."
Se sua referência é estática, você pode examinar os metadados do assembly em execução para o manifesto. O manifesto pode ser examinado usando o ILDASM ou alguma outra ferramenta como o ILSpy. Se for dinâmico, o processo de localização é complexo e sofisticado.
Minha experiência tem sido que, se existem várias versões do CLR (por exemplo, 2.0 e 4.0), o resultado pode ser inesperado. Existem vários fatores adicionais, como:
- configuração da máquina e configuração da aplicação;
- se o aplicativo é todo código gerenciado ou possui algum código não gerenciado (COM / Interop);
- se a montagem de execução / chamada e assemblies chamados forem independentes de plataforma ("qualquer cpu") ou específica de plataforma (x86 ou x64).
Também é possível executar o código CLR 2.0 e 4.0 em um processo ao mesmo tempo (execução lado-a-lado).
Eu acho que isso deve ser reproduzível em um ambiente de desenvolvimento, e não é realista esperar que o consumidor saiba ou lide com todos os cenários possíveis.
Execução lado-a-lado no processo .NET
link
Assemblies: localização, vinculação e implantação do link
Quando você executa o Process Explorer do Microsoft SysInternals, seleciona o processo do serviço e a guia .NET Assemblies, ele deve mostrar todos os vários assemblies carregados para que você possa validar se o arquivo correto está carregado: