Если взглянуть на вопрос в ключе потенциальных повышений нагрузки и расширения функционала - то один порт, на одном хосте окажутся узким местом. Так что можно смотреть и шире - сервисы расползутся по разным хостам и т.п. Или не смотреть на это.
Там собственно все прозрачно
есть секция [UninstallDelete]
где описываются файлы/директории для удаления - которые деинсталлятор удалит
(там же призывают к аккуратности в плане *.* и т.п. - дабы случайно установленная в c:\ установка при деинсталляции не попыталась удалить все с c:\ ))
p.s.
ну и рядом [UninstallRun]
где в общем-то что-то запустить при удалении
притом помимо taskkil и sc stop service / sc delete service
можно даже запустить какой-нибудь предварительно написанный или готовый "зачищатель"
Ну в обобщенном случае, если постучаться с компьютера за NAT в адрес xx.xx.xx.xx, то совсем не исключено что ответные стуки от строго того самого xx.xx.xx.xx могут быть донесены NAT до компа.
Но не для всех NAT и не всегда...
Ну можно создать отдельный домен приложения и грузить туда сборки через Assembly.LoadFrom
+ пригодится подвесить на событие CurrentAppDomain.AssemblyResolve свой обработчик, который будет подсовывать нужное
Вопрос только - зачем это надо для фрейвочных сборок? Попытаться запустить программу без установленного фреймворка?)