VC++ 创建msi文件

  • 编写自己软件的安装程序

  • 这里只是创建安装程序类型的文件,当然创建出来也是不能用的。找了好多天资料,看了好多天英语,终于能创建出msi文件了,用orca打开是正确的文件格式,值得自己记录一下了,msi数据库里面的各种表关系复杂,不是一时半刻能研究清楚的,现在先记录一个开头吧。希望研究过msi c++ 编程的大神们给点指导。想实现的目标是写一个程序附到软件程序后面,这样可以在编译完成后直接会有安装程序msi文件。就像平常下载的软件,可以写注册表,创建桌面快捷方式,注册各种软件用到的组件和功能。就简单的hello
    world 程序也是麻雀虽小,五脏俱全就显得专业了。
  • 示例程序

  • #pragma once
    
    //CRT headers.
    #include <tchar.h>
    
    //windows platform headers.
    #include <Windows.h>
    //msi headers.
    #pragma comment(lib,"msi.lib")
    #include <Msi.h>
    #include <MsiQuery.h>
    
    INT APIENTRY _tWinMain(
    	HINSTANCE,
    	HINSTANCE,
    	LPTSTR,
    	INT)
    {
    	MSIHANDLE msiHandle=NULL;
    
    	//create msi database.
    	UINT openResult=MsiOpenDatabase(
    		_T("Setup.msi"),
    		MSIDBOPEN_CREATEDIRECT,
    		&msiHandle);
    
    	//create msil database failed.
    	if(openResult != ERROR_SUCCESS)
    	{
    		LPVOID formatMsg=NULL;
    
    		MSIHANDLE errorCode=MsiGetLastErrorRecord();
    
    		//format error code to string.
    		FormatMessage(
    		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    		NULL,
    		errorCode,
    		MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),
    		(LPTSTR)&formatMsg,
    		0,
    		NULL);
    
    		//output error message.
    		MessageBoxEx(
    			NULL,
    			(LPTSTR)formatMsg,
    			_T("tip window"),
    			MB_OK,
    			MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT));
    
    		//free message buffer.
    		LocalFree(formatMsg);
    
    		formatMsg=NULL;
    
    		return -1;
    	}
    
    	//commit msi database.
    	UINT commitResult=MsiDatabaseCommit(msiHandle);
    
    	if(commitResult != ERROR_SUCCESS)
    	{
    		LPVOID formatMsg=NULL;
    
    		MSIHANDLE errorCode=MsiGetLastErrorRecord();
    
    		//format error code to string.
    		FormatMessage(
    		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    		NULL,
    		errorCode,
    		MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),
    		(LPTSTR)&formatMsg,
    		0,
    		NULL);
    
    		//output error message.
    		MessageBoxEx(
    			NULL,
    			(LPTSTR)formatMsg,
    			_T("tip window"),
    			MB_OK,
    			MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT));
    
    		//free message buffer.
    		LocalFree(formatMsg);
    
    		formatMsg=NULL;
    
    		return -1;
    	}
    
    	//close msi database handle.
    	UINT closeResult=MsiCloseHandle(msiHandle);
    
    	if(closeResult != ERROR_SUCCESS)
    	{
    		LPVOID formatMsg=NULL;
    
    		MSIHANDLE errorCode=MsiGetLastErrorRecord();
    
    		//format error code to string.
    		FormatMessage(
    		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    		NULL,
    		errorCode,
    		MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),
    		(LPTSTR)&formatMsg,
    		0,
    		NULL);
    
    		//output error message.
    		MessageBoxEx(
    			NULL,
    			(LPTSTR)formatMsg,
    			_T("tip window"),
    			MB_OK,
    			MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT));
    
    		//free message buffer.
    		LocalFree(formatMsg);
    
    		formatMsg=NULL;
    
    		return -1;
    	}
    
    	return 0;
    }
    </span>
    
  • 结果展示

  • 总结

  • 现在我研究的还不是很明白,不过最终的目的就是自己编写的软件需要一个安装程序,这样子就看着专业一些了,总是绿色软件很是不甘心。



VC++ 创建msi文件

时间: 2024-12-19 07:51:03

VC++ 创建msi文件的相关文章

MSI文件的制作

1.历史 说到MSI文件,不得不先说说Windows Installer,它不只是安装程序,而是可扩展的软件管理系统. Windows Installer的用途包括:管理软件的安装.管理软件组件的添加和删除.监视文件的复原以及使用回滚技术维护基本的灾难恢复.另外, Windows Installer还支持从多个源位置安装和运行软件,而且可以由想要安装自定义程序的开发人员自定义.要想使用这些功能,就必须通过 MSI文件.MSI文件是Windows Installer的数据包,它实际上是一个数据库,

[转]VC++中对文件的写入和读取

本文转自:http://blog.csdn.net/fanghb_1984/article/details/7425705 本文介绍两种方法对文件进行读取和写入操作:1.采用fstream类:2.采用CStdioFile类. CStdioFile继承自CFile,一个CStdioFile对象代表一个用运行时函数fopen 打开的C 运行时流式文件. C++中的fstream类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O.stream类有两个重要的运算符:插入器(<<)和析

VC关于INI文件的操作

1.查看INI文件是否存在,不存在则创建INI文件 //查看是否有First.ini文件 CFileFind fd; if(fd.FindFile(".First.int")) { MessageBox("找到文件"); } else { MessageBox("没找到文件,创建文件"); CFile file; file.Open(".\First.int",CFile::modeCreate|CFile::modeWrit

vc++实现avi文件的操作

为了对avi进行读写,微软提供了一套API,总共50个函数,他们的用途主要有两类,一个是avi文件的操作,一类是数据流streams的操作. 1.打开和关闭文件 AVIFileOpen ,AVIFileAddRef, AVIFileRelease 2.从文件中读取文件信息 通过AVIFileInfo可以获取avi文件的一些信息,这个函数返回一个AVIFILEINFO结构,通过AVIFileReadData可以用来获取AVIFileInfo函数得不到的信息.这些信息也许不包含在文件的头部,比如拥有

VC++:创建,调用Win32动态链接库

VC++:创建,调用Win32动态链接库 概述 DLL(Dynamic Linkable Library)动态链接库,Dll可以看作一种仓库,仓库中包含了可以直接使用的变量,函数或类.仓库的发展史经历了"无库" ---> "静态链接库"  ---> "动态链接库".静态链接库与动态链接库都能实现共享代码,如果使用静态链接库,编译后lib中的指令会被包含在生成的EXE文件中,如果使用动态链接库,则不会被包含到EXE文件中,EXE文件执行

Linux安装vsftp:install: 无法创建普通文件“/usr/local/man/man8/vsftpd.8”:没有那个文件或目录

在编译模式中安装vsftpd时,出错:install:无法创建普通文件"/usr/local/man/man8/vsftpd.8":没有那个文件或目录 如下图 找到安装的目录,修改安装的配置文件MakeFIle,我的结构如下图 修改文件中的内容,在MakeFile中修改内容如下 修改成下面的代码 然后,再重新sudo make install一遍,就OK了

eclipse maven工程中src/main/resources目录下创建的文件夹是包图标的解决方法

如图:在src/main/resources目录下创建的文件夹却以包的图标显示  修改方法: 入下图,按顺序1 ,2,3,4操作,把3处remove,在4处添加**  修改后如下:  然后点击完成后,文件夹图标显示正常了 

Windows下使用创建多层文件夹 SHCreateDirectoryEx 函数需要注意的问题

1.在使用SHCreateDirectoryEx函数创建多层文件夹的过程中,发现在文件夹路径中,只能使用\\而不能使用/,否则将创建文件夹失败. 2.下面为在MFC中使用的代码片段 CString new_path = "C:/abc/d/e"; //SHCreateDirectoryEx函数必须使用\\,不能使用/ new_path.Replace("/", "\\"); //判断是否存在该文件夹 if (!PathIsDirectory(ne

创建日志文件并在该文件里添加内容

'创建日志文件并在该文件里添加内容 Sub writelog(log) Const forreading =1,forwriting =2,foraddpending=8 Dim fso,f Dim filepath filepath ="C:\log\log.txt" Set fso =createobject("scripting.filesystemobject") If fso.FileExists(filepath) = false Then Set f