.NET Framework 4.7.2
Ese fue un tema muy sorprendente...
Tengo esta rutina para obtener todas las plantillas de Inventor disponibles del disco local, sin importar la versión que sea:
private static IEnumerable<string> GetInventorTemplates_FAILS() { var publicPath = Environment.GetEnvironmentVariable("PUBLIC"); var autodeskPath = Path.Combine(publicPath, "Documents", "Autodesk"); var inventorPaths = Directory.GetDirectories(autodeskPath, "*Inventor*"); var templatePaths = inventorPaths.Select(path => Path.Combine(path, "Templates")); var templates = templatePaths.Where(Directory.Exists).SelectMany(path => Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)); // throws error ^^^^^^^^^^^^^^^^ return templates; }
Si ejecuto este código, obtengo este error:
System.Linq.SystemCore_EnumerableDebugView`1[System.String].get_Items() calls into native method Microsoft.Win32.Win32Native.GetFullPathName(char*, int, char*, System.IntPtr). Evaluation of native methods in this context is not supported.
Lo que lo vuelve más loco es si reescribo el código, para llamar manualmente a Directory.Exists
y funciona.
private static IEnumerable<string> GetInventorTemplates_WORKS() { var publicPath = Environment.GetEnvironmentVariable("PUBLIC"); var autodeskPath = Path.Combine(publicPath, "Documents", "Autodesk"); var inventorPaths = Directory.GetDirectories(autodeskPath, "*Inventor*"); var templatePaths = inventorPaths.Select(path => Path.Combine(path, "Templates")); foreach (var path in templatePaths) if (Directory.Exists(path)) // <- no exception!!! foreach (var template in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)) yield return template; }
Obtendrá el mismo resultado si solo verifica a través de QuickWatch :
Por ahora puedo usar la versión reescrita, pero tenía mucha curiosidad si soy el afortunado... :-)
Eso no es un problema de .NET. El código funcionará bien, no tienes que cambiar nada. El depurador dice que no puede ejecutar la consulta de forma segura en la ventana de observación, por lo que no puede mostrar ningún resultado. El error explica que
No se admite la evaluación de métodos nativos en este contexto.
template
no es una lista de documentos, es una consulta que aún no se ha ejecutado. El depurador tendría que ejecutar esa consulta para recuperar y los resultados.
Esto no es un problema ni poco común. Hay varios casos en los que el depurador no puede ejecutar una consulta LINQ o enumerar un IEnumerable de forma segura y mostrar los resultados. Si desea inspeccionar los resultados, ejecute la consulta explícitamente, por ejemplo, con ToList
.
PD
Probablemente sea una buena idea usar una biblioteca global como Glob (descargas de 3M NuGet) para reemplazar todo este código con:
var root = new DirectoryInfo(autodeskPath); var templates = root.GlobFileSystemInfos("*Inventor*/Templates/**/*.*");
.NET Core en sí mismo usa archivos globbing a través del paquete Microsoft.Extensions.FileSystemGlobbing .
Matcher matcher = new(); matcher.AddIncludePatterns(new[] { "*Inventor*/Templates/**/*.*" }); foreach (string file in matcher.GetResultsInFullPath(autodeskPath)) { Console.WriteLine(file); }