Legolash2o Posted March 30, 2011 Posted March 30, 2011 (edited) Hello, i was wondering if any knows the c# code to mount an image and display its progress (%) in text form i.e. "Mounting 3% Complete").I can mount the image fine but i can't get it to display it's progress. I will display below what code i have...Thanks,much appreciated! WIMMountImage("C:\\Mount", "D:\\Win7SP1\\sources\\boot.wim", 1, "C:\\MountTemp"); Edited March 30, 2011 by Legolash2o
The Glimmerman Posted July 14, 2012 Posted July 14, 2012 (edited) I know this is a old post but I have the same problem, code to display its progress (%) in text form i.e. "Mounting 3% Complete").I hate the waiting so I am making my own RT7 Lite clone ( Wim Customizer ).I searched the internet for examples or code for CopyProgressRoutine or WIMMessageCallbackbut cannot find anything.I hope that some one (post date a year later) can help me out.Maybe you have found the solution Legolash20 and can post it here. For the people interested my wingapi wrapperusing System;using System.Runtime.InteropServices;using System.Collections;using System.Globalization;using System.Text;using System.IO;using System.Xml;namespace WIMAPI{ public class WimApi { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct _WIM_INFO { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string WimPath; public Guid Guid; public Int32 ImageCount; public Int32 CompressionType; public Int16 PartNumber; public Int16 TotalParts; public Int32 BootIndex; public Int32 WimAttributes; public Int32 WimFlagsAndAttr; } public struct _WIM_MOUNT_LIST { public string WimPath; public string MountPath; public Int64 ImageIndex; public Int64 MountedForRW; } public const uint WIM_DELETE_MOUNTS_ALL = 0x00000001; public const uint WIM_GENERIC_READ = 0X80000000; public const uint WIM_GENERIC_WRITE = 0X40000000; public const int WIM_CREATE_NEW = 1; public const int WIM_CREATE_ALWAYS = 2; public const int WIM_OPEN_EXISTING = 3; public const int WIM_OPEN_ALWAYS = 4; public const int WIM_COMPRESS_NONE = 0; public const int WIM_COMPRESS_XPRESS = 1; public const int WIM_COMPRESS_LZX = 2; public const int WIM_CREATED_NEW = 0; public const int WIM_OPENED_EXISTING = 1; public const int WIM_FLAG_RESERVED = 0x00000001; public const int WIM_FLAG_VERIFY = 0x00000002; public const int WIM_FLAG_INDEX = 0x00000004; public const int WIM_FLAG_NO_APPLY = 0x00000008; public const int WIM_FLAG_NO_DIRACL = 0x00000010; public const int WIM_FLAG_NO_FILEACL = 0x00000020; public const int WIM_FLAG_SHARE_WRITE = 0x00000040; public const int WIM_FLAG_FILEINFO = 0x00000080; public const int WIM_FLAG_NO_RP_FIX = 0x00000100; public const int WIM_REFERENCE_APPEND = 0x00010000; public const int WIM_REFERENCE_REPLACE = 0x00020000; // WIMExportImage public const int WIM_EXPORT_ALLOW_DUPLICATES = 0x00000001; public const int WIM_EXPORT_ONLY_RESOURCES = 0x00000002; public const int WIM_EXPORT_ONLY_METADATA = 0x00000004; // WIMRegisterMessageCallback: public const uint INVALID_CALLBACK_VALUE = 0xFFFFFFFF; public const int WIM_COPY_FILE_RETRY = 0x01000000; public const int COPY_FILE_FAIL_IF_EXISTS = 0x00000001; public const int WM_APP = 0x8000; public const int WIM_MSG = WM_APP + 0x1476; public const int WIM_MSG_TEXT = WM_APP + 0x1477; public const int WIM_MSG_PROGRESS = WM_APP + 0x1478; public const int WIM_MSG_PROCESS = WM_APP + 0x1479; public const int WIM_MSG_SCANNING = WM_APP + 0x147A; public const int WIM_MSG_SETRANGE = WM_APP + 0x147b; public const int WIM_MSG_SETPOS = WM_APP + 0x147c; public const int WIM_MSG_STEPIT = WM_APP + 0x147d; public const int WIM_MSG_COMPRESS = WM_APP + 0x147e; public const int WIM_MSG_ERROR = WM_APP + 0x147f; public const int WIM_MSG_ALIGNMENT = WM_APP + 1480; public const int WIM_MSG_RETRY = WM_APP + 1481; public const int WIM_MSG_SPLIT = WM_APP + 1482; public const int WIM_MSG_FILEINFO = WM_APP + 1483; public const int WIM_MSG_INFO = WM_APP + 1483; public const int WIM_MSG_WARNING = WM_APP + 1484; public const int WIM_MSG_CHK_PROCESS = WM_APP + 1485; public const int WIM_MSG_SUCCESS = 0x0; public const uint WIM_MSG_DONE = 0xFFFFFFF0; public const uint WIM_MSG_SKIP_ERROR = 0xFFFFFFFE; public const uint WIM_MSG_ABORT_IMAGE = 0xFFFFFFFF; public const int WIM_ATTRIBUTE_NORMAL = 0x00000000; public const int WIM_ATTRIBUTE_RESOURCE_ONLY = 0x00000001; public const int WIM_ATTRIBUTE_METADATA_ONLY = 0x00000002; public const int WIM_ATTRIBUTE_VERIFY_DATA = 0x00000004; public const int WIM_ATTRIBUTE_RP_FIX = 0x00000008; public const int WIM_ATTRIBUTE_SPANNED = 0x00000010; public const int WIM_ATTRIBUTE_READONLY = 0x00000020; public const string WIM_XML_NODE_NAME = "NAME"; public const string WIM_XML_NODE_WIM = "WIM"; public const string WIM_XML_NODE_WINDOWS = "WINDOWS"; public const string WIM_XML_NODE_VERSION = "VERSION"; public const string WIM_XML_NODE_MAJOR = "MAJOR"; public const string WIM_XML_NODE_MINOR = "MINOR"; public const string WIM_XML_NODE_BUILD = "BUILD"; public const string WIM_XML_NODE_SPBUILD = "SPBUILD"; /*************************DllImport Attributes ********************************************* * CallingConvention - Specifies the calling convention to use in passing method arguments.* * The default is WinAPI, which corresponds to __stdcall * * for the 32-bit Intel-based platforms. * * EntryPoint - Specifies the DLL entry point to be called. * * SetLastError - Enables the caller to use the Marshal.GetLastWin32Error API * * function to determine whether an error occurred while * * executing the method. In Visual Basic, the default is true; * * in C# and C++, the default is false. * ********************************************************************************************/ // WIMCreateFile - Makes a new image file or opens an existing image file. [DllImport("wimgapi.dll", EntryPoint = "WIMCreateFile", SetLastError = true)] public static extern IntPtr WIMCreateFile( [MarshalAs(UnmanagedType.LPWStr)] string lpszWimPath, UInt32 dwDesiredAccess, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, Int32 dwCompressionType, out Int32 lpdwCreationResult ); // WIMApplyImage - Applies an image to a directory path from a Windows image (.wim) file. [DllImport("wimgapi.dll", EntryPoint = "WIMApplyImage", SetLastError = true)] public static extern int WIMApplyImage( IntPtr hImage, [MarshalAs(UnmanagedType.LPWStr)] string lpszPath, Int32 dwApplyFlags ); // WIMCaptureImage - Captures an image from a directory path and stores it in an image file. [DllImport("wimgapi.dll", EntryPoint = "WIMCaptureImage", SetLastError = true)] public static extern IntPtr WIMCaptureImage( IntPtr hWim, [MarshalAs(UnmanagedType.LPWStr)] string lpszPath, Int32 dwApplyFlags ); // WIMCloseHandle - Closes an open Windows Imaging (.wim) file or image handle. [DllImport("wimgapi.dll", EntryPoint = "WIMCloseHandle", SetLastError = true)] public static extern int WIMCloseHandle( IntPtr hObject ); // WIMDeleteImage - Removes an image from within a .wim (Windows image) file // so it cannot be accessed. However, the file resources // are still available for use by the WIMSetReferenceFile function. [DllImport("wimgapi.dll", EntryPoint = "WIMDeleteImage", SetLastError = true)] public static extern int WIMDeleteImage( IntPtr hWim, Int32 dwApplyFlags ); // WIMExportImage - Transfers the data of an image from one Windows image (.wim) // file to another. [DllImport("wimgapi.dll", EntryPoint = "WIMExportImage", SetLastError = true)] public static extern int WIMExportImage( IntPtr hImage, IntPtr hWim, Int32 dwApplyFlags ); // WIMGetAttributes - Returns the information about the .wim file. [DllImport("wimgapi.dll", EntryPoint = "WIMGetAttributes", SetLastError = true)] public static extern int WIMGetAttributes( IntPtr hWim, ref _WIM_INFO lpWimInfo, Int32 cbWimInfo ); // WIMGetImageCount - Returns the number of volume images stored in a Windows image (.wim) file. [DllImport("wimgapi.dll", EntryPoint = "WIMGetImageCount", SetLastError = true)] public static extern Int32 WIMGetImageCount( IntPtr hwim ); // WIMGetMessageCallbackCount - Returns the count of callback routines currently registered by the imaging library. [DllImport("wimgapi.dll", EntryPoint = "WIMGetMessagecallbackCount", SetLastError = true)] public static extern Int32 WIMGetMessagecallbackCount( IntPtr hwim ); // WIMLoadImage - Loads a volume image from a Windows image (.wim) file. [DllImport("wimgapi.dll", EntryPoint = "WIMLoadImage", SetLastError = true)] public static extern IntPtr WIMLoadImage( IntPtr hwim, Int32 dwImageIndex ); // WIMSetBootImage - Marks the image with the given image index as bootable. [DllImport("wimgapi.dll", EntryPoint = "WIMSetBootImage", SetLastError = true)] public static extern int WIMSetBootImage( IntPtr hwim, Int32 dwImageIndex ); // WIMSetReferenceFile - Enables the WIMApplyImage and WIMCaptureImage // functions to use alternate .wim files for file // resources. This can enable optimization of storage // when multiple images are captured with similar data. [DllImport("wimgapi.dll", EntryPoint = "WIMSetReferenceFile", SetLastError = true)] public static extern int WIMSetReferenceFile( IntPtr hwim, [MarshalAs(UnmanagedType.LPWStr)] string lpszPath, Int32 dwFlags ); // WIMSplitFile - Enables a large Windows image (.wim) file to be split // into smaller parts for replication or storage on smaller forms of media. [DllImport("wimgapi.dll", EntryPoint = "WIMSplitFile", SetLastError = true)] public static extern int WIMSplitFile( IntPtr hwim, [MarshalAs(UnmanagedType.LPWStr)] string lpszPartPath, out Int64 pliPartSize, Int32 dwFlags ); // WIMMountImage - Mounts an image in a Windows image (.wim) file to the specified directory. [DllImport("wimgapi.dll", EntryPoint = "WIMMountImage", SetLastError = true)] public static extern bool WIMMountImage( [MarshalAs(UnmanagedType.LPWStr)] string lpszMountPath, [MarshalAs(UnmanagedType.LPWStr)] string lpszWimFileName, Int32 dwImageIndex, [Optional] [MarshalAs(UnmanagedType.LPWStr)] string lpszTempPath ); // WIMUnmountImage - Unmounts a mounted image in a Windows image (.wim) // file from the specified directory. [DllImport("wimgapi.dll", EntryPoint = "WIMUnmountImage", SetLastError = true)] public static extern int WIMUnmountImage( [MarshalAs(UnmanagedType.LPWStr)] string lpszMountPath, [MarshalAs(UnmanagedType.LPWStr)] string lpszWimFileName, Int32 dwImageIndex, int bCommitChanges ); // WIMSetTemporaryPath - Sets the location where temporary imaging files // are to be stored. [DllImport("wimgapi.dll", EntryPoint = "WIMSetTemporaryPath", SetLastError = true)] public static extern int WIMSetTemporaryPath( IntPtr hWim, [MarshalAs(UnmanagedType.LPWStr)] string lpszPath ); // WIMCopyFile - Copies an existing file to a new file. Notifies the // application of its progress through a callback function. // If the source file has verification data, the contents of // the file are verified during the copy operation. [DllImport("wimgapi.dll", EntryPoint = "WIMCopyFile", SetLastError = true)] public static extern int WIMCopyFile( [MarshalAs(UnmanagedType.LPWStr)] string lpszExistingFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpszNewFileName, CopyProgressRoutine lpProgressRoutine, IntPtr lpvData, out Int32 pbCancel, Int32 dwCopyFlags ); // WIMRegisterMessageCallback - Registers a function to be called with imaging-specific data. // For information about the messages that can be handled, // see Messages [DllImport("wimgapi.dll", EntryPoint = "WIMRegisterMessageCallback", SetLastError = true)] public static extern Int32 WIMRegisterMessageCallback( IntPtr hwim, WIMMessageCallback fpMessageProc, IntPtr lpvUserData ); // WIMUnregisterMessageCallback - Unregisters a function from being called with imaging-specific data. [DllImport("wimgapi.dll", EntryPoint = "WIMUnregisterMessageCallback", SetLastError = true)] public static extern long WIMUnregisterMessageCallback( IntPtr hwim, WIMMessageCallback fpMessageProc ); // WIMGetImageInformation - Returns information about an image within the .wim (Windows image) file. [DllImport("wimgapi.dll", EntryPoint = "WIMGetImageInformation", SetLastError = true)] public static extern Int32 WIMGetImageInformation( IntPtr hImage, ref IntPtr lplpvImageInfo, ref Int32 lpcbImageInfo ); [DllImport("kernel32.dll", EntryPoint = "LocalFree", SetLastError = true)] public static extern long LocalFree( IntPtr hMem ); // WIMSetImageInformation - Stores information about an image in the Windows image (.wim) file. [DllImport("wimgapi.dll", EntryPoint = "WIMSetImageInformation", SetLastError = true)] public static extern int WIMSetImageInformation( IntPtr hImage, IntPtr lpvImageInfo, int cbImageInfo ); // WIMDeleteImageMounts - Removes images from all directories where they have been previously mounted. [DllImport("wimgapi.dll", EntryPoint = "WIMDeleteImageMounts", SetLastError = true)] public static extern int WIMDeleteImageMounts( int Flag ); public delegate long CopyProgressRoutine( long TotalFileSize, long TotalBytesTransferred, long StreamSize, long StreamBytesTransferred, Int32 dwStreamNumber, Int32 dwCallbackReason, int hSourceFile, int hDestinationFile, int lpData); // WIMMessageCallback - An application-defined function used with the // WIMRegisterMessageCallback or WIMUnregisterMessageCallback functions. public delegate Int32 WIMMessageCallback( Int32 dwMessageId, Int32 wParam, Int32 lParam, Int32 lpvUserData ); // Get the Name for the given Image in the WIM file // if image not found, returns blank string public static string GetNameForImage(string WimFileName, int ImageIndex) { string strReturn = ""; XmlDocument xmlImageData = new XmlDocument(); IntPtr hWIM; IntPtr XMLInfo = (IntPtr)0; Int32 iLength = 0; Int32 iReturn; int created; hWIM = WIMCreateFile(WimFileName, WIM_GENERIC_READ, WIM_OPEN_EXISTING, WIM_FLAG_VERIFY, WIM_COMPRESS_XPRESS, out created); if (hWIM != null) { iReturn = WIMGetImageInformation(hWIM, ref XMLInfo, ref iLength); if (iReturn != 0) { String XMLStr = Marshal.PtrToStringUni(XMLInfo); String EditedXML = XMLStr.Substring(1); xmlImageData.LoadXml(EditedXML); XmlNode root = xmlImageData.DocumentElement; if (root.Name == WimApi.WIM_XML_NODE_WIM) { XmlNode xmlImage = root.LastChild; int icount = root.ChildNodes.Count; for (int i = 1; i < icount; i++) { if (i == ImageIndex) { int ichild = xmlImage.ChildNodes.Count; if (ichild > 0) { for (int j = 0; j < ichild; j++) { if (xmlImage.ChildNodes[j].Name == (WIM_XML_NODE_NAME)) { strReturn = xmlImage.ChildNodes[j].InnerText; } } } } } } } WIMCloseHandle(hWIM); } return strReturn; } // Get the name for the image, if given the WIM file name and ImageID // If image not found, returns 0 public static int GetIDForImage(string strWimFileName, string Imagename) { int iID = 0; XmlDocument xmlImageData = new XmlDocument(); IntPtr hWIM; IntPtr XMLInfo = (IntPtr)0; Int32 iLength = 0; Int32 iReturn; string strName = Imagename.ToUpper(); int created; hWIM = WIMCreateFile(strWimFileName, WIM_GENERIC_READ, WIM_OPEN_EXISTING, WIM_FLAG_VERIFY, WIM_COMPRESS_XPRESS, out created); if (hWIM != null) { iReturn = WIMGetImageInformation(hWIM, ref XMLInfo, ref iLength); if (iReturn != 0) { String XMLStr = Marshal.PtrToStringUni(XMLInfo); String EditedXML = XMLStr.Substring(1); xmlImageData.LoadXml(EditedXML); XmlNode root = xmlImageData.DocumentElement; if (root.Name == WimApi.WIM_XML_NODE_WIM) { XmlNode xmlImage = root.LastChild; int icount = root.ChildNodes.Count; for (int i = 1; i < icount; i++) { int ichild = xmlImage.ChildNodes.Count; if (ichild > 0) { for (int j = 0; j < ichild; j++) { if (xmlImage.ChildNodes[j].Name == WIM_XML_NODE_NAME) { if (xmlImage.ChildNodes[j].InnerText.ToUpper() == strName) { iID = i; } } } } } } } WIMCloseHandle(hWIM); } return iID; } // Get the list of all Imagenames in the given WIM file // Returns a string in the format n1-name1;n2-name2; etc public static string GetImageNames(string strWimFileName) { string strReturn = ""; XmlDocument xmlImageData = new XmlDocument(); IntPtr hWIM; IntPtr XMLInfo = (IntPtr)0; Int32 iLength = 0; Int32 iReturn; int created; hWIM = WIMCreateFile(strWimFileName, WIM_GENERIC_READ, WIM_OPEN_EXISTING, WIM_FLAG_VERIFY, WIM_COMPRESS_XPRESS, out created); if (hWIM != null) { iReturn = WIMGetImageInformation(hWIM, ref XMLInfo, ref iLength); if (iReturn != 0) { String XMLStr = Marshal.PtrToStringUni(XMLInfo); String EditedXML = XMLStr.Substring(1); xmlImageData.LoadXml(EditedXML); XmlNode root = xmlImageData.DocumentElement; if (root.Name == WimApi.WIM_XML_NODE_WIM) { XmlNode xmlImage = root.LastChild; int icount = root.ChildNodes.Count; for (int i = 1; i < icount; i++) { int ichild = xmlImage.ChildNodes.Count; if (ichild > 0) { for (int j = 0; j < ichild; j++) { if (xmlImage.ChildNodes[j].Name == WIM_XML_NODE_NAME) { //strReturn += i.ToString() + "-"; strReturn += xmlImage.ChildNodes[j].InnerText; strReturn += ";"; } } } } } } WIMCloseHandle(hWIM); } return strReturn; } ///<summary> ///Mounts an image in a .wim file to the specified directory. ///</summary> ///<returns>Returns TRUE and sets the LastError to ERROR_SUCCESS. ///Returns FALSE in case of a failure and the LastError is set to the appropriate Win32 error value. ///</returns> public static void MountImage(string mountPath, string windowsImageFileName, int imageIndex) { bool status = false; int rc; try { status = WIMMountImage(mountPath, windowsImageFileName, imageIndex, System.Environment.GetEnvironmentVariable("temp")); rc = Marshal.GetLastWin32Error(); } catch (System.StackOverflowException) { // //Throw an exception. // throw new System.InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Unable to mount image {0} to {1}.", windowsImageFileName, mountPath)); } if (status == false) { // //Throw an exception. // throw new System.InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Unable to mount image {0} to {1}. Error = {2}", windowsImageFileName, mountPath, rc)); } } } // UTILTY Class to get all needed infoirmation about an Image in a WIM file // constructor takes the WIM File name and the image id as parameters // Usually get the image count in the WIM file and instantiate as many CFIWIMImage // objects as per the number of images in the WIM file // IF THE OBJECT IS NOT CONSTRUCTED , iSuccess is set to false. public class WindowsImage { private string m_WimPath; public string WimPath { get { return m_WimPath; } } private int m_ImageID; public int ImageID { get { return m_ImageID; } } private string m_ImageName; public string ImageName { get { return m_ImageName; } } private Int32 m_Major; public Int32 Major { get { return m_Major; } } private Int32 m_Minor; public Int32 Minor { get { return m_Minor; } } private Int32 m_Build; public Int32 Build { get { return m_Build; } } private Int32 m_SPBuild; public Int32 SPBuild { get { return m_SPBuild; } } private bool m_Success; public bool Success { get { return m_Success; } } public WindowsImage(string wimfile, int index) { m_WimPath = wimfile; m_ImageID = index; IntPtr hWim; int created; IntPtr XMLInfo = (IntPtr)0; Int32 iLength = 0; int iReturn; m_Success = false; hWim = WimApi.WIMCreateFile(wimfile, WimApi.WIM_GENERIC_READ, WimApi.WIM_OPEN_EXISTING, WimApi.WIM_FLAG_VERIFY, WimApi.WIM_COMPRESS_XPRESS, out created); if (hWim != null) { iReturn = WimApi.WIMGetImageInformation(hWim, ref XMLInfo, ref iLength); if (iReturn != 0) { XmlDocument xmlImageData = new XmlDocument(); String XMLStr = Marshal.PtrToStringUni(XMLInfo); String EditedXML = XMLStr.Substring(1); xmlImageData.LoadXml(EditedXML); XmlNode root = xmlImageData.DocumentElement; if (root.Name == WimApi.WIM_XML_NODE_WIM) { XmlNode xmlImage = root.LastChild; int icount = root.ChildNodes.Count; for (int i = 1; i < icount; i++) { if (i == index) { m_Success = true; int ichild = xmlImage.ChildNodes.Count; if (ichild > 0) { for (int j = 0; j < ichild; j++) { if (xmlImage.ChildNodes[j].Name == WimApi.WIM_XML_NODE_NAME) { m_ImageName = xmlImage.ChildNodes[j].InnerText; } if (xmlImage.ChildNodes[j].Name == WimApi.WIM_XML_NODE_WINDOWS) { XmlNode xmlWindows = xmlImage.ChildNodes[j]; int iWCount = xmlWindows.ChildNodes.Count; for (int ij = 0; ij < iWCount; ij++) { if (xmlWindows.ChildNodes[ij].Name == WimApi.WIM_XML_NODE_VERSION) { XmlNode xmlVersion = xmlWindows.ChildNodes[ij]; int iVCount = xmlVersion.ChildNodes.Count; for (int k = 0; k < iVCount; k++) { if (xmlVersion.ChildNodes[k].Name == WimApi.WIM_XML_NODE_MAJOR) { m_Major = Convert.ToInt32(xmlVersion.ChildNodes[k].InnerText); } if (xmlVersion.ChildNodes[k].Name == WimApi.WIM_XML_NODE_MINOR) { m_Minor = Convert.ToInt32(xmlVersion.ChildNodes[k].InnerText); } if (xmlVersion.ChildNodes[k].Name == WimApi.WIM_XML_NODE_BUILD) { m_Build = Convert.ToInt32(xmlVersion.ChildNodes[k].InnerText); } if (xmlVersion.ChildNodes[k].Name == WimApi.WIM_XML_NODE_SPBUILD) { m_SPBuild = Convert.ToInt32(xmlVersion.ChildNodes[k].InnerText); } } } } } } } } } } } WimApi.WIMCloseHandle(hWim); } } }} Edited July 14, 2012 by The Glimmerman
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now