当前位置:编程学习 > C#/ASP.NET >>

刻录程序报错,调用COM组件失败的问题

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
//using IMAPI2FS;
using IMAPI2.Interop;
using System.Runtime.InteropServices.ComTypes;

namespace BurnCD
{
    internal class Recorder :  IRecorder
    {
        #region IRecorder 成员

        /// <summary>
        /// 刻录机对象
        /// </summary>
        private MsftDiscRecorder2 m_recorder = null;

        /// <summary>
        /// 根据指定的光驱路径,建立光驱对象
        /// </summary>
        /// <param name="strPath">参数是光驱的标示符</param>
        internal Recorder(string strID)
        {
            try
            {
                m_recorder = new MsftDiscRecorder2();
                m_recorder.InitializeDiscRecorder(strID);
            }
            catch (System.Exception Ex)
            {
                throw new System.Exception("根据光驱标示符:" + strID + " 建立光驱对象出错");
            }
        }
        
        /// <summary>
        /// 不允许通过其他途径建立
        /// </summary>
        private Recorder()
        {

        }

        /// <summary>
        /// 要刻录到这个刻录机中的文件或文件夹
        /// </summary>
        private List<IBurnMedia> m_needBurnMedias = new List<IBurnMedia>();

        /// <summary>
        /// 要刻录的对象,要想修改要刻录的文件,自己从这里找好了,不再给你提供
        /// 其他查询方法
        /// </summary>
        public List<IBurnMedia> BurnMediaFileList
        {
            get
            {
                return m_needBurnMedias;
            }
        }

        /// <summary>
        /// 添加刻录文件到这个对象中
        /// </summary>
        /// <returns></returns>
        public IBurnMedia AddMediaFile()
        {
            //列表中新加一个BurnMedia对象
            BurnMedia burnMedia = new BurnMedia();
            m_needBurnMedias.Add(burnMedia);
            return burnMedia;
        }

        /// <summary>
        /// 刻录
        /// </summary>
        /// <returns></returns>
        public bool Burn(out string Excep)
        {
            try
            {
                return DoBurn(out Excep);
            }
            catch (System.Exception Ex)
            {
                Excep = Ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 刻录
        /// </summary>
        private bool DoBurn(out string Excep)
        {
            //正式的开始刻录
            MsftDiscFormat2Data msFormat = new MsftDiscFormat2Data();
            msFormat.Recorder = m_recorder;
            msFormat.ClientName = "15s";

            //设置verification等级
            IBurnVerification burnVer = (IBurnVerification)msFormat;
            burnVer.BurnVerificationLevel = IMAPI_BURN_VERIFICATION_LEVEL.IMAPI_BURN_VERIFICATION_FULL;

            //检查是否是blank
            object[] sessions = null;
            if (false == msFormat.MediaHeuristicallyBlank)
            {
                sessions = (object[])msFormat.MultisessionInterfaces;
            }

            //创建文件流
            IStream fileStream = null;
            if (false == CreateFileStream(ref sessions, out fileStream, out Excep))
            {
                return false;
            }

            //写文件
            try
            {
                msFormat.Write(fileStream as System.Runtime.InteropServices.ComTypes.IStream);
                Excep = "Write file to DVD success!";
                return true;
            }
            catch (System.Exception Ex)
            {
                Excep = Ex.Message;
                return false;
            }
            finally
            {
                if (fileStream != null)
                {
                    Marshal.FinalReleaseComObject(fileStream);
                }
            }
        }

        /// <summary>
        ///  创建文件流
        /// </summary>
        /// <param name="sessions"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        private bool CreateFileStream(ref object[] sessions, out IStream stream, out string Excep)
        {
            MsftFileSystemImage msImage;
            try
            {
                //设置相关信息
                msImage = new MsftFileSystemImage();
                msImage.ChooseImageDefaults(m_recorder);
                msImage.FileSystemsToCreate = FsiFileSystems.FsiFileSystemISO9660 | FsiFileSystems.FsiFileSystemJoliet;
                msImage.VolumeName = "ABC";

                //以下为抄的,没看懂
                if (sessions != null)
                {
                    msImage.MultisessionInterfaces = sessions;
                    msImage.ImportFileSystem();
                }

                IFsiDirectoryItem rootItem = msImage.Root;

                foreach (BurnMedia bm in m_needBurnMedias)
                {
                    //依次刻录
                    bm.AddToFileSystem(rootItem);
                }

                stream = msImage.CreateResultImage().ImageStream;
                Excep = "Create file stream success!";
                return true;
            }
            catch (System.Exception Ex)
            {
                stream = null;
                Excep = Ex.Message;
                return false;
            }
        }

        private long m_nDiskSize = 0;
        private long m_nUseableSize = 0;

        /// <summary>
        /// 获取光驱中光盘的大小,单位是字节
        /// </summary>
        /// <returns>如果返回-1,则说明当前光驱中没有光盘或者光盘读取错误</returns>
        public long GetDiskSize()
        {
            //首先判断光驱是否可以读盘
            IDiscFormat2Data msFormat = new MsftDiscFormat2Data();
            
            if (msFormat.IsRecorderSupported(m_recorder) == false)
            {
                //光驱不支持这种格式光盘,或者没有怎么的
                return -1;
            }

            //以下代码,还没有研究明白
            msFormat.Recorder = m_recorder;
            //判断是不是有光盘在里面
            try
            {
                IMAPI_FORMAT2_DATA_MEDIA_STATE  st = msFormat.CurrentMediaStatus;
            }
            catch (System.Exception ex)
            {
             //光盘不存在
                return -1;
            }

            //可用的
            m_nUseableSize = msFormat.FreeSectorsOnMedia * 2048;
            //总大小
            m_nDiskSize = (msFormat.TotalSectorsOnMedia) * 2048;
            return m_nDiskSize;
        }

        /// <summary>
        /// 获取可用的光盘空闲空间
        /// </summary>
        /// <returns></returns>
        public long GetDiskUseableSize()
        {
            GetDiskSize();
            return m_nUseableSize;
        }

        #endregion
    }
}















然后我写了一个接口实现刻录文件的功能:
        public int BurnCD(string RecordPartition, string RecordFilePath, out string Excep)
        {
            IBurnCD Bcd = IBurnCD.CreateInstance();
            List<string> StrRecorder = Bcd.GetRecorderList();
            string PartitionName = StrRecorder.Find(
                          delegate(string Partition)
                          {
                              return Partition.Equals(RecordPartition);
                          }
                          );
            if (String.IsNullOrEmpty(PartitionName))
            {
                Excep = "Specified partition is not exist!";
                return 1;
            }

            if (!File.Exists(RecordFilePath))
            {
                Excep = "The file is not exist!";
                return 2;
            }
            IRecorder Record = Bcd.GetRecorder(RecordPartition);
            IBurnMedia BurnMedia = Record.AddMediaFile();
            BurnMedia.Path = RecordFilePath;
            BurnMedia.Type = MediaType.File;

            bool bRet = Record.Burn(out Excep);
            if (bRet)
                return 0;
            else
                return 3;
        }

上面的代码在刻录大概800M以下的文件没有问题,但是在刻录800M以上的文件的时候就会抛异常,提示“调用COM组件时失败”请哪位大侠指点? --------------------编程问答-------------------- 上面的程序在msFormat.Write(fileStream as System.Runtime.InteropServices.ComTypes.IStream);
这条语句执行的时候抛异常了,调用COM组件失败,但是写小文件的时候不会抛异常,返回是成功的。请高手指点原因,不胜感激!高分送上!
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,