Dea*_*unz 2 .net c# directory .net-core
Stack Overflow. We meet again. /Sigh
Is it just me or is anybody else getting wacky messages from Directory.CreateDirectory.
Is it just me or do other people have code that has been running flawlessly for years only to suddenly go poof at random for no reason even, when that code has not been changed at all?
Running with windows 10, VS2019. All projects are .NET Core 3.1 or .NET Std 2.0/2.1.
Anyway, I have this code ISettingsProvider that gets implemented by my class for managing app settings. (Stored in xml format) In that class constructor I pass in a string representing the file path to the xml file were the settings will be stored. If the file does not already exist I grab the folder path ala Path.GetDirectoryName and check if it exists and if it does not create it, then write out a empty setting file to that folder. Other wise do nothing because we are about to read the data from the file immediately afterwards.
Below is the constructor for that class. Again this code has been working flawlessly for me for years, across multiple platforms versions and projects, .net pcl 3.5 4.6 .NET Std, Unity3D etc etc
/// <summary>
/// Initializes a new instance of the <see cref="XmlSettingsProvider"/> class.
/// </summary>
/// <param name="fileName">
/// The file name.
/// </param>
/// <param name="create"><c>true</c> Create the settings file immediately if one does not exist.</param>
/// <exception cref="ArgumentNullException">
/// If <see cref="fileName"/> is null or empty.
/// </exception>
public XmlSettingsProvider(string fileName, bool create)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException(nameof(fileName));
}
var directoryName = Path.GetDirectoryName(fileName);
if (directoryName != null && directoryName.IndexOfAny(Path.GetInvalidPathChars()) != -1)
{
throw new Exception("Invalid path characters detected!");
}
var name = Path.GetFileName(fileName);
if (name != null && name.IndexOfAny(Path.GetInvalidFileNameChars()) != -1)
{
throw new Exception("Invalid filename characters detected!");
}
this.readDelayInSeconds = 5;
this.FileName = fileName;
if (create && !File.Exists(fileName))
{
var doc = new XmlDocument();
var declaration = doc.CreateXmlDeclaration("1.0", null, null);
var settings = doc.CreateElement("settings");
doc.AppendChild(settings);
doc.InsertBefore(declaration, doc.DocumentElement);
Directory.CreateDirectory(directoryName);
using (var stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
{
doc.Save(stream);
}
}
this.Read();
}
Run Code Online (Sandbox Code Playgroud)
The problem is with Directory.CreateDirectory. I am trying to create a directory at "d:\documents\StockWatchWpfCore" where "d:\documents" exists and is my windows 10 "My Documents" folder and the "d:\documents\StockWatchWpfCore" does not yet exist.
I thought maybe it was windows 10 Ransomware detection preventing my app from creating a folder in "d:\documents" because I have "d:\documents" added as a protected folder. But I am not getting any messages in Block History stating my app is being blocked.
To make matters worse, or more confusing, the exception info that is being raised is not what you would expect.
The exception data being thrown.
Call Stack
at System.IO.FileSystem.CreateDirectory(String fullPath, Byte[] securityDescriptor)
at System.IO.Directory.CreateDirectory(String path)
at Codefarts.AppCore.SettingProviders.Xml.XmlSettingsProvider..ctor(String fileName, Boolean create) in P:\Code Projects\Codefarts.AppCore\Setting Providers\Codefarts.AppCore.SettingProviders.Xml\XmlSettingsProvider.cs:line 142
at Codefarts.AppCore.SettingProviders.Xml.XmlSettingsProvider..ctor(String fileName) in P:\Code Projects\Codefarts.AppCore\Setting Providers\Codefarts.AppCore.SettingProviders.Xml\XmlSettingsProvider.cs:line 162
at Codefarts.WpfAppBootstrapper.BootstrappedApp.OnStartup(StartupEventArgs e) in P:\Code Projects\Codefarts.WpfAppBootstrapper\BootstrappedApp.cs:line 63
at System.Windows.Application.<.ctor>b__1_0(Object unused)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
Run Code Online (Sandbox Code Playgroud)
Source
"System.IO.FileSystem"
Run Code Online (Sandbox Code Playgroud)
Message
"Could not find file 'd:\\Documents\\StockWatchWpfCore'."
Run Code Online (Sandbox Code Playgroud)
InnerException
null
Run Code Online (Sandbox Code Playgroud)
Did you notice the error message? "Could not find file 'd:\Documents\StockWatchWpfCore'." File? I'm working with directories not files?!?!
The plot thickens ......
So in another part of my code I have hooked into the AppDomain.ResolveAssemblies event. Interestingly as soon as I step into Directory.CreateDirectory the ResolveAssemblies event gets fired 2 times both with the same request
Name
"System.IO.FileSystem.resources, Version=4.1.2.0, Culture=en-US, PublicKeyToken=b03f5f7f11d50a3a"
Run Code Online (Sandbox Code Playgroud)
RequestingAssembly
{System.IO.FileSystem, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
Run Code Online (Sandbox Code Playgroud)
My assembly resolve event code
private Assembly ResolveAssemblies(object sender, System.ResolveEventArgs args)
{
var folderPaths = new List<string>(this.AssemblySearchFolders);
folderPaths.Add(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
var filter = new AssemblyName(args.Name);
foreach (var folderPath in folderPaths)
{
if (!Directory.Exists(folderPath))
{
continue;
}
var fileMatches = Directory.GetFiles(folderPath, filter.Name + ".dll", SearchOption.AllDirectories);
var assemblyPath = fileMatches.FirstOrDefault();
if (!string.IsNullOrWhiteSpace(assemblyPath) && File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
BTW "this.AssemblySearchFolders" is an empty collection. It's just there in case I want to search other locations other then the app install folder.
Ok so at this point it seems like .net is trying to resolve a missing assembly reference that it can't find on it's own. So I opened up my project containing the XmlSettingsProvider implementation. That project is a .NET Core 3.1 project type with this project info
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyVersion>2020.5.10.9</AssemblyVersion>
<FileVersion>2020.5.10.9</FileVersion>
</PropertyGroup>
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Codefarts.AppCoreNETStd\Codefarts.AppCoreNETStd2.csproj" />
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
Notice that after I started having this issue I made sure to include the CopyLocalLockFileAssemblies property in my .csproj file. But it does not copy any references to the bin folder like "System.IO.FileSystem".
Ok, so then I tried to do a nuget search for System.IO.FileSystem and found this https://www.nuget.org/packages/System.IO.FileSystem/4.3.0?_src=template
It appears to support .NET Standard 1.3 but no mention of .NET Core. I added the nuget reference anyway and did a rebuild then ran my app again and still the same issue. No System.IO.FileSystem.dll being copied to the bin folder and AssemblyResolve event still being fired still looking for missing assembly references.
It's at this point I'm running out of ideas and am at the limit of my understandings. Also the googles is not helping. It's frustrating because the XmlSettingsProvider code has not changed and has been working fine for the last two weeks.. All of a sudden it decides to pipe up and start giving my this error last two days.
As a simplified test I started a new .Net Core 3.1 console app with this code and I get the same issue with not being able to resolve System.IO.FileSystem
using System;
using System.IO;
namespace assembly_resolve
{
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Directory.CreateDirectory(@"d:\documents\wpfcore");
}
private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
return args.RequestingAssembly;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Also as a test of my sanity I wrote this linqPad6 test code.
void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
{
return e.RequestingAssembly;
};
Directory.CreateDirectory(@"d:\documents\WpfCoreTest");
}
Run Code Online (Sandbox Code Playgroud)
The test code does not fire the AssemblyResolve event as I new it would not. Also tried obligatory system shutdown and reboot to no avail. So it would seem that there are architecture/behaviour changes moving from .NET Framework to .NET Core. Ala -> https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.assemblyresolve?view=netcore-3.1
还尝试通过这个(无耻插件)结婚http://www.createdbyx.com/createdbyx/post/2016/07/02/MSBuild-Recursively-Copy-Indirect-Project-Dependency-to-bin.aspx 但仍然没有成功。
所以总而言之,我需要以某种方式指示 .net 在哪里找到程序集“System.IO.FileSystem”digery 这样做,这样它就可以“做这件事”
普韦兹哈尔普!
更新:第二天。整个晚上都在想这个问题。我的整个想法是 .NET Core 出现问题,或者某种用户权限等,因此我在 C# 和 VS2019 中创建了额外的控制台项目,目标是 .NET Framework 4 Client Profile、4.6、4.7、.NET Core 3.1,所有这些都做了不起作用并在尝试创建目录时抛出相同的错误。现在我知道他们过去曾工作过,但无法弄清楚为什么它停止工作了。我也尝试以管理员模式运行vs2019,但无济于事。到底是怎么回事?
我注意到它试图查找“System.IO.FileSystem.resources,Version=4.1.2.0,...”的程序集的版本号,当我查看nuget 包时,该包没有版本 4.1.2.0。另外,当我查看“C:\Users\Dean.nuget\packages\system.io.filesystem”文件夹时,没有 4.1.2 的相应文件夹。
所以我现在的想法是我的系统出了严重的错误,而且根本不是我的代码。
然后我尝试关闭 Windows 勒索软件保护,然后……到底是什么……它开始工作了。这让事情变得更有趣,因为 Windows 勒索软件保护中没有阻止历史记录报告表明它正在保护我的系统免受我自己的应用程序代码的侵害?!!!?!但我每隔一天都会从系统上的其他应用程序收到阻止历史记录通知和报告。作为旁注,我确实将 vs2019 devenv.exe 添加为允许的应用程序。
将我的应用程序 .exe 添加到“通过受控文件夹访问添加应用程序”,瞧它正在工作。还修改了应用程序代码并重新运行它以检查勒索软件保护是否会检测到我的应用程序的不同版本,但它没有。因此,这表明从首次创建块规则时起,它就没有进行任何类型的 crc/文件内容比较检查。
我想知道是否因为它是一个 .net 应用程序,勒索软件保护不会报告阻止历史记录。无论如何,问题已经被追踪到,我的理智已经恢复,并且我正在通过位于勒索软件保护窗口右侧的“给我们反馈”链接提交错误报告。
| 归档时间: |
|
| 查看次数: |
1259 次 |
| 最近记录: |