WinCE和PC数据交互之RAPI

来源:互联网 发布:北京网络监控安装 编辑:程序博客网 时间:2024/06/06 06:52
    /// <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动态的调用。

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

原创粉丝点击