在查找处理WIM,ESD文件的库,除了Wimgapi库还在找到一个开源库Wimlib处理WIM,ESD格式数据. Wimlib是一个开源的跨平台库,用于创建、提取和修改Windows映像(WIM)档案,Wimlib及其命令行前端Wimlib-imagex为微软提供免费的跨平台替代方案 Wimlib更适合在Linux环境下使用,测试时部分功能无法在Windows环境下使用。

目录导读

WIMLIB描述数据预处理获取镜像的相关信息导出指定系统中的文件获取镜像目录结构(装载/卸载镜像)提取镜像到指定目录注意

WIMLIB描述

wimlib是一个开源的跨平台库,用于创建、提取和修改Windows映像(WIM)档案。WIM是一种文件归档格式,有点类似于ZIP(和许多其他文件归档格式);但与ZIP不同的是,它允许存储各种特定于Windows的元数据,允许在单个归档中存储多个“映像”,自动对所有文件内容进行重复数据删除,并支持可选的固体压缩以获得更好的压缩比。wimlib及其命令行前端wimlib-imagex为微软提供免费的跨平台替代方案Wimgapi, ImageX,以及DISM.除其他外,Wimlib:

在Windows和类UNIX系统(如Mac OS X和Linux)上提供快速可靠的文件归档。允许非Windows操作系统的用户读写Windows映像(WIM)文件。支持在Windows风格的文件系统(如NTFS)上正确归档文件,而不会犯常见错误,如未正确处理ACL、文件属性、链接和命名数据流。允许从Linux等非Windows操作系统部署Windows操作系统。为多个应用程序提供独立、高质量的开源压缩器和解压缩器压缩格式由微软使用,不像更开放的格式那样广为人知,易于在不同的应用程序和文件格式中重用(不仅仅是WIM)。wimlib作为源tarball(适用于UNIX/Linux)或现成的二进制文件(适用于Windows XP和更高版本)分发。该软件由一个C库和wimlib-imagex命令行前端及其相关文档。 摘抄自官网:详见 [https://wimlib.net/]

数据预处理

通过github下载的wimlib-1.14.3-windows-x86_64-bin项目 将devel文件夹中的libwim.lib和wimlib.h添加到项目中,libwim-15.dll放在可执行程序同级目录中。 libwim.lib必须设置为完整路径

#include "devel/wimlib.h"

#pragma comment(lib,"E:\\data-bank\\Git\\Mirror_Image_READ\\Mirror_Image_DAL\\devel\\libwim.lib")

///进度条宏定义

#define TO_PERCENT(numerator, denominator) \

((float)(((denominator) == 0) ? 0 : ((numerator) * 100 / (float)(denominator))))

获取镜像的相关信息

wimlib库的使用和Wimgapi库基本差不多,参数这些一看就很明白,wimlib.h文件中也有参数说明,和所有的宏定义这些,但是: wimlib库在调用获取镜像XML信息时,与Wimgapi有点不一样,传递的是一个FILE * 指针。 wimlib_extract_xml_data 方法描述:

/**

* @ingroup G_wim_information

*

* Similar to wimlib_get_xml_data(), but the XML document will be written to the

* specified standard C FILE* instead of retrieved in an in-memory

* buffer.

*

* @return 0 on success; a ::wimlib_error_code value on failure. This may

* return any error code which can be returned by wimlib_get_xml_data() as well

* as the following error codes:

*

* @retval ::WIMLIB_ERR_WRITE

* Failed to write the data to the requested file.

*/

WIMLIBAPI int

wimlib_extract_xml_data(WIMStruct *wim, FILE *fp);

实际调用:

//实际调用

/*

* 唯一能解释这个问题:https://www.cnblogs.com/wsk3q/p/16964667.html

* 异常 expression:(_osfile(fh) &fopen)

FILE *fp=fopen("text.txt","at+");

if (fp == NULL) {

qDebug("无法打开文件...\n");

goto out;

}

// fprintf(_file, "%s", "data-dsadsa"); // 写入数据到文件

// fseek(_file,0L,SEEK_SET);

// G_wim_information

ret =wimlib_extract_xml_data(wim,fp);

if (ret != 0) // Always should check the error codes.

{

if(fp!=NULL)

fclose(fp);

goto out;

}

if(fp!=NULL)

fclose(fp);

*/

在做测试的时候,我FILE结构的所有打开方式都试了一遍,都愣是异常提示无法写入文件,最后找到唯一的解释就是:传递FILE*指针到dll里面之后引起异常 于是换了种方式改用 wimlib_get_wim_info方法获取WIM信息: wimlib_get_image_property 方法获取XML节点信息;

/**

* @ingroup G_wim_information

*

* Get basic information about a WIM file.

*

* @param wim

* Pointer to the ::WIMStruct to query. This need not represent a

* standalone WIM (e.g. it could represent part of a split WIM).

* @param info

* A ::wimlib_wim_info structure that will be filled in with information

* about the WIM file.

*

* @return 0

*/

WIMLIBAPI int

wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info);

/**

* @ingroup G_wim_information

*

* Since wimlib v1.8.3: get a per-image property from the WIM's XML document.

* This is an alternative to wimlib_get_image_name() and

* wimlib_get_image_description() which allows getting any simple string

* property.

*

* @param wim

* Pointer to the ::WIMStruct for the WIM.

* @param image

* The 1-based index of the image for which to get the property.

* @param property_name

* The name of the image property, for example "NAME", "DESCRIPTION", or

* "TOTALBYTES". The name can contain forward slashes to indicate a nested

* XML element; for example, "WINDOWS/VERSION/BUILD" indicates the BUILD

* element nested within the VERSION element nested within the WINDOWS

* element. Since wimlib v1.9.0, a bracketed number can be used to

* indicate one of several identically-named elements; for example,

* "WINDOWS/LANGUAGES/LANGUAGE[2]" indicates the second "LANGUAGE" element

* nested within the "WINDOWS/LANGUAGES" element. Note that element names

* are case sensitive.

*

* @return

* The property's value as a ::wimlib_tchar string, or @c NULL if there is

* no such property. The string may not remain valid after later library

* calls, so the caller should duplicate it if needed.

*/

WIMLIBAPI const wimlib_tchar *

wimlib_get_image_property(const WIMStruct *wim, int image,

const wimlib_tchar *property_name);

完整调用:

int ret=0;

WIMStruct *wim = NULL;

wimlib_wim_info *info=new wimlib_wim_info;

//QString Image_path; wim镜像路径

wchar_t* wimage=_utf8_to_wchar(Image_path.toStdString().c_str());

/* Open the WIM file as a WIMStruct. */

ret = wimlib_open_wim(wimage, /* Path of WIM file to open */

0, /* WIMLIB_OPEN_FLAG_* flags (0 means all defaults) */

&wim); /* Return the WIMStruct pointer in this location */

if (ret != 0) /* Always should check the error codes. */

goto out;

//通过wimlib_wim_info结构获取信息

//Get basic information about a WIM file.

ret =wimlib_get_wim_info(wim, info);

if (ret != 0) /* Always should check the error codes. */

goto out;

qDebug()<<"[image_count] "<image_count;

qDebug()<<"[boot_index] "<boot_index;

qDebug()<<"[wim_version] "<wim_version;

//!读取镜像属性 实际上就是读取xml文件结构数据

/*

for(int i=1;i<=info->image_count;i++)

{

XML_Wim_Version item_version;

item_version.Index=i;

item_version.DISPLAYNAME=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"DISPLAYNAME"));

QString image_size=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"TOTALBYTES"));

item_version.ISOSIZE=image_size.toDouble()!=0?(QString::number(image_size.toDouble()/MB,'f',1)+"MB"):"???";

item_version.MAJOR=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/VERSION/MAJOR"));

item_version.MINOR=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/VERSION/MINOR"));

item_version.BUILD=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/VERSION/BUILD"));

item_version.SPBUILD=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/VERSION/SPBUILD"));

item_version.PRODUCTTYPE=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/PRODUCTTYPE"));

item_version.VERSION=WINVERSION(item_version.PRODUCTTYPE,QString("%1.%2.%3.%4").arg(item_version.MAJOR).arg(item_version.MINOR).arg(item_version.BUILD).arg(item_version.SPBUILD));

item_version.FILECOUNT=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"FILECOUNT"));

item_version.DIRCOUNT=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"DIRCOUNT"));

Versions.append(item_version);

}

*/

//系统版本数量

//int Image_Count=Versions.count();

out:

/* Free the WIMStruct. Has no effect if the pointer to it is NULL. */

wimlib_free(wim);

/* Check for error status. */

if (ret != 0) {

qDebug()<<"wimlib error : "<

}

/* Free global memory (optional). */

wimlib_global_cleanup();

free(wimage);

Wimlib库自带异常捕获,能通过wimlib_get_error_string 完整获取错误信息。 在测试的时候,部分信息不完整的WIM文件无法通过wimlib_open_wim方法打开,暂时无解。

导出指定系统中的文件

可通过wimlib_extract_paths 导出指定系统版本中的文件, wimlib_extract_paths 函数说明:

/**

* @ingroup G_extracting_wims

*

* Extract zero or more paths (files or directory trees) from the specified WIM

* image.

*

* By default, each path will be extracted to a corresponding subdirectory of

* the target based on its location in the image. For example, if one of the

* paths to extract is /Windows/explorer.exe and the target is

* outdir, the file will be extracted to

* outdir/Windows/explorer.exe. This behavior can be changed by

* providing the flag ::WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE, which

* will cause each file or directory tree to be placed directly in the target

* directory --- so the same example would extract /Windows/explorer.exe

* to outdir/explorer.exe.

*

* With globbing turned off (the default), paths are always checked for

* existence strictly; that is, if any path to extract does not exist in the

* image, then nothing is extracted and the function fails with

* ::WIMLIB_ERR_PATH_DOES_NOT_EXIST. But with globbing turned on

* (::WIMLIB_EXTRACT_FLAG_GLOB_PATHS specified), globs are by default permitted

* to match no files, and there is a flag (::WIMLIB_EXTRACT_FLAG_STRICT_GLOB) to

* enable the strict behavior if desired.

*

* Symbolic links are not dereferenced when paths in the image are interpreted.

*

* @param wim

* WIM from which to extract the paths, specified as a pointer to the

* ::WIMStruct for a standalone WIM file, a delta WIM file, or part 1 of a

* split WIM. In the case of a WIM file that is not standalone, this

* ::WIMStruct must have had any needed external resources previously

* referenced using wimlib_reference_resources() or

* wimlib_reference_resource_files().

* @param image

* The 1-based index of the WIM image from which to extract the paths.

* @param paths

* Array of paths to extract. Each element must be the absolute path to a

* file or directory within the image. Path separators may be either

* forwards or backwards slashes, and leading path separators are optional.

* The paths will be interpreted either case-sensitively (UNIX default) or

* case-insensitively (Windows default); however, the case sensitivity can

* be configured explicitly at library initialization time by passing an

* appropriate flag to wimlib_global_init().

*

* By default, "globbing" is disabled, so the characters @c * and @c ? are

* interpreted literally. This can be changed by specifying

* ::WIMLIB_EXTRACT_FLAG_GLOB_PATHS in @p extract_flags.

* @param num_paths

* Number of paths specified in @p paths.

* @param target

* Directory to which to extract the paths.

* @param extract_flags

* Bitwise OR of flags prefixed with WIMLIB_EXTRACT_FLAG.

*

* @return 0 on success; a ::wimlib_error_code value on failure. Most of the

* error codes are the same as those returned by wimlib_extract_image(). Below,

* some of the error codes returned in situations specific to path-mode

* extraction are documented:

*

* @retval ::WIMLIB_ERR_NOT_A_REGULAR_FILE

* ::WIMLIB_EXTRACT_FLAG_TO_STDOUT was specified in @p extract_flags, but

* one of the paths to extract did not name a regular file.

* @retval ::WIMLIB_ERR_PATH_DOES_NOT_EXIST

* One of the paths to extract does not exist in the image; see discussion

* above about strict vs. non-strict behavior.

*

* If a progress function is registered with @p wim, then it will receive

* ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS.

*/

WIMLIBAPI int

wimlib_extract_paths(WIMStruct *wim,

int image,

const wimlib_tchar *target,

const wimlib_tchar * const *paths,

size_t num_paths,

int extract_flags);

获取镜像目录结构(装载/卸载镜像)

挂载WIM映像(仅限Linux); 这是在我测试的时候,把装载/卸载方法写完,调用失败查找官方文档才发现的问题… wimlib_mount_image 装载函数: wimlib_unmount_image 卸载函数:

/**

* @ingroup G_mounting_wim_images

*

* Mount an image from a WIM file on a directory read-only or read-write.

*

* @param wim

* Pointer to the ::WIMStruct containing the image to be mounted. This

* ::WIMStruct must have a backing file.

* @param image

* The 1-based index of the image to mount. This image cannot have been

* previously modified in memory.

* @param dir

* The path to an existing empty directory on which to mount the image.

* @param mount_flags

* Bitwise OR of flags prefixed with WIMLIB_MOUNT_FLAG. Use

* ::WIMLIB_MOUNT_FLAG_READWRITE to request a read-write mount instead of a

* read-only mount.

* @param staging_dir

* If non-NULL, the name of a directory in which a temporary directory for

* storing modified or added files will be created. Ignored if

* ::WIMLIB_MOUNT_FLAG_READWRITE is not specified in @p mount_flags. If

* left @c NULL, the staging directory is created in the same directory as

* the backing WIM file. The staging directory is automatically deleted

* when the image is unmounted.

*

* @return 0 on success; a ::wimlib_error_code value on failure.

*

* @retval ::WIMLIB_ERR_ALREADY_LOCKED

* Another process is currently modifying the WIM file.

* @retval ::WIMLIB_ERR_FUSE

* A non-zero status code was returned by @c fuse_main().

* @retval ::WIMLIB_ERR_IMAGE_HAS_MULTIPLE_REFERENCES

* There are currently multiple references to the image as a result of a

* call to wimlib_export_image(). Free one before attempting the

* read-write mount.

* @retval ::WIMLIB_ERR_INVALID_IMAGE

* @p image does not exist in @p wim.

* @retval ::WIMLIB_ERR_INVALID_PARAM

* @p wim was @c NULL; or @p dir was NULL or an empty string; or an

* unrecognized flag was specified in @p mount_flags; or the image has

* already been modified in memory (e.g. by wimlib_update_image()).

* @retval ::WIMLIB_ERR_MKDIR

* ::WIMLIB_MOUNT_FLAG_READWRITE was specified in @p mount_flags, but the

* staging directory could not be created.

* @retval ::WIMLIB_ERR_WIM_IS_READONLY

* ::WIMLIB_MOUNT_FLAG_READWRITE was specified in @p mount_flags, but the

* WIM file is considered read-only because of any of the reasons mentioned

* in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag.

* @retval ::WIMLIB_ERR_UNSUPPORTED

* Mounting is not supported in this build of the library.

*

* This function can additionally return ::WIMLIB_ERR_DECOMPRESSION,

* ::WIMLIB_ERR_INVALID_METADATA_RESOURCE, ::WIMLIB_ERR_METADATA_NOT_FOUND,

* ::WIMLIB_ERR_READ, or ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE, all of which

* indicate failure (for different reasons) to read the metadata resource for

* the image to mount.

*

* The ability to mount WIM images is implemented using FUSE (Filesystem in

* UserSpacE). Depending on how FUSE is set up on your system, this function

* may work as normal users in addition to the root user.

*

* Mounting WIM images is not supported if wimlib was configured

* --without-fuse. This includes Windows builds of wimlib;

* ::WIMLIB_ERR_UNSUPPORTED will be returned in such cases.

*

* Calling this function daemonizes the process, unless

* ::WIMLIB_MOUNT_FLAG_DEBUG was specified or an early error occurs.

*

* It is safe to mount multiple images from the same WIM file read-only at the

* same time, but only if different ::WIMStruct's are used. It is @b not safe

* to mount multiple images from the same WIM file read-write at the same time.

*

* To unmount the image, call wimlib_unmount_image(). This may be done in a

* different process.

*/

WIMLIBAPI int

wimlib_mount_image(WIMStruct *wim,

int image,

const wimlib_tchar *dir,

int mount_flags,

const wimlib_tchar *staging_dir);

/**

* @ingroup G_mounting_wim_images

*

* Unmount a WIM image that was mounted using wimlib_mount_image().

*

* When unmounting a read-write mounted image, the default behavior is to

* discard changes to the image. Use ::WIMLIB_UNMOUNT_FLAG_COMMIT to cause the

* image to be committed.

*

* @param dir

* The directory on which the WIM image is mounted.

* @param unmount_flags

* Bitwise OR of flags prefixed with @p WIMLIB_UNMOUNT_FLAG.

*

* @return 0 on success; a ::wimlib_error_code value on failure.

*

* @retval ::WIMLIB_ERR_NOT_A_MOUNTPOINT

* There is no WIM image mounted on the specified directory.

* @retval ::WIMLIB_ERR_MOUNTED_IMAGE_IS_BUSY

* The read-write mounted image cannot be committed because there are file

* descriptors open to it, and ::WIMLIB_UNMOUNT_FLAG_FORCE was not

* specified.

* @retval ::WIMLIB_ERR_MQUEUE

* Could not create a POSIX message queue.

* @retval ::WIMLIB_ERR_NOT_PERMITTED_TO_UNMOUNT

* The image was mounted by a different user.

* @retval ::WIMLIB_ERR_UNSUPPORTED

* Mounting is not supported in this build of the library.

*

* Note: you can also unmount the image by using the @c umount() system call, or

* by using the @c umount or @c fusermount programs. However, you need to call

* this function if you want changes to be committed.

*/

WIMLIBAPI int

wimlib_unmount_image(const wimlib_tchar *dir, int unmount_flags);

调用示例,建议Linux环境下测试,Windows环境下不支持:

int WIM_INDEX=qMin(qMax(1,index.toInt()),Image_Count);

wchar_t* wimage;

int ret=0;

WIMStruct *wim = NULL;

// wchar_t* wtemp=tempObj.GetTempDirU();

wchar_t* wtemp=_utf8_to_wchar(QString("C:\\Users\\admin\\Desktop\\textxml\\text").toStdString().c_str());

QDir tempMountDir(QString::fromWCharArray(wtemp)+"\\TempMount_WIMLIB");

if(!tempMountDir.exists())

tempMountDir.mkpath(QString::fromWCharArray(wtemp)+"\\TempMount_WIMLIB");

wchar_t* wdst=_utf8_to_wchar(QString(QString::fromWCharArray(wtemp)+"\\TempMount_WIMLIB").toStdString().c_str());

//TempFile 挂载路径

QString TempFile=QString::fromWCharArray(wdst);

qDebug()<<"[TempFile] "<

//Image_path 镜像路径

wimage=_utf8_to_wchar(Image_path.toStdString().c_str());

/* Open the WIM file as a WIMStruct. */

ret = wimlib_open_wim(wimage, /* Path of WIM file to open */

0, /* WIMLIB_OPEN_FLAG_* flags (0 means all defaults) */

&wim); /* Return the WIMStruct pointer in this location */

if (ret != 0) /* Always should check the error codes. */

goto out;

//WIMLIB_MOUNT_FLAG_READWRITE

//WIMLIB_MOUNT_FLAG_DEBUG

//WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_NONE

//WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR

//WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS

//WIMLIB_MOUNT_FLAG_UNIX_DATA

//WIMLIB_MOUNT_FLAG_ALLOW_OTHER

ret=wimlib_mount_image(wim,WIM_INDEX,wdst,0,L"");

if (ret != 0) /* Always should check the error codes. */

{

goto out;

}

//遍历目录结构

//Lib_Deploy_Environment::getInstance().EnumerateFiles(TempFile,Fetch_Files);

//! 如果需要对镜像镜像修改 可以在此处操作文件目录/文件 然后提交保存

//!WIMLIB_UNMOUNT_FLAG_COMMIT 保存装载后的更改!

//WIMLIB_UNMOUNT_FLAG_CHECK_INTEGRITY

//WIMLIB_UNMOUNT_FLAG_COMMIT

//WIMLIB_UNMOUNT_FLAG_REBUILD

//WIMLIB_UNMOUNT_FLAG_RECOMPRESS

//WIMLIB_UNMOUNT_FLAG_FORCE

//WIMLIB_UNMOUNT_FLAG_NEW_IMAGE

//不提交修改

ret=wimlib_unmount_image(wdst, 0);

if (ret != 0) /* Always should check the error codes. */

{

goto out;

}

out:

/* Free the WIMStruct. Has no effect if the pointer to it is NULL. */

wimlib_free(wim);

/* Check for error status. */

if (ret != 0) {

qDebug()<<"wimlib error : "<

}

/* Free global memory (optional). */

wimlib_global_cleanup();

提取镜像到指定目录

WIMLIB通过wimlib_extract_image函数提取镜像。 也可通过wimlib_register_progress_function设置回调函数直接获取进度。

/**

* @ingroup G_general

*

* Register a progress function with a ::WIMStruct.

*

* @param wim

* The ::WIMStruct for which to register the progress function.

* @param progfunc

* Pointer to the progress function to register. If the WIM already has a

* progress function registered, it will be replaced with this one. If @p

* NULL, the current progress function (if any) will be unregistered.

* @param progctx

* The value which will be passed as the third argument to calls to @p

* progfunc.

*/

WIMLIBAPI void

wimlib_register_progress_function(WIMStruct *wim,

wimlib_progress_func_t progfunc,

void *progctx);

/**

* @ingroup G_extracting_wims

*

* Extract an image, or all images, from a ::WIMStruct.

*

* The exact behavior of how wimlib extracts files from a WIM image is

* controllable by the @p extract_flags parameter, but there also are

* differences depending on the platform (UNIX-like vs Windows). See the

* documentation for wimapply for more information, including about the

* NTFS-3G extraction mode.

*

* @param wim

* The WIM from which to extract the image(s), specified as a pointer to the

* ::WIMStruct for a standalone WIM file, a delta WIM file, or part 1 of a

* split WIM. In the case of a WIM file that is not standalone, this

* ::WIMStruct must have had any needed external resources previously

* referenced using wimlib_reference_resources() or

* wimlib_reference_resource_files().

* @param image

* The 1-based index of the image to extract, or ::WIMLIB_ALL_IMAGES to

* extract all images. Note: ::WIMLIB_ALL_IMAGES is unsupported in NTFS-3G

* extraction mode.

* @param target

* A null-terminated string which names the location to which the image(s)

* will be extracted. By default, this is interpreted as a path to a

* directory. Alternatively, if ::WIMLIB_EXTRACT_FLAG_NTFS is specified in

* @p extract_flags, then this is interpreted as a path to an unmounted

* NTFS volume.

* @param extract_flags

* Bitwise OR of flags prefixed with WIMLIB_EXTRACT_FLAG.

*

* @return 0 on success; a ::wimlib_error_code value on failure.

*

* @retval ::WIMLIB_ERR_DECOMPRESSION

* The WIM file contains invalid compressed data.

* @retval ::WIMLIB_ERR_INVALID_IMAGE

* @p image does not exist in @p wim.

* @retval ::WIMLIB_ERR_INVALID_METADATA_RESOURCE

* The metadata for an image to extract was invalid.

* @retval ::WIMLIB_ERR_INVALID_PARAM

* The extraction flags were invalid; more details may be found in the

* documentation for the specific extraction flags that were specified. Or

* @p target was @c NULL or an empty string, or @p wim was @c NULL.

* @retval ::WIMLIB_ERR_INVALID_RESOURCE_HASH

* The data of a file that needed to be extracted was corrupt.

* @retval ::WIMLIB_ERR_LINK

* Failed to create a symbolic link or a hard link.

* @retval ::WIMLIB_ERR_METADATA_NOT_FOUND

* @p wim does not contain image metadata; for example, it represents a

* non-first part of a split WIM.

* @retval ::WIMLIB_ERR_MKDIR

* Failed create a directory.

* @retval ::WIMLIB_ERR_NTFS_3G

* libntfs-3g reported that a problem occurred while writing to the NTFS

* volume.

* @retval ::WIMLIB_ERR_OPEN

* Could not create a file, or failed to open an already-extracted file.

* @retval ::WIMLIB_ERR_READ

* Failed to read data from the WIM.

* @retval ::WIMLIB_ERR_READLINK

* Failed to determine the target of a symbolic link in the WIM.

* @retval ::WIMLIB_ERR_REPARSE_POINT_FIXUP_FAILED

* Failed to fix the target of an absolute symbolic link (e.g. if the

* target would have exceeded the maximum allowed length). (Only if

* reparse data was supported by the extraction mode and

* ::WIMLIB_EXTRACT_FLAG_STRICT_SYMLINKS was specified in @p

* extract_flags.)

* @retval ::WIMLIB_ERR_RESOURCE_NOT_FOUND

* A file data blob that needed to be extracted could not be found in the

* blob lookup table of @p wim. See @ref G_nonstandalone_wims.

* @retval ::WIMLIB_ERR_SET_ATTRIBUTES

* Failed to set attributes on a file.

* @retval ::WIMLIB_ERR_SET_REPARSE_DATA

* Failed to set reparse data on a file (only if reparse data was supported

* by the extraction mode).

* @retval ::WIMLIB_ERR_SET_SECURITY

* Failed to set security descriptor on a file.

* @retval ::WIMLIB_ERR_SET_SHORT_NAME

* Failed to set the short name of a file.

* @retval ::WIMLIB_ERR_SET_TIMESTAMPS

* Failed to set timestamps on a file.

* @retval ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE

* Unexpected end-of-file occurred when reading data from the WIM.

* @retval ::WIMLIB_ERR_UNSUPPORTED

* A requested extraction flag, or the data or metadata that must be

* extracted to support it, is unsupported in the build and configuration

* of wimlib, or on the current platform or extraction mode or target

* volume. Flags affected by this include ::WIMLIB_EXTRACT_FLAG_NTFS,

* ::WIMLIB_EXTRACT_FLAG_UNIX_DATA, ::WIMLIB_EXTRACT_FLAG_STRICT_ACLS,

* ::WIMLIB_EXTRACT_FLAG_STRICT_SHORT_NAMES,

* ::WIMLIB_EXTRACT_FLAG_STRICT_TIMESTAMPS, and

* ::WIMLIB_EXTRACT_FLAG_STRICT_SYMLINKS. For example, if

* ::WIMLIB_EXTRACT_FLAG_STRICT_SHORT_NAMES is specified in @p

* extract_flags, ::WIMLIB_ERR_UNSUPPORTED will be returned if the WIM

* image contains one or more files with short names, but extracting short

* names is not supported --- on Windows, this occurs if the target volume

* does not support short names, while on non-Windows, this occurs if

* ::WIMLIB_EXTRACT_FLAG_NTFS was not specified in @p extract_flags.

* @retval ::WIMLIB_ERR_WIMBOOT

* ::WIMLIB_EXTRACT_FLAG_WIMBOOT was specified in @p extract_flags, but

* there was a problem creating WIMBoot pointer files or registering a

* source WIM file with the Windows Overlay Filesystem (WOF) driver.

* @retval ::WIMLIB_ERR_WRITE

* Failed to write data to a file being extracted.

*

* If a progress function is registered with @p wim, then as each image is

* extracted it will receive ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN, then

* zero or more ::WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE messages, then zero

* or more ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS messages, then zero or more

* ::WIMLIB_PROGRESS_MSG_EXTRACT_METADATA messages, then

* ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END.

*/

WIMLIBAPI int

wimlib_extract_image(WIMStruct *wim, int image,

const wimlib_tchar *target, int extract_flags);

调用示例:

enum wimlib_progress_status extract_progress(enum wimlib_progress_msg msg,

union wimlib_progress_info *info, void *progctx)

{

switch (msg) {

case WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS:

qDebug("Extracting files: %.2f%% complete\n",

TO_PERCENT(info->extract.completed_bytes,

info->extract.total_bytes));

break;

default:

break;

}

return WIMLIB_PROGRESS_STATUS_CONTINUE;

}

void Export_WIM(QString Imagepath,int index,QString descpath)

{

//QString Imagepath; 镜像路径

wchar_t* wimage=_utf8_to_wchar(Imagepath.toStdString().c_str());

//QString descpath;输出目录

wchar_t* wdst=_utf8_to_wchar(descpath.toStdString().c_str());

int ret=0;

WIMStruct *wim = NULL;

/* Open the WIM file as a WIMStruct. */

ret = wimlib_open_wim(wimage, /* Path of WIM file to open */

0, /* WIMLIB_OPEN_FLAG_* flags (0 means all defaults) */

&wim); /* Return the WIMStruct pointer in this location */

if (ret != 0) /* Always should check the error codes. */

goto out;

/* Register our progress function. */

wimlib_register_progress_function(wim, extract_progress, NULL);

/* Extract the first image. */

ret = wimlib_extract_image(wim, /* WIMStruct from which to extract the image */

index, /* Image to extract */

wdst, /* Directory to extract the image to */

0); /* WIMLIB_EXTRACT_FLAG_* flags (0 means all defaults) */

if (ret != 0) /* Always should check the error codes. */

goto out;

out:

/* Free the WIMStruct. Has no effect if the pointer to it is NULL. */

wimlib_free(wim);

/* Check for error status. */

if (ret != 0) {

QString Error=QString::fromWCharArray(wimlib_get_error_string((enum wimlib_error_code)ret));

qDebug()<<"wimlib error : "<

}

/* Free global memory (optional). */

wimlib_global_cleanup();

free(wimage);

free(wdst);

}

注意

Wimlib库在Window环境下不如WIMGAPI库好用(个人感觉);Windows环境建议使用WIMGAPI开发,Linux环境建议使用Wimlib,实在不想这么麻烦,通过QProcess调用cmd执行wimlib-imagex.exe命令行的方式也很不错。Wimlib库函数的调用可以参考 https://github-wiki-see.page/m/openthos/openthos/wiki/wimlib-analysis 中的说明(中文版),包括一些函数的使用规范,宏定义都有说明。在Gitbit上有一个wimlib-master项目,具体链接丢了, 可以查看examples文件夹中的各种示例文件: applywim.c capturewim.c compressfile.c decompressfile.c updatewim.c

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。