作者:flydream0
转自:http://blog.csdn.net/flydream0/article/details/8013274
用MSComm很是方便,但是也得付出代价,那就是在没有注册MSComm控件的PC机上安装时,得注册此控件,网上的资料大部分都是手动注册MSComm控件的方法,但是,不可能每个客户都手动来操作一遍,因此,这种方法在发布时是不可行的,更好的方法是让用户安装程序时让安装程序自动注册MSComm.
注:关于如何手动注册MSComm控件可参考:http://blog.csdn.net/flydream0/article/details/8002012
而本文正在基于此出发点而来的,是用VS2010来实现这一目标的。
总体思想:在用VS2010中使用Custom Action Editor来实现这一目标,即专门写一个注册MSComm的程序来实现,然后在安装程序中执行它。关于如何使用VS2010建立安装部署工程这里就不细讲了,这里主要是讲这一具体实现注册的程序内容。
RegisteMSComm.cpp:
- // RegisterMSComm.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <stdio.h>
- #include <string.h>
- #include <Windows.h>
- //将三个文件拷贝到系统目录
- void CopeFile(char file[],char tarpath[])
- {
- char tempsys[100];
- //char *r;
- //char *t;
- //r=tarpath;
- //t=tempsys;
- //strcpy(t,r);
- char path[256];
- char *p;
- char *q;
- //获取当前程序的目录下的文件路径到path变量中
- GetModuleFileName(GetModuleHandle(NULL),path,sizeof(path));
- p = path;
- while(strchr(p,'\\'))
- {
- p = strchr(p,'\\');
- p++;
- }
- *p = '\0';
- p=strchr(path,'\0');
- q=file;
- strcpy(p,q);
- //获取目标文件的全路径信息
- strcpy(tempsys,tarpath);
- p=strchr(tempsys,'\0');
- *p = '\\';
- p++;
- q=file;
- strcpy(p,q);
- //复制文件
- CopyFile(path,tempsys,false);
- }
- //将相关信息写入注册表
- void regsted()
- {
- HKEY hkey;
- DWORD dwdip;
- BYTE byteArray[80];
- LPBYTE owner_get=byteArray;
- DWORD type_1 =REG_SZ;
- DWORD cbdata_1=80;
- long exist=RegQueryValueEx(HKEY_CLASSES_ROOT, "licenses\\4250e830-6ac2-11cf-8adb-00aa00c00905", NULL, &type_1, owner_get, &cbdata_1);
- if(exist!=ERROR_SUCCESS)
- {
- long ret = RegCreateKeyEx(HKEY_CLASSES_ROOT,"licenses\\4250e830-6ac2-11cf-8adb-00aa00c00905",0l,NULL,REG_OPTION_VOLATILE,KEY_ALL_ACCESS,NULL,&hkey,&dwdip);
- DWORD leng=37;
- char key[37]="kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun";
- /*LPBYTE lpb=new byte(37);
- for(int i=0;i<37;i++)
- lpb[i]=key[i];*/
- long ret2 = RegSetValueEx(hkey,NULL,NULL,REG_SZ,(LPBYTE)&key[0]/*lpb*/,leng);
- }
- }
- //调用新进程注册组件
- void regocx()
- {
- char commandline[256];
- char windowsdir[256];
- char lastcommandline[257];
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- char ocxfile[50]="\\mscomm32.ocx";
- char regfile[50]="\\regsvr32.exe";
- char *p,*q;
- GetSystemDirectory(windowsdir, 256);
- p=commandline;
- q=windowsdir;
- strcpy(p,q);
- p=strchr(commandline,'\0');
- q=ocxfile;
- strcpy(p,q);
- p=strchr(windowsdir,'\0');
- q=regfile;
- strcpy(p,q);
- p=commandline;
- q=&lastcommandline[1];
- strcpy(q,p);
- lastcommandline[0]=' ';
- // 启动regsvr32.exe作为子进程
- bool ret = CreateProcess(windowsdir, lastcommandline, NULL, NULL, false, 0, NULL, NULL, &si, &pi);
- if(ret)
- {
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- }
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- char sys[100];
- char file1[20]="mscomm32.ocx";
- char file2[20]="mscomm32.dep";
- char file3[20]="mscomm.srg";
- //获取win32路径
- GetSystemDirectory(sys,100);
- //拷贝文件
- CopeFile(file1,sys);
- CopeFile(file2,sys);
- CopeFile(file3,sys);
- //注册ocx
- regocx();
- //修改注册表
- regsted();
- return 0;
- }
代码主要分三步:
第一步:拷贝文件到win32目录。
第二步:注册MSComm组件。
第二步:修改注册表。
注:此代码在Debug下可以直接正常运行,但是在release下,默认情况下会编译不过,报找不到外部符号:RegQueryValueEx,RegCreateKeyEx,RegSetValueEx。
通过错误定位,发位在release下,缺少相应的lib库所致,因此,在工程属性->Linker->Input->Addtional Dependencies的内容改为与Debug下相应的内容一致即可,即:
kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
如此,即可编译通过并正常运行.
完!