Full temporary folder will crash cursor initialization
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
* .NET Core Version: 3.0 Preview5
* Windows version: windows 10 1903
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
**Problem description:**
The cursor will crash at initialization when the temporary folder full.
**Actual behavior:**
I set a cursor from a resource and use this code.
```
var uri = new Uri("pack://application:,,,/Foo.cur");
var resource = Application.GetResourceStream(uri);
Cursor = new Cursor(resource.Stream);
```
I can find the cursor will crash at initialization when the temporary folder full.
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
System.IO.Directory.InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, Boolean checkHost)
System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost)
System.IO.Directory.CreateDirectory(String path)
System.IO.FileHelper.CreateAndOpenTemporaryFile(String& filePath, FileAccess fileAccess, FileOptions fileOptions, String extension, String subFolder)
System.Windows.Input.Cursor.LoadFromStream(Stream cursorStream)
System.Windows.Input.Cursor..ctor(Stream cursorStream, Boolean scaleWithDpi)
System.Windows.Input.Cursor..ctor(Stream cursorStream)
FawlalnejajerelaWhallgemcurkear.MainWindow..ctor()
**Expected behavior:**
The cursor can be set.
**Minimal repro:**
Run this code when the temporary folder full.
var uri = new Uri("pack://application:,,,/Text.cur");
var resource = Application.GetResourceStream(uri);
Cursor = new Cursor(resource.Stream);
And the other way is set a can not visit folder as the temp folder. And you can see the code in https://github.com/lindexi/lindexi_gd/tree/8e346e750fe2075e1366a2a098d63af3b50db177/FawlalnejajerelaWhallgemcurkear that I set a folder name as `D:\lindexi\不存在文件` that is an unauthorized access folder.
**Reason**
The Cursor.LegacyLoadFromStream will generate a temporary file based on the memory stream. But the [Path.GetTempFileName Method](https://docs.microsoft.com/en-us/dotnet/api/system.io.path.gettempfilename?wt.mc_id=MVP ) limit the number of the files is 65535 and it will throw IOException when overcount.
The LoadFromStream code in https://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/Cursor.cs,090cb505b6310a4e
The LegacyLoadFromStream code in https://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/Cursor.cs,935d59bd1efe76e4,references
Actual LoadFromStream may ignore LegacyLoadFromStream. But FileHelper.CreateAndOpenTemporaryFile will generate the file in WPF folder by default and use Path.GetRandomFileName to create a file without check access. And it also crashes when the temp folder can not write.
**solution**
1. Set the Environment Variable to the own folder that can read or write.
```
Environment.SetEnvironmentVariable("TEMP", newTempFolder);
Environment.SetEnvironmentVariable("TMP", newTempFolder);
```
Why set the environment variable is safe? Because all the process can call the `Path.GetTempFileName` that will throw IOException when the other process uses it to create and do not delete.
1. Use the `public Cursor(string cursorFile)` replace `public Cursor(Stream cursorStream)` that the first will call LoadFromFile and the LoadFromFile will load the file and do not need to copy to temp folder.
Reference
[WPF 光标初始化的时候 temp 文件夹满了无法创建](https://blog.lindexi.com/post/WPF-%E5%85%89%E6%A0%87%E5%88%9D%E5%A7%8B%E5%8C%96%E7%9A%84%E6%97%B6%E5%80%99-temp-%E6%96%87%E4%BB%B6%E5%A4%B9%E6%BB%A1%E4%BA%86%E6%97%A0%E6%B3%95%E5%88%9B%E5%BB%BA.html )
Contributor guide
Assessment
This issue has not been assessed yet.