【问题标题】:PInvoke mciSendStringPInvoke mciSendString
【发布时间】:2013-12-05 08:53:02
【问题描述】:

我正在尝试使用这个功能(它需要),所以我正在编写这样的代码:

    [DllImport("winmm.dll")]
    private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);
    private static void OnEvent(MyEvent ev)
    {
        string sound = Path.Combine(SoundFolder, ev.SoundName) + ".mp3";
        var command = string.Format("open {0} type mpegvideo alias sound", sound);
        mciSendString(command, null, 0, IntPtr.Zero);
        mciSendString("play all", null, 0, IntPtr.Zero);
        new NotificationPage(ev).Show();
    }

但它不播放任何东西,即使是带有硬编码路径的文件。我做错了什么?


添加:我重写了方法以使用 int 来代替 long。 但它仍然无法正常工作。 即使是简单的代码:

    public MainWindow()
    {
        InitializeComponent();
        string sound = Path.Combine(SoundFolder, "NormalPriority") + ".mp3";
        if (!File.Exists(sound))
            throw new FileNotFoundException();
        var command = string.Format("open {0} type mpegvideo alias sound", sound);
        mciSendString(command, null, 0, IntPtr.Zero);
        mciSendString("play all", null, 0, IntPtr.Zero);
    }

所以它是一个 WPF 应用程序

原来是这样的

    private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
    {
        _notificator = new Notificator(Directory.GetCurrentDirectory());
        _notificator.EventStarted += (o, ev) => Dispatcher.Invoke(() => OnEvent(ev));
    ...

我在 C++ 2 上写的

#include <windows.h>
#include <mmsystem.h>
#pragma comment (lib, "winmm.lib")
#include <string>


int main()
{
    int res = mciSendString(L"open D:\\song.mp3 type mpegvideo alias sound", NULL, 0, 0);
    printf("%i", res);
    return 0;
}

同样的错误 277

【问题讨论】:

    标签: c# .net winapi pinvoke dllimport


    【解决方案1】:

    p/invoke 有一个我可以看到的错误。返回值应该是intuint 类型,因为MCIERROR 是一个32 位整数。在 C# 中,long 是 64 位宽。

    除此之外,您调用mciSendString 的方式很好。事实上,你的代码在我运行它时播放 mp3 文件就很好,即使是错误的返回类型声明。

    那么,为什么它对你来说失败了?最明显的原因是多媒体功能依赖于消息循环的存在。也许调用此代码的线程不为消息队列提供服务。例如,您是从控制台应用程序进行调用吗?

    如果线程确实有一个消息队列,并且正确地抽取它,那么我不确定还有什么建议。下一步将是执行一些您目前不执行的错误检查。记下mciSendString 返回的值,看看它们是否表示错误。


    您现在发现mciSendString 正在返回错误代码MCIERR_INTERNAL。对我来说,这听起来像你的问题是环境问题。您的代码对我来说效果很好,因此您的音频设置/驱动程序似乎有问题或 .mp3 文件有问题。但是,由于问题不在您的代码中,因此我们无法帮助您处理代码。

    【讨论】:

    • 当我调用 `mciSendString(command, null, 0, IntPtr.Zero)` 时返回 277。所以他们建议重新启动 Windows。大声笑,但这太疯狂了,应用程序不应该要求重启播放一些 4 秒的 mp3...
    • 那是MCIERR_INTERNAL 对吗?尝试使用完全不同的 .mp3 文件。尝试用 C++ 编写相同的代码。另外,为什么要使用mciSendString 来播放mp3 文件?当然 .net 框架对音频有原生支持。
    • 我知道,这就是为什么我说需要使用 winapi。我试图播放另一个 mp3 - 没办法。它在我第一次玩 autio 时工作过一次,但在 - 沉默之后......所以我会尝试用 C++ 编写它
    • 我认为您遇到了环境问题。你的代码很好。问题出在机器或 mp3 文件上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    相关资源
    最近更新 更多