Where can I get a Running Object Table Viewer like IROTVIEW? - com

Once upon a time Windows SDK (or it was Visual Studio) had a tool named IROTVIEW which enumerated the Running Object Table (ROT).
Where can I get this tool now?

This site has a pretty good viewer for download in 32 bit and 64 bit versions.
This site has a simple enumeration class, but it needs some improvement since if you have two objects running with the same name (like two instances of Excel), it cannot populate the dictionary with the duplicate key.

Related

Versioned classes appears to be created by REGASM - how to use them?

When I register a .NET assembly enabled for COM interop using the REGASM tool, the tool creates a separate registry key for each component version. For example, I get:
HKEY_CLASSES_ROOT\CLSID\{myCLSID}\InprocServer32\1.0.0.0
HKEY_CLASSES_ROOT\CLSID\{myCLSID}\InprocServer32\1.1.0.0
etc.
Each of these registry contains roughly the same structure values as it is under HKEY_CLASSES_ROOT\CLSID{}\InprocServer32, except that the entries point to different locations, depending on the component version. The HKEY_CLASSES_ROOT\CLSID{myCLSID}\InprocServer32 apparently contains the latest registered version, and that's what COM consumers will normally use, of course, and they ignore the rest.
This structure apparently allows different versions of the component coexist on the same computer (I know it is against the originally specified COM rules). I would like to use it, but I could not find any documentation about it anywhere in the Microsoft documentation or Googling for it. Does anybody know? I am looking for something like CoCreateInstance/CoCreateInstanceEx with the version specifier.
Thanks

Recover files overwritten by generated code

I have a Winforms project that had a amongst others, 7 forms that I blindly named them with the same name that I named tables in my SQL server. Now I was trying to experiment with Entity Frameworks Data Model and visual studio generated classes for the tables in Database. For these 7 forms that class names were identical visual studio deleted all the code that I had in the forms. Is there any way to recover my old code.
I have no usable backup!
I am sorry to say, but unless you have any backup there is no way to recover that files directly.
You could use ILSpy (or one of the other options in this blog article) to disassemble the assembly you have once compiled. You will have at least something like what you had. (You will lose comments and other stuff)
Maybe slightly off-topic, but when you are lucky, you might find your files back with some disk recovery tools like GetDataBack from the company Runtime. I use it a lot myself.

Will having two different versions of a DLL cause issues?

I have a vb6 program that needs to use MSOLAP80.dll to display its pivot tables properly. But because MSOLAP90.dll has some compatibility issues with this I cannot use MSOLAP90.dll and still have the pivot tables display.
I have registered MSOLAP90.dll and then registered MSOLAP80.dll again and everything seems to be fine. I however don't know if both are actually registered or if MSOLAP80.dll is the only one registered, because I have no reference point as to what is new in MSOLAP90.dll. Is it possible that both are registered and the program is just using MSOLAP80.dll and if there are programs that need MSOLAP90.dll then it will know to use that one?
I guess I am just confused about how registering DLL's work and if it is possible to have both of these registered at the same time. Can somebody help with an explanation?
If you want to know for sure which one is registered, you can:
Look at the References dialogue for a type library which matches your DLLs' paths.
Open up RegEdit, and search for MSOLAP80.DLL or MSOLAP90.DLL (uncheck "Match whole string only").
If you find references for both DLLs, then you are safe because you can bind to a specific version. If you find a reference to the wrong DLL, then unregister the wrong one, and register the right one.
COM originall only allowed one version of a set of CLSIDs (which uniquely identify classes), IIDs (which uniquely identify classes' interfaces) at any one time. It is possible to have more than one reference to a LIBID (which identifies a type library - a resource embedded in the DLLL) but they have to have different versions.
From Windows XP onwards, it became possible to do side by side DLL access in which an executable can access a specific version of a DLL, overriding the value in the registry. You need to embed or have a .manifest file in the same folder as the EXE file.
Unfortunately, the documentation for this seems to have disappeared from MSDN, and is only referred to by a couple of Knowledge Base articles:
http://support.microsoft.com/kb/828629
http://support.microsoft.com/kb/843524

VB.NET combobox persistence?

I'm fairly new to VB.NET, and I've mainly been doing ASP programming up 'til now, and I have a pretty simple question.
I'm creating a program that will copy a selected file to a selected directory, and I want to store recent files/dirs so that they can be selected from a combo box. I was planning to just create a settings with "files" and "dirs", and just store the strings as | separated values (since that's an illegal file character).
Is there anything wrong with this approach, or are there any better methods?
I think your approach is fine as it seems to be simply a local cache of recent directories. You can persist the data in the application at the module level(create a module with a public object essentially is a global variable) but it goes away when the application is terminated.
This article is using a similar approach to what you were thinking although the example is in C#

VBA Reference Libraries

I'm new to VBA and have been throwing together a small macro application for the Office. We've got about 80 users on essentially identical PC setups, and it will be accessed by all but a few users.
I've been playing around with some automation of accessing web pages using the Web Services references, and I've also loaded the Microsoft Scripting Runtime references into the project. I attempted to run it on a test PC and it complained that there were missing references.
I don't particularly want to go around 80 PCs and manually load the references.
My question, basically, is how should I manage the distribution of this macro-app to 80 odd users so as to ensure that the references will load every time for every user.
Thanks!
For the most part, late binding will solve problems with references in VBA, unless you have some unusual references. Most problems are caused by differences in library versions that can be overcome with late binding. With VBA, it is often recommended that you develop with early binding but release with late binding. The main disadvantage of late binding is changing built-in constants to values (speed is no longer the issue it used to be.)
So:
Dim fs As Object 'Instead of FileSystemObject '
Dim xl As Object 'Instead of Excel.Application '
Set fs=CreateObject("Scripting.FileSystemObject")
Set xl=CreateObject("Excel.Application")
'Value instead of built-in constant '
ForReading=2
Set f = fs.OpenTextFile("c:\testfile.txt", ForReading)
If you have references that your application depends on, that you know are not going to be on the target PCs, then I would strongly recommend you investigate some installer technology.
Using the installer you should be able to install your macro, and install and register all appropriate references / libraries.
There are generally two flavours on windows, Windows Installer based technology and Script based technology.
We use InstallShield for all of our deployment, although there are several options for you to use (there are several discussion on Stack Overflow).
Using windows installer technology, you can build MSI install files, which you are then able to deploy automatically using Group Policy.
Instead of having the documents expose the functionality, make it an add-in for Office (the suite, or the individual apps, your choice). This way, you don't have to deal with references.
Then, just distribute an install package with the add-in which registers the components and registers the add-ins with the appropriate Office apps.
VB6 might be a good idea here, given it's similarity to VBA.
In addition to this answer, which is the bullet-proof solution to solve this kind of issue, but which is quite complex to implement, you can also write some code to be executed when your VBA application starts, checking the 'references' collection of the 'application' object. You can then check (1) if requested files (dll, ocx, tlb) are available on the computer and (2) if reference can be created (application.references.addFromFile ...).
Be careful: object declarations that might be 'reference dependent', such as:
Dim cat as ADOX.catalog
will raise a compilation bug if the reference is not active when the corresponding module is 'compiled'. I then advise you to isolate your 'reference checking procedure' in a startup module (equivalent to an 'autoexec') which deals only with VBA and basic application objects. Check it with your Help Files (Example: in Access, default references that can be used without external references are VBA, Access and DAO).
EDIT:
in case external references depend on other software package and (1) cannot be distributed with a MSI file or (2) can have multiple versions, I think the 'references.addFromFile' is the only solution that can apply. Example:
You have an VBA/Access runtime client
app that needs to refer to Word
(msword.olb file).
For licensing issues, you cannot freely distribute this file with your msi pack
the olb file can be either the 'XP version or a newer one
Our solution is to have 2 tables on the client Access file. One lists all the references that have to be checked or added at startup time (Word will be one of them), and the other one lists all the possible locations of the file (depending if the user has the 'office11' version or a newer one), with a one to many relations between the 2 tables.
So, the best strategy could be a mix between msi packs and management through code:
msi is great for distributing independant dll's or other files that are totally 'embedded' in your app, such as activeX controls (like scanners controls, report or file viewers, etc)
code is the best solution where your app will have to communicate with other applications (word, excel, outlook, etc) that can exist in different versions on your user's machines.