Winmm.dll保存文件失败问题分析与解决方法
最近在调用Winmm.dll的MciSendString save函数保存音频时,发现怎么保存都没有用。
这是保存的相关代码
mciSendString("stop movie", "", 0, 0);
int mc_Res= mciSendString("save movie X://x//xxxx//xxxx/xxxx/xxxx.wav", "", 0, 0);
mciSendString("close movie", "", 0, 0);
当然路径就简写了。
经过测试后发现,返回的int结果都是304,后来我找到Winmm.dll的错误代码表对照了一下,如下
返回的代码是FileName_Required,带着这个代码去MSDN查了一下。
意思大概就是说,文件名无效,请确保文件名不超过8个字符。8个???我在想随便一个文件名就得超过8个了,这样这个库怎么可能用得上,于是带着这个问题又去谷歌了一下,比较幸运的是国外有很多开发人员也遇到了这个问题,但不知道如何解决。
万幸的是终于找到了答案
这个Basj大概意思是说,使用旧版MCI会碰到的问题就是代入的Path路径太长导致报错,这是它的一个功能限制,经过他的测试,发现,只要MciSendString的path路径+文件名长度超过127,这个文件就无法保存,尽管在MSDN并没有这样的限制,但是我经过实际测试,发现确实如此,只要path超过127,MciSendString函数就会返回FileName_Required。
所以最后解决方案就是
1.在保存之前,先判断一下path+filename的字符长度是否超过127,若超过可以建一个缓存路径,保存在缓存路径下后Cpoy到想放的指定目录。
2.使用Kernel32.dll函数中的GetShortPathName,它会将路径进行简化,代码如下:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetShortPathName(
[MarshalAs(UnmanagedType.LPTStr)]string path,
[MarshalAs(UnmanagedType.LPTStr)]StringBuilder short_path,
int short_len
);
public static string GetShortPath(string name)
{
StringBuilder short_ = new StringBuilder(255);
int result = GetShortPathName(@name, short_, 255);
return short_.ToString();
}
这样一般长度的路径将会大大缩减,但是也会碰到一个问题,面对于比较复杂,纵深较深的路径,往往缩短了还是会超过127个字符,所以推荐第一种方案,使用临时目录,再根据实际情况进行操作,或者最直接的方法,换库。
注:原创文章,转载请注明出处。