Создание уникального временного каталога из чистого C в окнах

Я хотел бы создать уникальный временный каталог в Windows с некоторого C код (не С++ или С#). Я хочу сделать это, чтобы я мог поместить некоторый темп файлы в каталоге, а затем удалять их все легко, когда я закончил (путем рекурсивного удаления каталога).

Я по сути ищу эквивалент linux mkdtemp функция. Здесь есть ответ С# и ответы на this вопрос предложите использовать Boost. Но поскольку я использую C, эти решения не работают для меня.

Лучшее, что я смог придумать, - это использовать GetTempFileName затем CreateDirectory, но проблема в том, что если я спрошу GetTempFileName для создания уникального имени файла, он также создаст файл (который я не хочу, так как я хочу сделать каталог вместо этого).

Кроме того, есть GetTempPath, который возвращает местоположение временной папки пользователя из среды переменные - но поскольку я хочу создать свой собственный каталог, который я могу безопасно удалить позже, мне все равно нужно создать каталог внутри любого путь, который он вернет.

Похоже, если я хочу создать уникальный каталог, мне придется создать временный файл, получить имя, удалить его, а затем создать каталог с тем же именем, что звучит очень грязно. Любые другие идеи?

Ответ 1

Вы можете использовать то, что GetTempPath возвращает конкатенацию с помощью Guid для обеспечения уникальности каталога. Вы можете создать Guid, используя UuidCreate или Функция CoCreateGuid.

Чтобы удалить рекурсивно каталог, здесь есть пример в чистом C: Как рекурсивно удалить каталог? на основе FindFirstFile, FindNextFile, DeleteFile и RemoveDirectory.

Существует также SHFileOperation, но он больше тяжеловес и основан на функциях Windows Shell, а DLL файлы Shell не всегда нужны, особенно если вы пишете код сервера.

Ответ 2

Используйте GetTempPath, затем CreateDirectory со случайным именем под ним, при необходимости повторите попытку, если CreateDirectory завершится сбой из-за того, что он уже существует. Но если ваше имя генерации достаточно хорошее, вероятность столкновения с существующим именем намного меньше, чем вероятность того, что blackhat угадывает ваш пароль или даже ваш секретный ключ, поэтому вы можете также игнорировать его.

Ответ 3

Используйте _tempnam tmpnam_s, чтобы создать имя файла, которое еще не существует, а затем используйте CreateDirectory для создания каталога. Там технически условие гонки, если вы это сделаете, в этом другом процессе потенциально может создать файл или каталог с таким именем в промежутке между тем, когда вы создаете имя файла и когда вы создаете каталог, но вероятность этого маловероятна. Чтобы защитить от этого, вы можете зацикливаться до тех пор, пока не добьетесь успеха.

Для рекурсивного удаления дерева каталогов вы можете использовать SHFileOperation. Кроме того, вы можете сделать обход каталога FindFirstFile/FindNextFile, DeleteFile и RemoveDirectory.

Если вы хотите удалить каталог автоматически после выхода, зарегистрируйте функцию, используя atexit. Это будет работать только для нормального завершения программы (т.е. Через функцию exit или путем возврата из main/WinMain). Это не будет работать для ненормального завершения программы (например, через abort, нарушение прав доступа, другое лицо, вызывающее TerminateProcess и т.д.).