Единственный способ, которым я когда-либо справлялся с чем-то подобным, - это иметь DLL в отдельном домене приложений для сборки, которая пытается удалить ее. Я выгружаю другой AppDomain и затем удаляю DLL с диска.
Если вы ищете способ выполнить обновление, я бы предпочел заглушку exe, которая порождает настоящий AppDomain. Затем, когда этот stub exe обнаруживает, что должно быть применено обновление, он закрывает другой домен приложения и затем выполняет магию обновления.
РЕДАКТИРОВАТЬ: средство обновления не может делить DLL с тем, что оно обновляет, в противном случае оно заблокирует эти DLL и, следовательно, предотвратит их удаление. Я подозреваю, что именно поэтому вы все еще получаете исключение. Средство обновления должно быть автономным и не зависеть ни от чего, что использует другой домен приложений, и наоборот.