WinCE和PC数据交互之RAPI

    /// <summary>
    /// wince设备--pc有线通信类
    /// </summary>
    public class Rapi
    {
        private const int TimeOut = 2000;//异步连接设备超时时间2秒

        #region 初始化、卸载设备(私有)

        /// <summary>
        /// 异步初始化设备,打开后不关闭(默认打开后不关闭,因此定义为私有)
        /// </summary>
        /// <param name="nTimeout">单位ms</param>
        /// <returns></returns>
        private bool InitDevice(int nTimeout)
        {
            Rapiinit ri = new Rapiinit();
            ri.cbsize = Marshal.SizeOf(ri);
            uint hRes = CeRapiInitEx(ref ri);

            ManualResetEvent me = new ManualResetEvent(false);
            me.SafeWaitHandle = new SafeWaitHandle(ri.heRapiInit, false);
            if (!me.WaitOne(nTimeout, true)) //阻塞等待结果
            {
                CeRapiUninit();
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// CE设备卸载,一般情况下不适用,各个方法末尾已经卸载设备。
        /// </summary>
        private void RapiUninit()
        {
            CeRapiUninit();
        }

        #endregion


        #region 公有方法(判断文件是否存在、删除、wince和pc传输文件)

        /// <summary>
        /// 判定文件是否存在
        /// -1:连接不到服务器 0:不存在 1:存在
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns>-1:连接不到服务器 0:不存在 1:存在</returns>
        public int IsExistFile(string fileName)
        {
            if (InitDevice(TimeOut))
            {
                CeFindData findData = new CeFindData();
                int jieg = CeFindFirstFile(fileName, ref findData);
                CeRapiUninit();
                if (jieg != -1) return 1;
                else return 0;
            }
            else
                return -1;

        }

        /// <summary>
        /// 删除ce设备上的文件
        /// -1:连接不到服务器 0:删除失败 1:删除成功
        /// </summary>
        /// <param name="fileName">要删除的文件名</param>
        /// <returns>-1:连接不到服务器 0:删除失败 1:删除成功</returns>
        public int DeleteFile(string fileName)
        {
            if (InitDevice(TimeOut))
            {
                CeFindData findData = new CeFindData();
                int jieg = CeFindFirstFile(fileName, ref findData);
                if (jieg != -1)
                {
                    bool isok = CeDeleteFile(fileName);
                    CeRapiUninit();
                    if (isok) return 1;
                    else return 0;
                }
                else return 1; //如果不存在要删除的文件,等同于删除成功。
            }
            else
                return -1;
        }

        /// <summary>
        /// PC-->Wince
        /// </summary>
        /// <param name="localFileName">pc文件</param>
        /// <param name="remoteFileName">wince文件</param>
        /// <returns></returns>
        public bool CopyFileToPDA(string localFileName, string remoteFileName)
        {
            #region 方法用变量

            const uint genericWrite = 0x40000000;
            // 设置读写权限
            const short createNew = 1;
            // 创建新文件 
            const short fileAttributeNormal = 0x80;
            // 设置文件属性 
            const short invalidHandleValue = -1;
            // 错误句柄 
            byte[] buffer = new byte[0x1000];
            // 传输缓冲区定义为4k 
            int byteswritten = 0;
            int filepos = 0;

            #endregion

            if (InitDevice(TimeOut))
            {
                //查找远程文件
                CeFindData findData = new CeFindData();
                int jieg = CeFindFirstFile(remoteFileName, ref findData);
                if (jieg != -1)
                {
                    CeDeleteFile(remoteFileName);
                }
                // 创建远程文件 
                IntPtr remoteFile = CeCreateFile(remoteFileName, genericWrite, 0, 0, createNew, fileAttributeNormal, 0);
                // 检查文件是否创建成功 
                if ((int) remoteFile == invalidHandleValue)
                {
                    throw new Exception("创建文件失败!");
                }
                else
                {
                    // 打开本地文件 
                    FileStream localFile = new FileStream(localFileName, FileMode.Open);
                    // 读取4K字节 
                    int bytesread = localFile.Read(buffer, filepos, buffer.Length);
                    while (bytesread > 0)
                    {
                        // 移动文件指针到已读取的位置 
                        filepos += bytesread;
                        // 写缓冲区数据到远程设备文件 
                        if (!Convert.ToBoolean(CeWriteFile(remoteFile, buffer, bytesread, ref byteswritten, 0)))
                        {
                            // 检查是否成功,不成功关闭文件句柄,抛出异常 
                            CeCloseHandle(remoteFile);
                            throw new Exception("写远程文件失败!");
                        }
                        try
                        {
                            // 重新填充本地缓冲区 
                            bytesread = localFile.Read(buffer, 0, buffer.Length);
                        }
                        catch (Exception)
                        {
                            bytesread = 0;
                        }
                    }
                    // 关闭本地文件 
                    localFile.Close();
                    // 关闭远程文件 
                    CeCloseHandle(remoteFile);
                    CeRapiUninit();
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Wince-->Pc
        /// </summary>
        /// <param name="remoteFileName">wince文件</param>
        /// <param name="localFileName">pc文件</param>
        /// <returns> 1 成功 0 失败 -1 没找到文件</returns>
        public int CopyFileToPC(string remoteFileName, string localFileName)
        {
            const short createOpen = 3;// 设置读写权限
            const uint genericRead = 0x80000000;
            const short fileAttributeNormal = 0x80; // 设置文件属性
            const short invalidHandleValue = -1; // 错误句柄

            if (InitDevice(TimeOut))
            {
                IntPtr fileh = CeCreateFile(remoteFileName, genericRead, 0, 0, createOpen, fileAttributeNormal, 0);
                if ((int) fileh == invalidHandleValue)
                {
                    return -1;
                }
                else
                {
                    try
                    {
                        FileStream writer = new FileStream(localFileName, FileMode.Create);
                        int size = CeGetFileSize((int) fileh, 0);
                        byte[] buff = new byte[400096];
                        int readed = 400096;
                        while (readed == 400096)
                        {
                            CeReadFile((int) fileh, buff, 400096, out readed, 0);
                            writer.Write(buff, 0, readed);
                        }
                        CeCloseHandle(fileh);
                        writer.Close();

                        //上传成功后删除ce文件
                        /*CeFindData findData = new CeFindData();
                        int jieg = CeFindFirstFile(remoteFileName, ref findData);
                        if (jieg != -1)
                        {
                            CeDeleteFile(remoteFileName);
                        }*/
                        CeRapiUninit();
                        return 1;
                    }
                    catch
                    {
                        return 0;
                    }
                }
            }
            else
            {
                return 0;
            }
        }

        #endregion


        #region 该类要用到的结构体

        public struct CeFindData
        {
            public int DwFileAttributes;
            public FILETIME FtCreationTime;
            public int FtCreationTime2;
            public FILETIME FtLastAccessTime;
            public FILETIME FtLastWriteTime;
            public int NFileSizeHigh;
            public int NFileSizeLow;
            public int DwOid;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string CFileName;
        }

        [StructLayout(LayoutKind.Explicit)]
        private struct Rapiinit
        {
            [FieldOffset(0)] public int cbsize;
            [FieldOffset(4)] public readonly IntPtr heRapiInit;
            [FieldOffset(8)] private readonly IntPtr hrRapiInit;
        }

        #endregion


        #region 声明要引用的API

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeCloseHandle(IntPtr hObject);

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeWriteFile(IntPtr hFile, byte[] lpBuffer,
                                              int nNumberOfbytesToWrite, ref int lpNumberOfbytesWritten,
                                              int lpOverlapped);

        
        [DllImport("rapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern IntPtr CeCreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode,
                                                  int lpSecurityAttributes, int dwCreationDisposition,
                                                  int dwFlagsAndAttributes, int hTemplateFile);

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeRapiUninit();

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern bool CeDeleteFile(string fileName);

        [DllImport("rapi.dll")]
        private static extern uint CeRapiInitEx(ref Rapiinit pRapiInit);

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeFindFirstFile(string lpFileName, ref CeFindData lpFindFileData);

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeGetFileSize(int hFile, int lpOverlapped);

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeReadFile(int hFile, byte[] lpBuffer, int lpOverlapped, out int laji, int gouride);

        #endregion


        #region 未用到的api接口

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
                                                        uint dwShareMode, IntPtr lpSecurityAttributes,
                                                        uint dwCreationDisposition,
                                                        uint dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern Boolean WriteFile(SafeFileHandle lpFileName, byte[] lpBuffer,
                                                int nNumberOfbytesToWrite, ref int lpNumberOfbytesWritten,
                                                int lpOverlapped);

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeCopyFile(string lpExistingFileName, string lpNewFileName, Boolean bFailIfExists);

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeReadFile(IntPtr hFile, byte[] lpBuffer,
                                             int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, int lpOverlapped);

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeRapiInit();

        [DllImport("rapi.dll", CharSet = CharSet.Unicode)]
        private static extern int CeRapiGetError();

        #endregion
    }

在做WinCE和PC之间进行文件传输要用到rapi.dll,但是在xp和win7上是不同的移动设备中心,该动态库的版本也是不同的,因此在VS解决方案中一定不要添加该动态库,如果添加了一定不要输出到debug里面,否则会因为编译好的程序在不同的操作系统上出现问题,因为目标平台一定会安装移动设备中心,程序会根据不同版本的rapi.dll动态的调用。

以上是在开发中遇到的问题。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值