.Net Framework 4.7.2
That was a very surprisingly issue...
I have this routine to get all available Inventor templates from local disk, no matter which version it is:
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;
}
If I run this code, I got this 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.
What makes it more crazy is if I rewrite the code, to manually call Directory.Exists
and it works!!!
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;
}
You'll get the same result if you just check via QuickWatch:
For now I can use the rewrited version, but I was a lot curious if I'm the lucky one... :-)
CodePudding user response:
That's not a .NET problem. The code will run fine, you don't have to change anything. The debugger says it can't safely execute the query in the watch window so it can't display any results. The error explains that
Evaluation of native methods in this context is not supported.
template
isn't a list of documents, it's a query that hasn't been executed yet. The debugger would have to execute that query to retrieve and the results.
This is neither a problem nor uncommon. There are several cases where the debugger can't execute a LINQ query or enumerate an IEnumerable safely and display the results. If you want to inspect the results, execute the query explicitly eg with ToList
.
PS
It's probably a good idea to use a globbing library like Glob (3M NuGet downloads) to replace all this code with :
var root = new DirectoryInfo(autodeskPath);
var templates = root.GlobFileSystemInfos("*Inventor*/Templates/**/*.*");
.NET Core itself uses file globbing through the Microsoft.Extensions.FileSystemGlobbing package.
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*Inventor*/Templates/**/*.*" });
foreach (string file in matcher.GetResultsInFullPath(autodeskPath))
{
Console.WriteLine(file);
}