如果路径太长,mciSendString将无法播放音频文件 [英] mciSendString won't play an audio file if path is too long
问题描述
当文件的路径+文件名非常长时,我注意到了
When the path+filename of a file is really long, I've noticed that
PlaySound(fName.c_str(), NULL, SND_ASYNC);
有效,但无效
mciSendString((L"open \"" + fName + L"\" type waveaudio alias sample").c_str(), NULL, 0, NULL);
mciSendString(L"play sample", NULL, 0, NULL);
命令失败的示例:
打开"C:\ qisdjqldlkjsqdjqdqjslkdjqlksjlkdjqsldjlqjsdjqdksq \ dajdjqjdlqjdlkjazejoizajoijoifjoifjoifjdsfjsfszjfoijdsjfoijdsoifoidsjfojdsofjdsoijfoisjfoijdsjpjjjjjjjjjjjjjjjjjjdjjjjjjjjjjjjjjjjjjwjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjwjjjjjjjjjwjjjjjjjjjwjjjjjjjjwjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj音符."
open "C:\qisdjqldlkjsqdjqdqjslkdjqlksjlkdjqsldjlqjsdjqdksq\dajdjqjdlqjdlkjazejoizajoijoifjoifjdsfjsfszjfoijdsjfoijdsoifoidsjfojdsofjdsoijfoisjfoijoisdjfosjfqsd\Windows Critical Stop.wav" type waveaudio alias sample
但是:
-
我真的需要mciSendString而不是PlaySound(),因为PlaySound()不会播放某些文件(48 khz音频文件,有时是24位文件等)
I really need mciSendString instead of PlaySound(), because PlaySound() doesn't play certain files (48 khz audio files, sometimes 24-bit files, etc.)
我需要能够播放路径很长的音频文件,因为我的应用程序的最终用户可能会有这样的文件
I need to be able to play audio files with potentially long paths because the end user of my app might have such files
如何使mciSendString接受长文件名?
注意:
-
我也尝试使用最大路径名+文件名长度为127(127:有效,128+:无效)
The max path+filename length is 127 (127: working, 128+: not working)
如果真的无法使
mci *
函数使用大于127个字符的文件名,我可以使用winapi(没有外部库)?(PlaySound
不是一个选项,因为它不能真正适用于所有wav文件,例如48 khz:无效等).If really it's impossible to make
mci*
functions work with longer-than-127-char filenames, what could I use instead, just with winapi (without external libraries)? (PlaySound
is not an option because doesn't work realiably with all the wav files, such as 48 khz: non-working, etc.)推荐答案
127的极限看起来很奇怪.我没有在MSDN上找到任何有关此的信息.
The 127 limit looks strange. I didn't find any information on MSDN about it.
-
还有另一种可打开的语法:您可以尝试的一个选项是将工作目录更改为文件目录,然后限制仅适用于文件名.->
SetCurrentDiectory
An option You could try is to change the working directory to the directory of the file, then the limit only applies to filename. ->
SetCurrentDiectory
To shorten the filename a Winapi function can be used
GetShortPathName
But:SMB 3.0不支持连续共享的短名称可用性功能.
SMB 3.0 does not support short names on shares with continuous availability capability.
弹性文件系统(ReFS)不支持短名称.如果你打电话磁盘上没有任何短名称的路径上的GetShortPathName,调用将成功,但是将返回长名称路径.NTFS卷也可以实现这种结果,因为没有确保给定的长名称存在短名称.
Resilient File System (ReFS) doesn't support short names. If you call GetShortPathName on a path that doesn't have any short names on-disk, the call will succeed, but will return the long-name path instead. This outcome is also possible with NTFS volumes because there's no guarantee that a short name will exist for a given long name.
基于MSDN的示例:
#include <string> #include <Windows.h> template<typename StringType> std::pair<bool, StringType> shortPathName( const StringType& longPathName ) { // First obtain the size needed by passing NULL and 0. long length = GetShortPathName( longPathName.c_str(), NULL, 0 ); if (length == 0) return std::make_pair( false, StringType() ); // Dynamically allocate the correct size // (terminating null char was included in length) StringType shortName( length, ' ' ); // Now simply call again using same long path. length = GetShortPathName( longPathName.c_str(), &shortName[ 0 ], length ); if (length == 0) return std::make_pair( false, StringType() ); return std::make_pair(true, shortName); } #include <locale> #include <codecvt> #include <iostream> std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; //std::string narrow = converter.to_bytes( wide_utf16_source_string ); //std::wstring wide = converter.from_bytes( narrow_utf8_source_string ); int main( int argc, char** argv ) { std::wstring myPath = converter.from_bytes( argv[0] ); auto result = shortPathName( myPath ); if (result.first) std::wcout << result.second ; return 0; }
这篇关于如果路径太长,mciSendString将无法播放音频文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-