Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Vista Imaging APIs (WIMGAPI) With C#

0.00/5 (No votes)
4 Mar 2007 1  
Using the WIMGAPI in C#

Introduction

Deploying a new operating systems to an enterprise is no small task, but to reduce the complexity of deployment, Microsoft based the installation of Windows Vista on the file based disk imaging technology called Windows Imaging(WIM). Microsoft also provided a set of APIs to programmatically capture,modify and apply images for deployment in a manufacturing or corporate environment. These APIs are available in a C++ Dll (WIMGAPI.DLL) and used by ImageX.exe. However calling these APIs from a C# module needs a little bit of work from developers. Microsoft provided few samples to use these APIs in C++ but there is not any sample to show how these APIs can be used in a C# environment.

Background

WIMGAPI.DLL is a C++ DLL and Microsoft provides a header file, library and documentation for developers to use with their C++ application. However in C#, the APIs need to be invoked as unmanaged code. This article is about how to call these APIs in a C# application using P/Invoke and DllImport features available in .NET and C#.

Using the code

This article has two classes in C#. WimApi class is a wrapper class to provide a DllImport statement for each API entry point available in WIMGAPI. It also has a generic WindowsImage class, which is used to construct a Windows Image object with most commonly used properties of a WIM object. To use these classes, simply add the source code to your project and include the reference to the namespace in your application. These is also small executable included to show how to use these two classes in your C# application.

WimApi class has an entry point defined for each WIMGAPI function using DllImport as listed below:

[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
    );

[DllImport("wimgapi.dll", EntryPoint = "WIMApplyImage",
           SetLastError = true)]
public static extern int  WIMApplyImage(
    IntPtr   hImage , 
    [MarshalAs (UnmanagedType .LPWStr )]  string lpszPath,
    Int32  dwApplyFlags
    );

[DllImport("wimgapi.dll", EntryPoint = "WIMCaptureImage",
           SetLastError = true)]
public static extern IntPtr  WIMCaptureImage(
    IntPtr   hWim,
    [MarshalAs (UnmanagedType .LPWStr )] string  lpszPath ,
    Int32   dwApplyFlags 
    );        
[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 
    );        

The utility class WindowsImage has a constructor that calls these APIs to create a C# object with some attributes of the WIM Image. Following code snippet shows how to invoke the C# method from a C# application: First include a reference to the WimApi namespace

using Library.WimApi

private void WIMGetImageInformation_Click(object sender, EventArgs e)
{
    if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        wimFile = this.openFileDialog1.FileName;
    }
    else
    {
        return;
    }
    IntPtr hWIM;
    IntPtr XMLInfo = (IntPtr)0;
    Int32 iLength = 0;
    Int32 iReturn;
    int created;
    hWIM = WimApi.WIMCreateFile(wimFile,
        WimApi.WIM_GENERIC_READ,
        WimApi.WIM_OPEN_EXISTING,
        WimApi.WIM_FLAG_VERIFY,
        WimApi.WIM_COMPRESS_XPRESS,
        out created);
    iReturn = WimApi.WIMGetImageInformation(hWIM,
        ref XMLInfo, ref iLength);
    if (iReturn != 0)
    {
        String XMLStr = Marshal.PtrToStringUni(XMLInfo);
        this.textBox1.Text = XMLStr;
        WimApi.LocalFree(XMLInfo);
    }
    else
    {
        string str = "Error from WIMGapi : " + 
                     Convert.ToString ( Marshal.GetLastWin32Error());
        MessageBox.Show(str, "WIMGapi_Error");
    }
    WimApi.WIMCloseHandle(hWIM);
}

Points of Interest

Even though Microsoft has provided a reasonable help documentation for WIMGAPI, there are few errors in the online help file. For example the WIMINFO structure defined in the help document does not match the structure defined in the Wimgapi.h header file. It is worthwhile to check the header file for all references rather than going with the online documentation.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here