Windows 永远不会包含临时文件的非 ASCII 字符的目录?
Windows directory that will never contain non-ASCII characters for temp file?
在 Windows 上使用 MinGW 7.3.0,由于 Windows 限制,Hunspell 无法从具有非 ASCII 字符的位置加载字典文件。我已经尝试了所有方法[1],现在我正在将文件复制到没有 ASCII 字符的路径,然后再将其提供给 Hunspell。将其复制到什么位置比较好?
[1]
- Windows 需要
wchar_t
支持 std::iostream.open()
才能正常工作,而 MinGW 没有实现
std::filesystem
可以解决这个问题,但只适用于 GCC 8
- Hunspell 坚持自己加载文件,无法将读取的文件作为字符串传递给它
“自然”适合使用用户选择的临时目录(或其子目录)(参见 %temp%
或 GetTempPath()
)。但是,默认为包含用户名的内容(可以包含“non-ASCII”字符;例如 c:\users\Ø¥Ć¼\AppData\LocalLow\Temp
)或任意内容(关于字符集)。
所以您最好选择一些目录,
a) 从一开始就不包含 off-limits 个字符。例如,您自己选择的 C:\ProgramData
下的目录(例如应用程序名称)不包含 non-ASCII 个字符。
b) 让用户决定将这些文件放在哪里,并确保不允许输入仅包含允许字符的路径。
c) 将 "short path name" 传递给 Hunspell,它不应包含 non-ASCII 字符以与 FAT 文件系统特征兼容。例如,c:\temp\Ø¥Ć¼
的短路径名称是 c:\temp1D~1
.
您可以使用 cmd.exe /c dir /x
查看目录的简称:
C:\temp>dir /x
...
19.07.2019 15:30 <DIR> .
19.07.2019 15:30 <DIR> ..
19.07.2019 15:30 <DIR> 571D~1 Ø¥Ć¼
如何从 MinGW 调用 GetShortPathName
Win32 API 我不知道,但我认为这是可能的。
还要确保查看 MSDN 页面以了解上述特征函数,例如并非所有地方都支持短名称(例如 SMB + 请参阅下面的评论)。
看起来 C:\Windows\Temp
仍然是您可以写给自己的有效路径。
来自 this bug tracker:
In WIN32 environment, use UTF-8 encoded paths started with the long
path prefix \?\ to handle system-independent character encoding
and very long path names (without the long path prefix Hunspell will
use fopen() with system-dependent character encoding instead of
_wfopen()).
所以实际的解决方案似乎是:
- 调用
GetFullPathNameW
to normalize the path. Required because paths with long path prefix\?\
都传递给NTAPI不变。
- 将
L"\\?\"
添加到规范化路径(由于 C 字符串文字要求,反斜杠加倍)。
- 对于 UNC 路径,您必须直接使用 "UNC" 设备(即
L"\\server\share"
→ L"\\?\UNC\server\share"
(感谢 eryksun)
- 以 UTF-8 编码路径,例如。 G。使用
WideCharToMultiByte()
和 CP_UTF8
.
- 将最终的 UTF-8 编码路径传递给 Hunspell。
在 Windows 上使用 MinGW 7.3.0,由于 Windows 限制,Hunspell 无法从具有非 ASCII 字符的位置加载字典文件。我已经尝试了所有方法[1],现在我正在将文件复制到没有 ASCII 字符的路径,然后再将其提供给 Hunspell。将其复制到什么位置比较好?
[1]
- Windows 需要
wchar_t
支持std::iostream.open()
才能正常工作,而 MinGW 没有实现 std::filesystem
可以解决这个问题,但只适用于 GCC 8- Hunspell 坚持自己加载文件,无法将读取的文件作为字符串传递给它
“自然”适合使用用户选择的临时目录(或其子目录)(参见 %temp%
或 GetTempPath()
)。但是,默认为包含用户名的内容(可以包含“non-ASCII”字符;例如 c:\users\Ø¥Ć¼\AppData\LocalLow\Temp
)或任意内容(关于字符集)。
所以您最好选择一些目录,
a) 从一开始就不包含 off-limits 个字符。例如,您自己选择的 C:\ProgramData
下的目录(例如应用程序名称)不包含 non-ASCII 个字符。
b) 让用户决定将这些文件放在哪里,并确保不允许输入仅包含允许字符的路径。
c) 将 "short path name" 传递给 Hunspell,它不应包含 non-ASCII 字符以与 FAT 文件系统特征兼容。例如,c:\temp\Ø¥Ć¼
的短路径名称是 c:\temp1D~1
.
您可以使用 cmd.exe /c dir /x
查看目录的简称:
C:\temp>dir /x
...
19.07.2019 15:30 <DIR> .
19.07.2019 15:30 <DIR> ..
19.07.2019 15:30 <DIR> 571D~1 Ø¥Ć¼
如何从 MinGW 调用 GetShortPathName
Win32 API 我不知道,但我认为这是可能的。
还要确保查看 MSDN 页面以了解上述特征函数,例如并非所有地方都支持短名称(例如 SMB + 请参阅下面的评论)。
看起来 C:\Windows\Temp
仍然是您可以写给自己的有效路径。
来自 this bug tracker:
In WIN32 environment, use UTF-8 encoded paths started with the long path prefix \?\ to handle system-independent character encoding and very long path names (without the long path prefix Hunspell will use fopen() with system-dependent character encoding instead of _wfopen()).
所以实际的解决方案似乎是:
- 调用
GetFullPathNameW
to normalize the path. Required because paths with long path prefix\?\
都传递给NTAPI不变。 - 将
L"\\?\"
添加到规范化路径(由于 C 字符串文字要求,反斜杠加倍)。 - 对于 UNC 路径,您必须直接使用 "UNC" 设备(即
L"\\server\share"
→L"\\?\UNC\server\share"
(感谢 eryksun) - 以 UTF-8 编码路径,例如。 G。使用
WideCharToMultiByte()
和CP_UTF8
. - 将最终的 UTF-8 编码路径传递给 Hunspell。