Video Screencast Help

SVS 2.X SDK Guide Part 3: Export and Import

Created: 24 Apr 2008 • Updated: 29 Jul 2010 | 1 comment
Language Translations
Jordan's picture
0 0 Votes
Login to vote

In Part Two of my SVS SDK series I covered Layer Managment methods such as activate and delete. Please review those articles before reading this one because I won't cover anything mentioned in Part One or Part Two here. Hint: the methods covered in Part Three won't work without what was covered in Part One.

Changes to FLS2 Class

I've added a new C# file to the class, SVSStuct.cs. It contains Structures and Enumerations that are used by the library.

I've added both Export and Import to ManagedSVS.cs.

Also a lot of new Constants have been added.

You can download the newest version of the FSL2 Class from the download portal.


Import and Export are both fairly complicated to set up and use, but thankfully they're similar enough that once you get one working the other will work with only a few minor changes. Import and Export are the first methods in the FSL2 Class that use a structure. There are several things that need to be done to get these two to work. First off I'll cover the actual methods themselves.


public static extern UInt32 import
   string archivePath,
   bool replaceIfExists,
   ref IMP_EXP_V1 pUserData,
   UInt32 structureVersion,
   [MarshalAs(UnmanagedType.LPStr)] StringBuilder importedGuid,
   int cbImportedGuid

Import takes a lot of parameters; first is the path to the VSA to import and a Boolean to see if SVS should replace a layer if a similar Guid already exists. Next is where things get complicated. IMPEXP_INFO_FUNC is a delegate function. We need to define this in the class so when you create a new instance of the class it gets created. If you're not familiar with these concepts I'll show them later on in this guide. IMP_EXP_V1 is our structure that reports on the import or export progress. It's covered in the next section, and we're passing a pointer to it. Like delegate, an instance needs to be created.

Structure Version is a constant that we'll pass in when we call the function. Imported Guid is a stringBuilder that's set to the constant size of 64 when we call the method. Lastly is cbImportedGuid which is the buffer size of the stringBuilder. When Import completes, it will populate the stringBuilder with the Guid of the imported layer.

MarshalAs: You'll notice from time to time I have certain strings set to marshal in. What this is doing is converting a type from C++ that doesn't exist in .Net into something .Net can use. It shouldn't be anything you'll have to worry about when using the FSL2 Class.


public static extern UInt32 Export
   string fslGUID,
   string archivePath,
   bool replaceIfExists,
   ref IMP_EXP_V1 pUserData,
   UInt32 structureVersion

Before we move on I want to cover Export. Since it's similar to Import there's not much new to cover. Export takes a Guid in addition to a path and a replace Boolean, and a new UInt named StructureVersion. Outside of that -- and the missing stringbuilder -- the method is the same (even if what it does is reversed). StructureVersion's value is always 1, why? Well as you'll see below we're attaching a structure to Export and Import. Currently there's only one and it's numbered as one. Simple enough.



public class IMP_EXP_V1 
   public int currentAction;
   public int totalPercent;
   public int itemPercent;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string layerName;
   public UInt32 errorCode;
   public UInt32 secondaryErrorCode;
   public UInt32 dwContinue;
   public IMPEXP_INFO_FUNC RTInfoFunc;
   public IntPtr pUserData;

Here's our structure. As I mentioned above in import IMP_EXP_V1 reports the Import or Export progress. For the most part it's fairly simple so I only want to point out the last two entries. Like Import and Export you're seeing us pass in our delegate -- I'll be covering that soon so don't worry -- and a pointer to pUserData, which is the instance of this structure our class will create (more on this next). As for the rest, you'll see how we use these other items in the example.

Creating our Instances

Outside of the new methods, we've added a few lines of code to the top of ManagedSVS.cs. These are class objects we'll be referencing throughout the Import/Export process. I've added the following two lines of code to the FLS2 class -- right after the constructor.

 public IMP_EXP_V1 pUserData = new IMP_EXP_V1();
 public delegate void IMPEXP_INFO_FUNC
   IMP_EXP_V1 RTInfoFunc

First off we create the pUserData object we've seen throughout this section. It's of type IMP_EXP_V1 which we just covered. Next we're creating a delegate method named IMPEXP_INFO_Function that takes a type IMP_EXP_V1 that we're naming RTInfoFunc (short for Real Time Info Function). If you're not familiar with Delegates, simply put, they're a way to define a method without defining what it does. You'll see this in action next.

Seeing it in Action

So here's a quick program that takes in multiple VSAs, adds them to a Queue list, and then, one-by-one, imports everything. I'm not going to cover everything (like the main function stuff that does argument validation).

Main Funtion

 FSL2 mySVS = new FSL2();
 Queue importList = new Queue();
 Console.WriteLine("Queue list has " + importList.Count +" Items");
 while (importList.Count > 0) {
    object myItem=importList.Dequeue();
    Console.WriteLine("Importing: " + myItem.ToString());
    if (import(myItem.ToString(), true, mySVS.pUserData)) {
       Console.WriteLine("Import done");
    }else {
       Console.WriteLine("Import failed");
    Console.WriteLine("Left: " + importList.Count);              

The first thing we do is create an object of type FLS2. This will initialize SVS as well as create our delegate and structure objects. Now look at my while statement. One of my Ifs is calling an import method but it's not FSL2.Import. This is a different import that I create for making things simpler to show. It takes myItem (which is the path to the VSA), true for over write and mySVS.pUserData which is the object we just created.


 public static bool import(string myArg, bool myBool,FSL2.IMP_EXP_V1 pUserData) 
   StringBuilder myGuid = new StringBuilder(FSL2.MAXNAMELEN);
   UInt32 result = FSL2.import(
      new FSL2.IMPEXP_INFO_FUNC(importStatus),
      ref  pUserData,
    if (result == FSL2.ERROR_SUCCESS) {
       return true;
    }else {
       return false;

Here's where we call the FSL2.import method. It might be confusing having two import methods -- even if they're in different classes -- but this is something I did to for this article so this code can be singled out because there are several things going on here that need to be pointed out. We start off by creating our Guid stringbuilder that will be populated by FSL2.import when it's done and then we call the method.

Next our delegate is created:

new FSL2.IMPEXP_INFO_FUNC(importStatus),

We're creating a new object of type FSL2.IMPEXP_INFO_FUNC which was an empty delegate that required a type of our structure but we're passing in something called importStatus which is our Real Time reporting function that will inform you what the import process is. If we were exporting, we could create an exportStatus function and pass it in the same way without having to define a separate delegate.

This delegate needs to have something to point at. It can be an empty function but it has to pass in RTInfoFunc as type FSL2.IMP_EXP_V1. Outside of that one requirement, you can have the function do whatever you want.

Import Status

public static void importStatus(FSL2.IMP_EXP_V1 RTInfoFunc) {
     string CmdAction;
     string CmdStatus = "Import Action: ";

     if (FSL2.IMPEXP_STATE_COMPLETE == RTInfoFunc.currentAction)
         CmdAction = "COMPLETE";
     else if (FSL2.IMPEXP_STATE_EXTRACTING == RTInfoFunc.currentAction)
         CmdAction = "EXTRACTING";
     else if (FSL2.IMPEXP_STATE_AFTER_EXTRACT == RTInfoFunc.currentAction)
         CmdAction = "AFTER EXTRACT";
     else if (FSL2.IMPEXP_STATE_REG_IMPORT == RTInfoFunc.currentAction)
         CmdAction = "REGISTRY IMPORTING";
     else if (FSL2.IMPEXP_STATE_DELETING == RTInfoFunc.currentAction)
         CmdAction = "DELETING";
     else if (FSL2.IMPEXP_STATE_NAME_VALID == RTInfoFunc.currentAction)
         CmdAction = "NAME_VALID";
     else if (FSL2.IMPEXP_STATE_ERROR == RTInfoFunc.currentAction)
     else CmdAction = RTInfoFunc.currentAction.ToString();

     Console.CursorLeft = 0;
     Console.Write(CmdStatus + CmdAction);

     if (FSL2.IMPEXP_STATE_COMPLETE == RTInfoFunc.currentAction) {
         for (int i = 0; i < CmdStatus.Length + CmdAction.Length; i++) {
             Console.Write(" ");

What this function is doing is getting called recursively by FSL2.import. We then check to see what our status is against a bunch of constants and then updating the command line. In this example, we're only checking against currentAction out of all the possibilities in IMP_EXP_V1 but you could get the total percent or the current percent of the action being worked on and display those if you want.


FSL2ImportEX is very similar to FSL2Import. I don't have it inside the FSL2 class because I haven't needed it (and most people won't) but it allows you to set the layer redirect area to someplace different than the normal SVS redirect area. If you open up RegEdit and navigate to where the FSL key is, you'll see that each layer has its own redirect location outside of the standard SVS one. By using FLS2ImportEX you can have a layer save to whatever path you want. Though, be warned that I've personally seen issues with applications run from layers not in the normal redirect area. Most aren't showstoppers but expect non-normal things to happen.


There you have it, the majority of SVS features that people use. I hope that I've made Export and Import more clear to those of you who've looked at the SDK before and been confused (it took me quite a while to figure out and I had to ask the guys who created the APIs for help, so don't feel bad if you couldn't figure it out from just what the SDK provided). With what has been covered in parts one, two, and three you can do most of what's already available in WMI but with more control over what each feature does. Part Four will most likely cover layer attributes, so stay tuned.

Remember that future versions will be listed in the FSL2 Class Portal where the FSL2 class is available for download. Be sure to subscribe to that thread which will inform you of any new articles and updates to the class.

Return to the Virtualization SDK Book

Comments 1 CommentJump to latest comment

Nick5020's picture

This helped alot thanks :)

Login to vote