По своей конструкции ClickOnce не позволяет выполнять произвольные шаги во время установки. Но при наличии необходимых разрешений нет никаких ограничений на то, что приложение ClickOnce может делать при первом запуске.
Наиболее распространенным решением является проверка при запуске приложения, чтобы увидеть, был ли распакован большой zip-файл, а если нет, то распаковывает PDF-файлы в каталог. Это можно сделать с помощью SharpZipLib или любым другим способом.
Альтернативное решение - использовать исполняемый файл не-ClickOnce, который разархивирует файлы, а также выполняет установку ClickOnce.
См. в этой статье для объяснения того, почему ClickOnce не позволяет настраивать пользовательские этапы установки, а также некоторые подробности о том, как обойти это.
Если вы согласны с тем, что PDF-файлы находятся в каталоге приложения ClickOnce, третий вариант - просто включить их в само развертывание ClickOnce. Недостатком этого является то, что вы теряете сжатие (за исключением того, что сервер может сжимать файлы, если вы развертываете по HTTP).
Если ваше приложение использует файлы PDF для внутреннего использования, другое решение - включить большой файл .zip в манифест, разархивируя отдельные файлы PDF в тот момент, когда они необходимы. Например, их можно разархивировать с помощью SharpZipLib и выписать с помощью File.WriteAllBytes(Path.GetTempFileName() + ".pdf", ...)
или загрузить непосредственно в любой компонент, который их использует. Если вы пишете во временный каталог, вам понадобится механизм для очистки файлов, которые вы больше не используете.
Любое из этих двух последних решений будет более чистым, чем копирование PDF-файлов по фиксированному пути, поскольку приложение ClickOnce будет автономным и будет полностью удалено.