# VBForums UtilityBank > UtilityBank - Tutorials >  [VB6] Tutorial: Using OCX Files with SxS Technology

## Elroy

*A Tutorial for Using OCX Files with SxS Technology in VB6*
*Contents*


Introduction & Scope
Assumptions
Justification
Preliminaries
The Quick Version of the Tutorial (for Advanced VB6ers)
The MT.EXE Utility Program
A Manifest File
Combining Manifest Files
Associating a Manifest File with a VB6 Project
Advanced Topics
Referencing ActiveX DLLs
Referencing ActiveX EXEs (or not)
Putting manifests into ActiveX DLL and ActiveX EXE projects
Packing OCX files into Resources
Examples of tested SxS manifest files


*Introduction & Scope*

This is a somewhat esoteric/advanced topic for VB6.  If you’re willing to distribute your VB6 compiled applications with an installer, and you’re not concerned about using whatever version of an OCX file is found in the C:\Windows\System32 (or C:\Windows\SysWOW64 if you’re installing on a 64 bit system) folder when you execute your compiled program on a user’s computer, then you don’t need to concern yourself with any of this.

SxS is short for Side-by-Side.  There’s a Wikipedia page that describes it in detail.

If I were starting a new project, I’d take a serious look at Krool’s work found here and here. I’d tend to just include the source in whatever project I was developing, and be completely done with OCX files (not using them at all).  However, this is not necessarily a practical solution for existing projects that are well developed, for which you may wish to make portable, or just have more control over your OCX files.

In this tutorial, we shall be discussing how to specify exactly which OCX files your application is using.  Furthermore, we will only be discussing how to use these OCX files once your application is compiled into an executable (EXE file).  We will not be discussing how to manifest the actual VB6 IDE.  In other words, when you’re developing (on your development computer), you will still most likely be using whatever OCX files are found in your C:\Windows\System32 (or C:\Windows\SysWOW64 for 64 bit) folder when in the VB6 IDE.  If you intend to use different versions of OCX files for IDE development than you intend to use for manifesting your executable, it is contingent upon you to do appropriate testing to make sure there are no functional differences in these different OCX files.  The easiest thing to do is to have the same set of OCX files registered on your development machine that you intend to use for SxS manifest distribution and execution.

As a note, it’s my understanding that you can also reference ActiveX DLLs with the SxS technology.  However, under Advanced Topics, I discuss an alternative way to reference ActiveX DLLs which I consider to be cleaner (and easier to maintain) than the SxS approach.  Therefore, using ActiveX DLL files with the SxS technology will not be part of this tutorial.


*Assumptions*

*The Command Prompt (aka, Command Window)*:  It will be assumed that you know how to get around in a Command (CMD) prompt window.  Just briefly, you can call up a Command prompt by typing in “CMD” (no quotes) in either your Windows Run box or your Windows Search box.  Once the Command window is open, you can use the CD (chdir, change directory) command to navigate around in your computer’s file system.  And, from any Command window prompt, you can execute any command (executable) that is either on the environment’s path or in the folder you are in.  (Alternatively, you could specify the path of the command (on the same line) before you specify the actual command.)  Most commands also have arguments that you can type in on the same command line.  Hopefully, all of this is already core knowledge for you.

*Where are the OCX files located*:  I’m going to write this tutorial for both 32 bit versions of Windows as well as 64 bit Windows versions.  The primary difference between the two is the location of your registered OCX files.  If everything is as it should be, and you’re on a 32 bit version of Windows, all of your registered OCX files should be in the C:\Windows\System32 folder.  If you’re on a 64 bit version of Windows, these OCX files should be in the C:\Windows\SysWOW64 folder.  However, if you’ve been “playing around” with these OCX files, the registered version can “in theory” be anywhere on your system.  For the purposes of this tutorial, it will be assumed that they are in the “correct” folder as stated.


*Justification*

There are a few different reasons you may want to consider using the SxS technology:

You maintain strict control over which OCX files your application is using when you use the SxS technology.  In other words, your application doesn’t dig through C:\Windows\System32 (or C:\Windows\SysWOW64) to find these OCX files.  Rather, it goes directly where you direct your program to go to find these files.  This assures that you know what functionality your OCX files will have.  In the Windows world of shared DLL files (and OCX files are just a special type of DLL files), programs installed subsequent to yours may replace and “update” the OCX files that you installed.  Furthermore, during your installation, if an OCX file found in C:\Windows\System32 (or C:\Windows\SysWOW64) has a later version stamp than the one you are distributing, it will not be replaced (unless you have an installer that doesn’t follow accepted protocols).  That’s all part of installation protocol.  However, problems arise when OCX files of later versions don’t operate precisely as you want.  This is specifically known as DLL hell.  This has become such a problem that even major portions of the Windows OS (from Vista forward) use this SxS technology.
The VB6 core runtime files have been installed as part of the Windows OS since Windows 2000, and continue to be a part of the Windows OS through Windows 10.  In other words, a simple VB6 compiled program is completely portable (no installation required; it’ll just directly execute). However, once we include OCX files (via IDE_Menu/Project/Components…), this is no longer true.  However, by using the SxS technology with our OCX files, we can again achieve portability for even the most complex VB6 programs.
If you embrace the SxS technology when using OCX files, you will have gone a long way toward staying completely away from your user’s computer’s registry.  This is essentially another aspect of being portable.  I’m sure many of us have somewhat negative feelings about the Windows’ registry, so this will be a plus for many.

----------


## Elroy

(tutorial continued)

*Preliminaries*

*Service Pack 6*.  Initial versions of VB6 had problems with correctly implementing the SxS technology when producing an executable (i.e., when compiling).  This was all corrected with the VB6 Service Pack 6 (SP6) (Vs6sp6B.exe).  Therefore, be sure you have this SP6 installed for your VB6 IDE before compiling a VB6 program for use with the SxS technology.

You can check to make sure you have SP6 installed by checking your VB6 IDE’s About page:





If you don’t have the SP6, it can be downloaded from Microsoft here.  It is also my understanding that, if you happen to have installed “Visual Studio 6” (rather than “Visual Basic 6”) that the Vs6sp6B.exe (above link) will work just fine.


*Making copies of OCX files for SxS operations*.  If you intend to implement this SxS technology with your VB6 project, be sure to copy (*not move*) any OCX files from your C:\Windows\System32 (or C:\Windows\SysWOW64) folder.  If you accidentally move them, move them back, and then make a copy.  In certain cases, the act of moving one of these files will change the registry entries for the OCX file (and we don’t want this).


*The Quick Version of the Tutorial (for Advanced VB6ers)*

Use MT.exe with each of your OCX files to extract the SxS manifest information.  It’s easiest to do this by making sure MT.exe is either in the environment path, or a copy is in C:\Windows\System32 (or C:\Windows\SysWOW64), and then issue a command something like the following:

*mt -tlb:SomeOcxFile.ocx -dll:SomeOcxFile.ocx -out:SomeOcxFile.ocx.manifest*
Once this is executed, you will see a new file named…

*SomeOcxFile.ocx.manifest*
…in the same folder.  This .manifest file is an ANSI (typically ASCII) file that is Notepad editable.  It’s actually an XML file.  You will do this for each of your OCX files.
Once you have a manifest file for each of your OCX files, combine them into one .manifest file, making sure this final .manifest file has only one <?xml… header line and only one *assembly* section.  If you’re not familiar with this, read more details below.  The actual name of the final manifest file does not matter.
Place this final .manifest file into your project’s resources with a “#24” type (no quotes but # is essential), and 1 as the ID.  The ID must be numeric.
Make sure all your OCX files are in the same folder as your compiled executable.
Execute your program (the EXE).  If done correctly, your program will be utilizing the OCX files in its own folder, and not those found in C:\Windows\System32 (or C:\Windows\SysWOW64).

----------


## Elroy

(tutorial continued)

*The MT.EXE Utility Program*

MT stands for “Manifest Tool”, and is a Microsoft program.  I don’t believe it comes with Windows (out of the box), and it doesn’t come with the VB6 IDE either.  It does comes with several other Microsoft IDEs, so you may already have a copy somewhere on your computer.  However, if you don’t (or even if you do, it’s possibly an old version), the easiest way to get it is to install the Windows SDK for whatever version of Windows you’re using (they’re free).

Here’s a link for the Windows 7 SDK.
Here’s a link for the Windows 8 SDK.
Here’s a link for the Windows 10 SDK.
Typically, I also make a copy of MT.EXE and place it into my C:\Windows\System32 (or C:\Windows\SysWOW64) folder.  This will just make things easier, as this is basically a command line utility.

Now, as shown above, to get the necessary SxS information for a manifest file out of our utilized OCX files, we need to execute this MT.EXE utility against each of the OCX files we’ve used.  A sample command to do this would be…

*mt -tlb:SomeOcxFile.ocx -dll:SomeOcxFile.ocx -out:SomeOcxFile.ocx.manifest*
…where you replace the three “SomeOcxFile” words with the name of the OCX file you’re targeting.  You’d type this command in from a Command window after having navigated to  C:\Windows\System32 (or C:\Windows\SysWOW64).

Alternatively, you could build a batch file that you placed into your C:\Windows\System32 (or C:\Windows\SysWOW64) folder (possibly named BatchMT.bat) that contained the following:



```
@echo .
@echo The single argument should be the name
@echo of an OCX file including the .OCX extension
@echo .
@echo The argument you've specified is: %1
@pause
mt -tlb:%1 -dll:%1 -out:%1.manifest
@echo .
@pause
```

Using such a batch file, you could just drag your OCX files onto this BatchMT.bat, and your manifest information would be extracted.

Once you execute the MT.EXE tool against some OCX file, you’ll have a .manifest file for that OCX file.  For example, let’s say we’ve run MT.EXE against the TabCtl32.ocx.  The MT command line would be:

*mt -tlb:TabCtl32.ocx -dll:TabCtl32.ocx -out:TabCtl32.ocx.manifest*
And, after this was executed, we’d have a file named *TabCtl32.ocx.manifest* with the following information:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><file name="tabctl32.ocx" hashalg="SHA1"><comClass clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}"></comClass><comClass clsid="{2334D2B4-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}"></comClass><comClass clsid="{BDC217C5-ED16-11CD-956C-0000C04E4C0A}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" description="A Tabbed Dialog control that can be used to group controls on separate tabs."></comClass><comClass clsid="{942085FD-8AEE-465F-ADD7-5E7AA28F8C14}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" description="A Tabbed Dialog control that can be used to group controls on separate tabs."></comClass><typelib tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" resourceid="1" version="1.1" helpdir=""></typelib></file><comInterfaceExternalProxyStub name="IVBDataObject" iid="{2334D2B1-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub><comInterfaceExternalProxyStub name="IVBDataObjectFiles" iid="{2334D2B3-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub><comInterfaceExternalProxyStub name="ISSTabCtl" iid="{2A4FCCB0-DFF1-11CF-8E74-00A0C90F26F8}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub><comInterfaceExternalProxyStub name="DSSTabCtlEvents" iid="{BDC217C7-ED16-11CD-956C-0000C04E4C0A}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub></assembly>
As we can see, the MT tool gives us the information, but it’s not very nice with its formatting.  We'll discuss this more in the next section.  More information about this MT tool from Microsoft can be found here.

----------


## Elroy

(tutorial continued)

*A Manifest File*

These manifest files are Notepad readable ANSI (typically ASCII) files.  Furthermore, they are a special version of XML files.  As such, they have a certain structure to them.  The first important thing about them is that white space doesn’t matter (extra spaces, tabs, and/or extra lines).  Therefore, let me take the above manifest file for the TabCtl32.ocx and reformat it.  This doesn’t change its functionality at all:



```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <file name="tabctl32.ocx" hashalg="SHA1">
        <comClass clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}"></comClass>
        <comClass clsid="{2334D2B4-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}"></comClass>
        <comClass clsid="{BDC217C5-ED16-11CD-956C-0000C04E4C0A}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" description="A Tabbed Dialog control that can be used to group controls on separate tabs."></comClass>
        <comClass clsid="{942085FD-8AEE-465F-ADD7-5E7AA28F8C14}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" description="A Tabbed Dialog control that can be used to group controls on separate tabs."></comClass>
        
        <typelib tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" resourceid="1" version="1.1" helpdir=""></typelib>
    </file>

    <comInterfaceExternalProxyStub name="IVBDataObject"         iid="{2334D2B1-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IVBDataObjectFiles"    iid="{2334D2B3-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSTabCtl"             iid="{2A4FCCB0-DFF1-11CF-8E74-00A0C90F26F8}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DSSTabCtlEvents"       iid="{BDC217C7-ED16-11CD-956C-0000C04E4C0A}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>

</assembly>
```

It’s important to note that manifest files (in the broader sense) can contain a great deal of other information unrelated to SxS operations.  However, those discussions are beyond the scope of this tutorial.  There are many other threads (and utilities) in the VBForums that discuss building manifest files for these other purposes, and you are encouraged to explore them.  However, in this tutorial, we will restrict ourselves to discussions of SxS operations.

Every manifest file I’ve seen for VB6 programs has the same header line.  That’s the *<?xml…* line at the very top of the file.  And that is the only section in the file that isn’t explicitly opened and closed.  Just always make sure that header line is in your manifest file.

If you’re familiar with HTML, you’ll see that these XML manifest files have much the same flavor.  You open a section with a <keyword> tag, and then you close it with a </keyword> tag.  (Alternatively, if a section is wholly contained within <> brackets, it can be closed with a single / just before the closing bracket, such as <section info />.  However, that’s not the way the MT tool does it.)  In the above reformatted manifest file, I've bolded and made dark red each time a section is opened and closed.

Next, we see that the *assembly* section is opened.  The information you see in the opening of this assembly section is standard information for the use of SxS technology with VB6.  It also just stays at it is.

Next, we see a *file* section being opened with mention of our TabCtl32.ocx file.  These file names are not case sensitive.  Also, you’ll see a *hashalg="SHA1"* in this section.  This is unimportant, and I typically delete it.  However, before proceeding, we need to further discuss the <file…> tag that opens this *file* section.  For this TabCtl32.ocx file, we have…

*<file name="tabctl32.ocx">*
…after I’ve deleted the *hashalg* portion.  If we leave it this way, your executable will expect to find this TabCtl32.ocx in the same path as the executable.  If it’s not there, the executable will report an error and fail to execute.

As a strongly recommended alternative, we might place our OCX files in a sub-folder of our executable.  I’ve seen several people use a sub-folder named “Dependencies”.  If we wanted to set things up like this, we would need to edit the tag opening the *file* section as follows for our example:

*<file name="Dependencies\tabctl32.ocx">*
Note that some might want to put a “.\” before “Dependencies”, such as “.\Dependencies”.  However, this would fail.  The SxS technology is _not_ setup for absolute path specifications.  For instance, something like “C:\Temp\Dependencies” would not work either.  In other words, for SxS operations to work correctly, your OCX files must be in the same folder as your executable, or some sub-folder directly beneath that folder (with that sub-folder specified in the manifest file).

Next (within the manifest file), you will see several *comClass* sections opened and closed, with various GUID and other information within them.  This is the important information necessary for your executable program to understand how to use the OCX file.  Do not tamper with this (other than possibly adding white space for formatting).

Next, you may see a *typelib* section.  This is more information necessary for the SxS operations and should not be changed (again, other than adding white space).

Next, you’ll see a tag closing the *file* section. 

Next, you’ll see several *comInterfaceExternalProxyStub* sections opened and closed.  Again, these are just supplying necessary information for SxS operations, and should not be changed, other than white space.

Finally, you’ll see a tag closing the *assembly* section.

----------


## Elroy

(tutorial continued)

*Combining Manifest Files*

For any particular VB6 project, you may be using more than one OCX file.  In fact, you may be using many.  But only one manifest file is allowed per VB6 project.  Therefore, we will need to understand how to combine these manifest files.  It’s actually quite easy.  We just need to remember that we always only have one <?xml… header line (and it’s always the same).  And we also always only have one *assembly* section (unless you have a need for others beyond the scope of SxS operations).

You will have one *file* section per OCX file.  Don’t forget to modify each for any sub-folder (i.e., “Dependencies”) redirection if you’re doing this.  Within the *file* sections, the *comClass* and *typelib* sections will stay the same as what the MT tool produced.  Also, below the *file* sections,  you will have as many *comInterfaceExternalProxyStub* sections as is necessary to capture all the information produced by the MT tool.  For example, the following is a manifest file with the manifests for TabCtl32.ocx and RichTx32.ocx combined.

I’ve deleted the *hashalg* information and inserted the “Dependencies” sub-folder redirection.  If you’re only using TabCtl32.ocx and RichTx32.ocx in your VB6 project, and you have no other information to place in your manifest file, you’re ready to go.



```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <file name="Dependencies\tabctl32.ocx">
        <comClass clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}"></comClass>
        <comClass clsid="{2334D2B4-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}"></comClass>
        <comClass clsid="{BDC217C5-ED16-11CD-956C-0000C04E4C0A}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" description="A Tabbed Dialog control that can be used to group controls on separate tabs."></comClass>
        <comClass clsid="{942085FD-8AEE-465F-ADD7-5E7AA28F8C14}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" description="A Tabbed Dialog control that can be used to group controls on separate tabs."></comClass>
        
        <typelib tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" resourceid="1" version="1.1" helpdir=""></typelib>
    </file>

    <file name="Dependencies\richtx32.ocx">
        <comClass clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}"></comClass>
        <comClass clsid="{2334D2B4-713E-11CF-8AE5-00AA00C00905}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}"></comClass>
        <comClass clsid="{3B7C8860-D78F-101B-B9B5-04021C009402}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" description="Microsoft Rich Textbox Control 6.0 (SP6)"></comClass>
        <comClass clsid="{894BA3A3-3CA3-402F-B4FE-CD08337E9535}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" description="Microsoft Rich Textbox Control 6.0 (SP6)"></comClass>
        <comClass clsid="{4A8F35A0-D900-11CF-89B4-00AA00688B10}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" description="RichText Control OLEObjects Collection Interface"></comClass>
        <comClass clsid="{4A8F35A1-D900-11CF-89B4-00AA00688B10}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" description="The RichTextBox control enables you to add insertable objects to an RTF file. Insertable objects are represented by the OLEObject."></comClass>
        <typelib tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" resourceid="1" version="1.2" helpdir=""></typelib>
    </file>
    
    <comInterfaceExternalProxyStub name="IVBDataObject"         iid="{2334D2B1-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IVBDataObjectFiles"    iid="{2334D2B3-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSTabCtl"             iid="{2A4FCCB0-DFF1-11CF-8E74-00A0C90F26F8}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DSSTabCtlEvents"       iid="{BDC217C7-ED16-11CD-956C-0000C04E4C0A}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>

    <comInterfaceExternalProxyStub name="IVBDataObject"         iid="{2334D2B1-713E-11CF-8AE5-00AA00C00905}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IVBDataObjectFiles"    iid="{2334D2B3-713E-11CF-8AE5-00AA00C00905}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IOLEObject"            iid="{ED117630-4090-11CF-8981-00AA00688B10}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IOLEObjects"           iid="{859321D0-3FD1-11CF-8981-00AA00688B10}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IRichText"             iid="{E9A5593C-CAB0-11D1-8C0B-0000F8754DA1}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DRichTextEvents"       iid="{3B7C8862-D78F-101B-B9B5-04021C009402}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    
</assembly>
```

I’ve never used it, so I can’t say how well it works, but there’s a tool distributed by Microsoft to check manifest files.  It can be found here.

----------


## Elroy

(tutorial continued)

*Associating a Manifest File with a VB6 Project*

Once you get your manifest file like you want it (or at least close enough for testing), there are two ways you can associate these files with your VB6 project: *externally* or *internally*.  And, to get it stated early, the internal method is far preferred over the external method.  In fact, you’d do best to think of the external method as just a way to test your manifest file while you’re developing it.  And then, when you get the manifest file just like you want it, use the internal approach.  Also, you may mistakenly think you can simultaneously use both approaches, but you can’t.  If you have an internal manifest, it will override any external manifest.

And, to state it again, this tutorial is only addressing the execution of programs you’ve compiled into executables (EXEs) with VB6 (either from the IDE or using the VB6.exe from the command line).  We are _not_ talking about the execution of p-code from within the IDE (via F5, F8, or the “run” or “step…” buttons).

*The external approach*:  To use this approach, you simply name your manifest file the same as your executable, with the addition of a .manifest extension.  For instance, let’s say you compile your VB6 program, and you’ve named it:

*MyProgram.exe*
In this case, you’d name your prepared manifest file…

*MyProgram.exe.manifest*
…and place it in the same folder as your executable.  It must be in the same folder.

When you execute your MyProgram.exe, it will look for this MyProgram.exe.manifest before it executes any of your compiled VB6 code and before it loads any of your VB6 forms, taking all the appropriate direction as outlined in the manifest file.  If there’s SxS information in this manifest file, you will need to be sure that those OCX files can be found in the specified location (either the folder of the executable, or some sub-folder).

*The internal approach*:  To use this *internal* approach, you must have some familiarity with resource files.  There is a RC.EXE (resource compiler) utility that comes with VB6, but the use of that utility is beyond the scope of this tutorial.  However, there’s a much easier way to access this resource file.  It can be done from within the VB6 IDE through one of the Add-Ins that comes with VB6:



Once you have the Add-In Manager window open, you'll select the "VB 6 Resource Editor", select it to be "Loaded/Unloaded", and then click "OK":



Now, you will have access to the Resource Editor:



If you click this new aqua-boxy button, you will get the VB6 Resource Editor:



You can use the “open” button on the Resource Editor, but it’s typically easiest to just drag files directly onto the Resource Editor window.  Initially, it will add them as “Custom / 101” files…




(Associating... continued on next post.)

----------


## Elroy

(Associating a Manifest File with a VB6 Project, continued)

You will want to drag your prepared manifest file onto the Resource Editor’s window in just this way.  After you’ve done this, you will need to rename its “Type” and “ID”.  To do this, double-click the 101 for the manifest file you just added.  An “Edit Properties” window will open…



You must change the “Type” to *#24* (the # is essential).  And then the ID must be changed to *1* (and it must be numeric).  Then hit “OK”, and then save the Resource file…



Once you save your resource file, it will be associated with your VB6 project.  For example, if your project is named MyProject, your resource file will typically be named MyProject.res, and this will be recorded in the project’s VBP file.

Furthermore, when you compile your project, this resource file will be wrapped into the executable.

*These resource files can have all kinds of information in them.  However, anytime there’s a resource file with a Type of #24 and an ID of 1, the compiled executable will attempt to read and interpret this file as a manifest file.*

If all is done correctly, you will be using OCX files that you have specified (with no referencing of the Windows registry), rather than the OCX files found in C:\Windows\System32 (or C:\Windows\SysWOW64).

Also, it's been noted that there may be a Windows registry flag named *PreferExternalManifest*. It might be found under the...

*HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide*
...registry entry as a DWORD entry. If it's found, it'll just be a 0 or 1 boolean-type entry. If it's there, and set to 1, and you have both an internal and external manifest, the external will be preferred. Also, there are a couple of reports (here and here, etc.) for certain versions of Windows that external manifests won't work correctly unless this *PreferExternalManifest* flag is set to 1. This is all yet another reason that *internal* manifests (with* no external* manifest found) are the superior way to go.

And that's about it.  Hopefully, I've provided you with all the information you need to use any/all OCX files you use in a SxS way.

Good Luck,
Elroy

----------


## Elroy

(tutorial continued)

*Advanced Topics*


*Referencing ActiveX DLLs*.
It's my understanding that ActiveX DLLs can be executed with the SxS technology in a similar fashion as OCX files.  In fact, if I understand things correctly, the MT.EXE tool can also be used with them.  However, I use an approach that just directly references them, rather than messing with the manifest file.  You can't do this with the OCX files, because forms load the OCX files, and code loads the ActiveX DLL files.

As a note, you can _not_ reference ActiveX EXE files from another project with the SxS technology.  ActiveX EXE files are out-of-process programs, whereas the SxS technology is intended for accessing other components that will be executed in-process.

Attached to this post is a complete example project to show how I access ActiveX DLL files.  The Module1 has the primary code for instantiating and un-instantiating classes out of an ActiveX DLL.  However, if you look at the code under Command1 on Form1 of the EXE_Project1.vbp project, that's the best place to start.  The rest of the code is just support for doing this.

Also, the Module2 code is just extended (but necessary) support for getting everything done.  It got a bit involved because of the way various procedures get interdependent on other procedures, but everything is there that you need.  If we're focusing specifically on instantiating classes out of ActiveX DLLs, some of that code in Module2 could possibly be simplified (but I didn't bother to do this, as it all came out of a much larger project).

Now, let me just quickly outline all the ways this code will run.  Also note that only source code is included in the attached example.  To test in all of the following ways, you will need to compile both the DLL_Project1 project and the EXE_Project1 project.
If you just load EXE_Project1.vbp in the VB6 IDE and execute it as p-code, it will attempt to find the DLL_Project1.dll, and instantiate the class from there.If you compile EXE_Project1.vbp (making EXE_Project1.exe) and then execute the executable, again, it will attempt to find the DLL_Project1.dll, and instantiate the class from there.If you load the EXE_and_DLL_Group.vbg file into the VB6 IDE, and then execute the p-code, it will attempt to instantiate the class from the p-code version of the DLL_Project1 project.
It should be obvious that all of this assumes you already have familiarity with creating ActiveX DLLs.  If not, then don't worry about any of this.  Creating and writing ActiveX DLLs is a discussion beyond the scope of this tutorial.

*Referencing ActiveX EXEs (or not)*.
This topic is just placed here as a note.  It is not possible for a standard executable to access an ActiveX EXE through a manifest file and the SxS technology.  The SxS technology is primarily designed for in-process references.  And an ActiveX EXE runs out-of-process to the other program(s) accessing it.  Also, it's probably impossible to include an ActiveX EXE in an overall project that desires to stay entirely portable.  The reason for this is that ActiveX EXEs tend to self-register certain information for other processes to use them.  It may not be possible to set up a VB6 developed ActiveX EXE in such a way that it stays completely away from the registry.

*Putting manifests into ActiveX DLL and ActiveX EXE projects*.
To be clear, we are *not* talking about referencing an ActiveX DLL nor an ActiveX EXE with a manifest file.  Rather, we're talking about an ActiveX DLL or an ActiveX EXE (or even an ActiveX OCX file you've developed) referencing other OCX files via SxS and a manifest.  All three of these project types (ActiveX DLL, ActiveX EXE, and/or OCX) would use a manifest in the same way.  Because of this, I will just discuss this in terms of an ActiveX DLL that we may be developing.

We may be developing an ActiveX DLL that makes use of various OCX files and the associated controls on various forms included in the ActiveX DLL.  And furthermore, even with this ActiveX DLL, we'd still like to utilize the SxS technology.  An ActiveX DLL project can have a resources file just like a standard EXE project.  We simply follow all the above instructions, but substitute ActiveX DLL everywhere where we're talking about an executable.  When an ActiveX DLL executes, it will look for a manifest (external or internal), just like an executable does.  And, if it's there, and there are SxS directives in it about OCX files, it will attempt to find those OCX files.  And, if they're not found, that ActiveX DLL will report an error and fail to execute.

Just as another point, you can actually reference the same set of OCX files from your executable as are referenced from within any ActiveX DLL.  Just because you have two manifests (one within the executable, and one within the ActiveX DLL), you don't need two sets of OCX files.  This is what will happen when the same OCX file is specified in the ActiveX DLL's manifest as is specified in the main executable's manifest.  However, there may be times when you want an ActiveX DLL to reference an OCX file (or set of OCX files) that is different from those accessed by your main executable.  In these cases, you place the manifest file into the ActiveX DLL project with a Type of *#24*, but you use an *ID=2* rather than *ID=1*.  Also, when you do this, you are responsible for making sure that the ActiveX DLL knows how to find its own set of OCX files.  This is a rather technical Microsoft webpage that discusses these issues.

If you're careful about the way you do things, you can use the same manifest file for your ActiveX DLLs that you use for your executable.  For me, I tend to also place my ActiveX DLL files into my "Dependencies" folder.  Therefore, the manifest file that I insert into those ActiveX DLL projects does not have the *Dependencies\SomeOcxFile.ocx* redirection, because the ActiveX DLL is already in the "Dependencies" folder.

----------


## Elroy

(Advanced Topics, continued)

*Packing OCX files into Resources*.
Here, we are talking about putting our OCX files into our project's resources (in addition to the manifest file).  This is a step toward making our project even *more* portable.  In other words, if done correctly, and all we need is our executable and the OCX files for SxS operations, with this approach, we can pack everything into our executable so that we can distribute this single EXE file (and still not need any installation).

If you do this, you should absolutely have a *Sub Main* to start execution in your project.  And you should do all your OCX unpacking in this *Sub Main*.  That way, you can guarantee that all your OCX files (to be used for SxS operations) will get unpacked before some form starts trying to find them.

There is an attached project for this one, but it's not complete because I'm not allowed to distribute the OCX file with the project.  I've used the RichTx32.ocx for the example.  If you download this example project, you will need to do the following steps to complete the project:

Find your own copy of the RichTx32.ocx file (probably in either C:\Windows\System32 or C:\Windows\SysWOW64).  If it were me, I'd just make a copy of it and place it in the folder with this project.
Check the file version of your RichTx32.ocx file (right-click, Properties, Details, File Version).  If it's not "6.1.98.16", you will need to open the project in the IDE (double-click the Project1.vbp), and then open the Sub Main (in Module1), and patch the File Version to match your File Version.  It's a long line of code in Sub Main, but you should be able to easily find this FileVersion number.
You will need to include your RichTx32.ocx in the project's resources.  How to get the VB6 Resource Editor open was discussed in posts above.  Once you drag the RichTx32.ocx file into the Resource Editor, you should see something similar to the following:



The "Custom"/101 will be the RichTx32.ocx file that was just drug in.  We must rename this to have a "Dependencies" Type and an ID of "RICHTX32.OCX", like the following:



Be sure to save your resources file after you've made these changes.
Once those things are done, you're ready to compile your project into an executable.  The RichTx32.ocx file will be compiled into the executable because you've placed it into the project's resources.
After you've compiled into a Project1.exe, you can double-click and see if things worked.  If everything worked correctly, you should have a sub-folder named "Dependencies" automatically created, with the RichTx32.ocx unpacked into it.  And, when your form shows, you will see a RichTextBox on it that was created by using the unpacked RichTx32.ocx in the "Dependencies" sub-folder.
Now, some final notes about packing these OCX files into the resources of your project.  First, make sure you've got permission to create a sub-folder in whatever folder your executable is in.  If not, you will get an error and your program will not execute.  Even if you change things such that your OCX files are unpacked into the same folder as your executable, you will still need to make sure you've got permission to set files out into this folder.

If you study the code in *Sub Main*, you'll see that the File Version of the OCX file is checked each time your program executes.  In other words, if the OCX file is already found in the "Dependencies" folder, and it has the correct File Version, the program will not waste time unpacking it again.  The File Version is part of this so that you can update the OCX files of your project upon project updates.  You must just be sure that the File Version that's in the code matches the File Version that's packed into the project's resources.

Lastly, the unpacking code I've provided you can rather easily be used to unpack other things beyond these OCX files.  In my main project, I have the ability to unpack an entire empty database along with a plethora of Word and Excel templates that are used for reporting.  My entire application is distributed as a single portable executable that's almost 200 meg.  As a note, no modern executables are read into memory in their entirety.  This is particularly true for things included in their resources.

----------


## Elroy

(Advanced Topics, continued)

*Examples of tested SxS manifest files*.
SxS manifest file for *RichTx32.ocx* (file version 6.1.98.16):
(Note that it's redirected to look in the "Dependencies" sub-folder.)


```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <file name="Dependencies/richtx32.ocx">
        <comClass clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}"></comClass>
        <comClass clsid="{2334D2B4-713E-11CF-8AE5-00AA00C00905}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}"></comClass>
        <comClass clsid="{3B7C8860-D78F-101B-B9B5-04021C009402}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" description="Microsoft Rich Textbox Control 6.0 (SP6)"></comClass>
        <comClass clsid="{894BA3A3-3CA3-402F-B4FE-CD08337E9535}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" description="Microsoft Rich Textbox Control 6.0 (SP6)"></comClass>
        <comClass clsid="{4A8F35A0-D900-11CF-89B4-00AA00688B10}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" description="RichText Control OLEObjects Collection Interface"></comClass>
        <comClass clsid="{4A8F35A1-D900-11CF-89B4-00AA00688B10}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" description="The RichTextBox control enables you to add insertable objects to an RTF file. Insertable objects are represented by the OLEObject."></comClass>

        <typelib tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" resourceid="1" version="1.2" helpdir=""></typelib>
    </file>

    <comInterfaceExternalProxyStub name="IVBDataObject"         iid="{2334D2B1-713E-11CF-8AE5-00AA00C00905}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IVBDataObjectFiles"    iid="{2334D2B3-713E-11CF-8AE5-00AA00C00905}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IOLEObject"            iid="{ED117630-4090-11CF-8981-00AA00688B10}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IOLEObjects"           iid="{859321D0-3FD1-11CF-8981-00AA00688B10}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IRichText"             iid="{E9A5593C-CAB0-11D1-8C0B-0000F8754DA1}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DRichTextEvents"       iid="{3B7C8862-D78F-101B-B9B5-04021C009402}" tlbid="{3B7C8863-D78F-101B-B9B5-04021C009402}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>

</assembly>
```


SxS manifest file for *ThreeD32.ocx* (file version 1.0.41.0):
(Note that it's redirected to look in the "Dependencies" sub-folder.)


```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <file name="Dependencies\ThreeD32.ocx">
        <comClass clsid="{0BA686AA-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" description="A three-dimensional check box.">                                       </comClass>
        <comClass clsid="{0BA686AF-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" description="A three-dimensional frame control.">                                   </comClass>
        <comClass clsid="{0BA686B4-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" description="A three-dimensional command button.">                                  </comClass>
        <comClass clsid="{0BA686B9-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" description="A three-dimensional rectangular control with inner and outer bevels."> </comClass>
        <comClass clsid="{0BA686BE-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" description="A three-dimensional option button.">                                   </comClass>
        <comClass clsid="{0BA686C3-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" description="A three-dimensional push button used in a group.">                     </comClass>

        <typelib tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" resourceid="1" version="1.0" helpdir="" flags="CONTROL">    </typelib>
    </file>

    <comInterfaceExternalProxyStub name="ISSCBCtrl"         iid="{0BA686AB-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSCBCtrlEvents"   iid="{0BA686AC-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSFRCtrl"         iid="{0BA686B0-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSFRCtrlEvents"   iid="{0BA686B1-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSPBCtrl"         iid="{0BA686B5-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSPBCtrlEvents"   iid="{0BA686B6-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSPNCtrl"         iid="{0BA686BA-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSPNCtrlEvents"   iid="{0BA686BB-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSRBCtrl"         iid="{0BA686BF-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSRBCtrlEvents"   iid="{0BA686C0-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSRICtrl"         iid="{0BA686C4-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSRICtrlEvents"   iid="{0BA686C5-F7D3-101A-993E-0000C0EF6F5E}" tlbid="{0BA686C6-F7D3-101A-993E-0000C0EF6F5E}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>

</assembly>
```


SxS manifest file for *TabCtl32.ocx* (file version 6.1.98.16):
(Note that it's redirected to look in the "Dependencies" sub-folder.)


```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <file name="Dependencies\tabctl32.ocx" hashalg="SHA1">
        <comClass clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}"></comClass>
        <comClass clsid="{2334D2B4-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}"></comClass>
        <comClass clsid="{BDC217C5-ED16-11CD-956C-0000C04E4C0A}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" description="A Tabbed Dialog control that can be used to group controls on separate tabs."></comClass>
        <comClass clsid="{942085FD-8AEE-465F-ADD7-5E7AA28F8C14}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" description="A Tabbed Dialog control that can be used to group controls on separate tabs."></comClass>

        <typelib tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" resourceid="1" version="1.1" helpdir=""></typelib>
    </file>

    <comInterfaceExternalProxyStub name="IVBDataObject" iid="{2334D2B1-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IVBDataObjectFiles" iid="{2334D2B3-713E-11CF-8AE5-00AA00C00905}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISSTabCtl" iid="{2A4FCCB0-DFF1-11CF-8E74-00A0C90F26F8}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DSSTabCtlEvents" iid="{BDC217C7-ED16-11CD-956C-0000C04E4C0A}" tlbid="{BDC217C8-ED16-11CD-956C-0000C04E4C0A}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>

</assembly>
```

----------


## Elroy

(Advanced Topics, Examples of tested SxS manifest files, continued)

SxS manifest file for *MsComCtl.ocx* (file version 6.1.98.46):
(Note that it's redirected to look in the "Dependencies" sub-folder.)


```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <file name="Dependencies\mscomctl.ocx">
        <comClass clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}"></comClass>
        <comClass clsid="{2334D2B4-713E-11CF-8AE5-00AA00C00905}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}"></comClass>
        <comClass clsid="{1EFB6596-857C-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft TabStrip Control"></comClass>
        <comClass clsid="{24B224E0-9545-4A2F-ABD5-86AA8A849385}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft TabStrip Control"></comClass>
        <comClass clsid="{9A948063-66C3-4F63-AB46-582EDAA35047}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft TabStrip Control"></comClass>
        <comClass clsid="{1EFB6598-857C-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Returns a reference to a collection of Tab objects in the TabStrip control."></comClass>
        <comClass clsid="{1EFB659A-857C-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Returns a reference to a collection of Tab objects in the TabStrip control."></comClass>
        <comClass clsid="{66833FE6-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft Toolbar Control"></comClass>
        <comClass clsid="{7DC6F291-BF55-4E50-B619-EF672D9DCC58}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft Toolbar Control"></comClass>
        <comClass clsid="{8B2ADD10-33B7-4506-9569-0A1E1DBBEBAE}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft Toolbar Control"></comClass>
        <comClass clsid="{66833FE8-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ToolBar Buttons"></comClass>
        <comClass clsid="{66833FEA-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ToolBar Button"></comClass>
        <comClass clsid="{66833FEC-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ToolBar ButtonMenus"></comClass>
        <comClass clsid="{66833FEE-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ToolBar ButtonMenu"></comClass>
        <comClass clsid="{8E3867A3-8586-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft StatusBar Control"></comClass>
        <comClass clsid="{627C8B79-918A-4C5C-9E19-20F66BF30B86}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft StatusBar Control"></comClass>
        <comClass clsid="{585AA280-ED8B-46B2-93AE-132ECFA1DAFC}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft StatusBar Control"></comClass>
        <comClass clsid="{8E3867A5-8586-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="StatusBar Panels collection"></comClass>
        <comClass clsid="{8E3867AB-8586-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="StatusBar Panel"></comClass>
        <comClass clsid="{35053A22-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft ProgressBar Control"></comClass>
        <comClass clsid="{A0E7BF67-8D30-4620-8825-7111714C7CAB}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft ProgressBar Control"></comClass>
        <comClass clsid="{C74190B6-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Displays a hierarchical list of Node objects, each of which consists of a label and an optional bitmap."></comClass>
        <comClass clsid="{9181DC5F-E07D-418A-ACA6-8EEA1ECB8E9E}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Displays a hierarchical list of Node objects, each of which consists of a label and an optional bitmap."></comClass>
        <comClass clsid="{95F0B3BE-E8AC-4995-9DCA-419849E06410}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Displays a hierarchical list of Node objects, each of which consists of a label and an optional bitmap."></comClass>
        <comClass clsid="{DD2DBE12-F9F8-4E32-B087-DAD1DCEF0783}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Displays a hierarchical list of Node objects, each of which consists of a label and an optional bitmap."></comClass>
        <comClass clsid="{0713E8C0-850A-101B-AFC0-4210102A8DA7}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Treeview Nodes collection"></comClass>
        <comClass clsid="{C74190B9-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="An object in a TreeView control that can contain images and text."></comClass>
        <comClass clsid="{BDD1F04B-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Displays a collection of ListItems such as files or folders."></comClass>
        <comClass clsid="{996BF5E0-8044-4650-ADEB-0B013914E99C}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Displays a collection of ListItems such as files or folders."></comClass>
        <comClass clsid="{979127D3-7D01-4FDE-AF65-A698091468AF}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Displays a collection of ListItems such as files or folders."></comClass>
        <comClass clsid="{CCDB0DF2-FD1A-4856-80BC-32929D8359B7}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Displays a collection of ListItems such as files or folders."></comClass>
        <comClass clsid="{BDD1F04D-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ListView Item collection"></comClass>
        <comClass clsid="{BDD1F04F-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="An item in a ListView control that contains the index of icons associated with it, text, and an array of strings representing subitems that are displayed in Report view."></comClass>
        <comClass clsid="{0713E8C6-850A-101B-AFC0-4210102A8DA7}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ListView Column Header collection"></comClass>
        <comClass clsid="{BDD1F052-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ListView Column Header"></comClass>
        <comClass clsid="{BDD1F054-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ListView SubItem collection"></comClass>
        <comClass clsid="{BDD1F056-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="ListView SubItem object"></comClass>
        <comClass clsid="{2C247F23-8591-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Contains a collection of ListImage objects, each of which can be referred to by its index or key"></comClass>
        <comClass clsid="{F91CAF91-225B-43A7-BB9E-472F991FC402}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Contains a collection of ListImage objects, each of which can be referred to by its index or key"></comClass>
        <comClass clsid="{556C2772-F1AD-4DE1-8456-BD6E8F66113B}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Contains a collection of ListImage objects, each of which can be referred to by its index or key"></comClass>
        <comClass clsid="{2C247F25-8591-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="A bitmap or icon of any size that can be used in other controls."></comClass>
        <comClass clsid="{2C247F27-8591-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="A bitmap or icon of any size that can be used in other controls."></comClass>
        <comClass clsid="{F08DF954-8592-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="A calibrated control with a slider for setting or selecting values."></comClass>
        <comClass clsid="{0B314611-2C19-4AB4-8513-A6EEA569D3C4}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="A calibrated control with a slider for setting or selecting values."></comClass>
        <comClass clsid="{C8A3DC01-8593-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Controls collection"></comClass>
        <comClass clsid="{DD9DA661-8594-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="An object that represents an entry in the listbox portion of the combobox control."></comClass>
        <comClass clsid="{DD9DA663-8594-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="The ComboItems Collection."></comClass>
        <comClass clsid="{DD9DA666-8594-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft ImageComboBox Control"></comClass>
        <comClass clsid="{87DACC48-F1C5-4AF3-84BA-A2A72C2AB959}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" description="Microsoft ImageComboBox Control"></comClass>

        <typelib tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" resourceid="1" version="2.2" helpdir=""></typelib>
    </file>

    <comInterfaceExternalProxyStub name="IVBDataObject"         iid="{2334D2B1-713E-11CF-8AE5-00AA00C00905}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IVBDataObjectFiles"    iid="{2334D2B3-713E-11CF-8AE5-00AA00C00905}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ITabStrip"             iid="{1EFB6594-857C-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ITabStripEvents"       iid="{1EFB6595-857C-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ITabs"                 iid="{1EFB6597-857C-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ITab"                  iid="{1EFB6599-857C-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IToolbar"              iid="{66833FE4-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IToolbarEvents"        iid="{66833FE5-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IButtons"              iid="{66833FE7-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IButton"               iid="{66833FE9-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IButtonMenus"          iid="{66833FEB-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IButtonMenu"           iid="{66833FED-8583-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IStatusBar"            iid="{8E3867A1-8586-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IStatusBarEvents"      iid="{8E3867A2-8586-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IPanels"               iid="{8E3867A4-8586-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IPanel"                iid="{8E3867AA-8586-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IProgressBar"          iid="{35053A20-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IProgressBarEvents"    iid="{35053A21-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ITreeView"             iid="{C74190B4-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ITreeViewEvents"       iid="{C74190B5-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="INodes"                iid="{C74190B7-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="INode"                 iid="{C74190B8-8589-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IListView"             iid="{BDD1F049-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ListViewEvents"        iid="{BDD1F04A-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IListItems"            iid="{BDD1F04C-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IListItem"             iid="{BDD1F04E-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IColumnHeaders"        iid="{BDD1F050-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IColumnHeader"         iid="{BDD1F051-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IListSubItems"         iid="{BDD1F053-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IListSubItem"          iid="{BDD1F055-858B-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IImageList"            iid="{2C247F21-8591-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ImageListEvents"       iid="{2C247F22-8591-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IImages"               iid="{2C247F24-8591-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IImage"                iid="{2C247F26-8591-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISlider"               iid="{F08DF952-8592-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="ISliderEvents"         iid="{F08DF953-8592-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IControls"             iid="{C8A3DC00-8593-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IComboItem"            iid="{DD9DA660-8594-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IComboItems"           iid="{DD9DA662-8594-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IImageCombo"           iid="{DD9DA664-8594-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DImageComboEvents"     iid="{DD9DA665-8594-11D1-B16A-00C0F0283628}" tlbid="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>

</assembly>
```

----------


## Elroy

(Advanced Topics, Examples of tested SxS manifest files, continued)

SxS manifest file for *MsComCt2.ocx* (file version 6.1.98.16):
(Note that it's redirected to look in the "Dependencies" sub-folder.)


```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <file name="Dependencies\mscomct2.ocx">
        <comClass clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}"></comClass>
        <comClass clsid="{2334D2B4-713E-11CF-8AE5-00AA00C00905}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}"></comClass>
        <comClass clsid="{B09DE715-87C1-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Animation Control"></comClass>
        <comClass clsid="{1906F94F-8256-480A-8CDF-60821592CB4B}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Animation Control"></comClass>
        <comClass clsid="{3D8152C1-0CFD-4968-9684-794046886E31}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Animation Control"></comClass>
        <comClass clsid="{603C7E80-87C2-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="UpDown Control"></comClass>
        <comClass clsid="{CEDFFAFD-3C2F-4552-9FD3-3DC4299057FD}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="UpDown Control"></comClass>
        <comClass clsid="{232E456A-87C3-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Microsoft MonthView Control"></comClass>
        <comClass clsid="{F1651457-356D-4CA2-989D-701606A4C828}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Microsoft MonthView Control"></comClass>
        <comClass clsid="{20DD1B9E-87C4-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Microsoft Date and Time Picker Control"></comClass>
        <comClass clsid="{4D588145-A84B-4100-85D7-FD2EA1D19831}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Microsoft Date and Time Picker Control"></comClass>
        <comClass clsid="{FE38753A-44A3-11D1-B5B7-0000C09000C4}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Microsoft Flat Scrollbar Control"></comClass>
        <comClass clsid="{CFA7636D-CAA1-4F18-868F-8720624C8B86}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" description="Microsoft Flat Scrollbar Control"></comClass>

        <typelib tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" resourceid="1" version="2.0" helpdir=""></typelib>
    </file>

    <comInterfaceExternalProxyStub name="IVBDataObject"         iid="{2334D2B1-713E-11CF-8AE5-00AA00C00905}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IVBDataObjectFiles"    iid="{2334D2B3-713E-11CF-8AE5-00AA00C00905}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IAnimation"            iid="{B09DE713-87C1-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DAnimationEvents"      iid="{B09DE714-87C1-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IUpDown"               iid="{603C7E7E-87C2-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DUpDownEvents"         iid="{603C7E7F-87C2-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IMonthView"            iid="{232E4565-87C3-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DMonthViewEvents"      iid="{232E4569-87C3-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IDTPicker"             iid="{20DD1B9B-87C4-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DDTPickerEvents"       iid="{20DD1B9D-87C4-11D1-8BE3-0000F8754DA1}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="IFlatSB"               iid="{FE387538-44A3-11D1-B5B7-0000C09000C4}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
    <comInterfaceExternalProxyStub name="DFlatSBEvents"         iid="{FE387539-44A3-11D1-B5B7-0000C09000C4}" tlbid="{86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}" proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>

</assembly>
```

----------


## Elroy

Saved...

----------


## LaVolpe

Good stuff Elroy. Lots of info to consider for those not familiar enough with SxS manifesting. Question for you to research unless you know the answer ahead of time.

When using VB's P&DW (package and deployment wizard), will it attempt to install the DLLs/OCXs you have referenced in your project? The reason I ask is that when uncompiled, you need to reference those items even though they exist in your manifest. If the P&DW will do the unwanted registrations, even though you don't want that, then what strategies do we have to create an installer that won't install the manifested items?

Just FYI. I'm not a big fan of using a resource file as a warehouse for the binaries and having the exe to act as an ad-hoc installer. Also since the binaries will be extracted to a folder during 'unpacking', in effect, that's two copies: one in the extracted folder and another compiled into the exe. I do realize that your strategy does negate a standard installer. But standard installers have other purposes than just placing files on a pc.

----------


## Elroy

Hi LaVolpe,

It's been a while since I've used the P&DW, but I do feel that I remember (pretty much) how it works.  And yes, if you let the P&DW build a distribution package by just clicking through it, I'm quite sure that it'll include your referenced OCX files in the CAB file(s) it creates.  Furthermore, I'm quite sure it'll unpack them and register them on the target machine during installation.  However, if you've done all the SxS stuff correctly (manifest, and also placed OCX files in a sub-folder), then those registered OCX files wouldn't be used.

As another alternative, if I remember correctly, you can instruct the P&DW to not include specific files (such as those OCX files) into your package (i.e., the CAB file).  If this is done, it would seem that you wouldn't install them in System32 or SysWOW64.  Although, I haven't really tested that assumption.  And you'd still need a copy of the OCX files in a sub-folder to your executable.

And, to the other point you raised, I'm not sure why you're "not a big fan of using a resource file as a warehouse for the binaries".  I've heard others (specifically Dilettante) say that this might be a flag for virus detectors, but I've never had one single problem with it.  And my software runs in some pretty tightly monitored (i.e., virus scanned) environments.  And I just love the ease of program distribution/updating when everything is wrapped into a single executable.  As you've probably noticed, due to the very nature of my primary program, it's always under some degree of constant development.  (In fact, I'm "on site" at this very moment, making some modifications for a new client.)  However, once it's put together, I very rarely ever mess with my .RES file, especially with respect to these OCX files.  They just sit there in the RES file, and get wrapped into the EXE everytime I compile.

But hey ho, that's just my preference.  There are many ways to skin a cat.  I've just been completely portable for many years, and I'm sure I'll always stay that way.




> ...standard installers have other purposes than just placing files on a pc.


Other than registering OCX files (and possibly some DLL files), I'm wondering what other purposes an installer has.  I suppose we could say, "add shortcuts to the desktop and/or start button", but that's no biggie.  What else is there?

Best Regards,
Elroy

----------


## LaVolpe

> Other than registering OCX files (and possibly some DLL files), I'm wondering what other purposes an installer has. I suppose we could say, "add shortcuts to the desktop and/or start button", but that's no biggie. What else is there?


https://msdn.microsoft.com/en-us/library/bb742606.aspx

Not saying VB's P&DW does everything a modern installer would do, but installers can do more based on the distributor's needs.

You did mention something that may be the answer... unselecting dependencies during the P&DW process.

----------


## Elroy

WOW, just reading through that link (https://msdn.microsoft.com/en-us/library/bb742606.aspx) absolutely convinces me that I'll stay portable for as long as it's possible.  There's all kinds of caveats and ways one application's installer can damage other applications discussed in that link.  

I'll agree that I miss out on creating an entry under the Start Button (or possibly also on the Desktop).  However, these days, virtually all of my users are quite familiar with how to make shortcuts.  I understand that other developers (and other applications) may need that feature more than me.  However, even *with* an installer, I'd argue that we're better off staying as "execution-portable" as we possibly can.

When/If I have time, maybe I'll play around with the VB6 P&DW and see if de-selecting the OCX files during packaging works as one would hope.  Also, it'd be nice if there's a way to tell it to set a copy of utilized OCX files out into a sub-folder of the installation/EXE.

Best Regards,
Elroy

----------


## Spooman

Elroy

Good stuff, indeed.
Definitely a lot to chew on and, for me at least, to digest.

Spoo

----------


## immortalx

Elroy I can't thank you enough for the detailed tutorial. Not only did it worked flawlessly on my first attempt, I also learned tons of stuff about a subject that I wouldn't dare touch until now!
Again thanks from the bottom of my heart.

----------


## Elroy

No problem, immortalx.  I'm glad you got some use out of it.   :Smilie:

----------


## HiddenX

Thank you for the info Elroy - this thread helped me a lot.

btw you can check a manifest with mt.exe:



```
mt.exe -manifest my.exe.manifest -validate_manifest
```

The latest experimental version of MMM generates class IDs for for classes with no threading model,too, so you can get duplicate entries if you use more than one ocx-file in your project. For example the clsid="{2334D2B2-713E-11CF-8AE5-00AA00C00905}" (Dataobject) exists in several ocx-files. Duplicate clsids are not allowed in an application  manifest file.

You can fix this by uncommenting this line (and the End If) in frmMake.frm:


```
'''                            If StrPtr(.ThreadingModel) <> 0 Then
```

Normally only the creatable classes with a ThreadingModel are important for VB6 manifests.

----------


## CrazyDude

Just now finding this.  Like others, I'd like to thank you for such a well-written and detailed tutorial.  I'm in need of going portable and I know this will help a lot.  The things you find on here by searching is like a gold mine.

----------


## MrsPie

Great stuff, thank you for putting this together.

Quick (maybe) question: My program uses Crystal Reports 9. Can I include the Crystal Reports .dll's and .ocx's in the SxS manifest, or do I still need to go through the Crystal Reports install? Has anyone else dealt with this?

----------


## MrsPie

Great stuff, thank you for putting this together.

Quick (maybe) question: My program uses Crystal Reports 9. Can I include the Crystal Reports .dll's and .ocx's in the SxS manifest, or do I still need to go through the Crystal Reports install? Has anyone else dealt with this?

----------


## Elroy

Hi MrsPie,

Regretfully, I've only used Crystal Reports WAY back in the beginning, and then moved onto other methods of reports.  So, I've really got no knowledge of how Crystal Reports works.  But, I'd be surprised if you couldn't build the SxS stuff for the OCX.  And, regarding any DLLs, they'll probably work just fine if you drop them in the program's primary folder (before using them, of course).  That does assume they're standard DLLs and not ActiveX DLLs (of which I have no idea).  However, that's all speculation, with no testing.

Good Luck,
Elroy

p.s.  Sorry about the VERY late reply.  I'm just now seeing this.

----------

