@Chris. Yo también estaba obsesionado con el riesgo remoto de que un directorio temporal ya pudiera existir. Las discusiones sobre aleatorio y criptográficamente fuerte tampoco me satisfacen por completo.
Mi enfoque se basa en el hecho fundamental de que el O / S no debe permitir 2 llamadas para crear un archivo para que ambos tengan éxito. Es un poco sorprendente que los diseñadores de .NET opten por ocultar la funcionalidad de la API Win32 para los directorios, lo que lo hace mucho más fácil, ya que devuelve un error cuando intenta crear un directorio por segunda vez. Esto es lo que uso:
[DllImport(@"kernel32.dll", EntryPoint = "CreateDirectory", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CreateDirectoryApi
([MarshalAs(UnmanagedType.LPTStr)] string lpPathName, IntPtr lpSecurityAttributes);
/// <summary>
/// Creates the directory if it does not exist.
/// </summary>
/// <param name="directoryPath">The directory path.</param>
/// <returns>Returns false if directory already exists. Exceptions for any other errors</returns>
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
internal static bool CreateDirectoryIfItDoesNotExist([NotNull] string directoryPath)
{
if (directoryPath == null) throw new ArgumentNullException("directoryPath");
// First ensure parent exists, since the WIN Api does not
CreateParentFolder(directoryPath);
if (!CreateDirectoryApi(directoryPath, lpSecurityAttributes: IntPtr.Zero))
{
Win32Exception lastException = new Win32Exception();
const int ERROR_ALREADY_EXISTS = 183;
if (lastException.NativeErrorCode == ERROR_ALREADY_EXISTS) return false;
throw new System.IO.IOException(
"An exception occurred while creating directory'" + directoryPath + "'".NewLine() + lastException);
}
return true;
}
Puede decidir si el "costo / riesgo" del código de p / invoke no administrado lo vale. La mayoría diría que no, pero al menos ahora tienes una opción.
CreateParentFolder () se deja como un ejercicio para el alumno. Yo uso Directory.CreateDirectory (). Tenga cuidado al obtener el padre de un directorio, ya que es nulo cuando está en la raíz.