Changing the location of an existing VBA Reference from C:\Windows\system32\ to a shared drive - vb.net

I've been trying for a while now to get a reference file to be loaded externally to no avail.
To be specific I am trying to load a "Microsoft Date and Time Picker Control 6.0(SP4)" which usually resides in C:\Windows\System32\MSCOMCT2.OCX
However some people that run a macro containing this element don't have that "MSCOMCT2.OCX" file on their PCs so I thought I will move the MSCOMCT2.OCX to a shared location and reference the code to use the shared one instead (so everyone will have access to it)
I tried doing that but when I was trying to load a reference with "Browse" from a different location it didn't load it - because I already had that in C:..
So I thought OK... I will remove the file from C:\ so I can only reference the shared file. - so I deleted it.
So I open the workbook again and look at references - I cant find "Microsotft Windows Common Controls-2.6.0(SP4)" - great!
And I proceed to add it manually with Browse from the shared drive.
When I do that however 2 references of "Microsotft Windows Common Controls-2.6.0(SP4)" are being added - 1 from C:\(which is not there) and 1 from the shared drive.
The one from C:\ is always automatically selected.
If I try to disable the one from C:\ and enable the one from the shared drive it automatically changes back to what it was when i press OK.
If I try to enable both - it says duplicate References and keeps only the one from C:\
So.. does anybody know how can I get rid of that C:\ reference from the list so it doesn't get loaded? Apparently deleting the files themselves did not work.
Ultimately my goal is to enable people without C:\Windows\System32\MSCOMCT2.OCX file to be able to use my Date Picker Tool.
Thanks a lot!

ActiveX control rereferences are always GUID-based. The VB IDE shows you the current location of the file as listed in the registry on your computer, as a courtesy, but it really doesn't matter what it says. The control will be loaded from wherever it was registered on the user's computer.
That's the key: the control must be registered on the user's computer.
I must strongly discourage you from doing what you're trying to do. You might be able to concoct a method by which you load the DLL from a network location, but it presents no advantage over doing the Right Thing(TM), and plenty of problems. The Right Thing is simply that if you need that control, you must distribute and register it with your application, just like everybody else does. And you really should install it in the recommended location for it (System32); not on the network.
Here's a quick example of what can go wrong: you provide your user with you app, and it works with the control on the network like you want it. Then the user installs another application that happens to need the same control. The app's installer sees that the control is already registered on the user's computer, so it doesn't try to add it again. Except that this particular app is intended to be used when the user is not connected to a network. Now you just broke someone else's program.
The VB/VBA architecture was never intended to support XCOPY deployment. I'm know it's a pain and that these extra steps are extremely inconvenient when you're just trying to deploy a "macro". Sadly, it's the nature of the beast. I'm sorry

Related

Debug .NET com dll when running from Access

I have a com dll developed in VB.net that provides an interface to eBay api's. Been working for many years. Recently eBay change certificate authority and moved to TLS 1.2. Sorted through that but now the dll seems to quit in mid transaction when called from Access. The functionality does listings from local inventory to eBay. The first part loads pictures of the listing item to eBay. That works fine. I can see the calls and responses using Fiddler. It then moves on to actually listing the item which seems to stop when called from Access. What I get back in Access is "Can't find x.dll at file location". I know the call is going to the dll because it uploads the pictures.
I have a test project developed in VB.net to test the dll and when run from that everything works. I can see the listing call and response in fiddler. When run from Access there is no listing call. I can verify that the endpoints for the calls are the same from test project or Access.
My question is how to debug the dll in the Visual Studio IDE when it is called from Access. Any thoughts?
Yes, the way you do this is open up the vs class you have for the .dll.
Then in debug of the project, setup this:
Now, when you hit f5, then access will launch and run.
If at this point, say you close access (exit), then you note the debugging process stops.
However, go though the forms and whatever in Access, and get to the point where you hit that button or whatever.
You find now that you can say set a break point and even step and debug your .net code like any other code. So say in my example (a custom sage 300 .net interface to access), I want to debug "find customer" routine from VBA.
Well, in vb.net I have this code:
so, when any routine - even those in the class instances is called, you can set break-points etc.
And to stop? Just exit access.
So, you can make a change to your code, and even hit f5.
It not clear how you are registering your .dll (or do you use some VBA to side-load the .net - that's what I do, since it is a pain to have to register my .net com objects on each PC.
But, do give the above a try. It should let you debug your .dll code. The trick is to have VS launch ms-access as a attached debug session - and that is exactly what the above setting in your class project above allows you to do.
do note in above, I used the path to access 2010 (access 14), so replace the path name to the access.exe with your version of access you are using.
And keep in mind, that if have some installer, or some custom "thing" that registers your .net .dll for you?
Well, during this process, if your VBA assumes a registered com object, then ensure you have this check box enabled:
On compile for the project settings, you thus want this option checked:
NOTE very careful, checking the above option does not change the code or anything at all - it ONLY does a regasum automatic for you, and this would of course re-register your existing .dll - which is what we want for debugging. After you done, do run your re-register of your .dll to switch back from the debug .dll that going to be in your current project bin folder to whatever you "regular" use on your PC.
FYI:
In MOST cases, I find this whole idea does NOT work unless you launch VS as administraor. So, make sure VS is being run as administraor for this to work.
I tend to just tap windows key, or even right click on your vs shortcut, and of course choose run as administraor.
This is so often required, you note that VS will EASY and quite CLEAR show you running in admin mode, and I quite much now always run VS this way.
You should see this:

Check and Notify non-existence of Microsoft.VisualBasic.PowerPacks

In a simple windows form application on VS 2010 I have put a ovalShape using power packs.
The simple Form
Now automatically this action puts the reference of Microsoft.VisualBasic.PowerPacks.Vs in to project properties.
when deploying this in different PC obviously the (a)powerpacks needed to be installed if this application doesn't work, (b) or it can set to "copy local = true" in reference properties so that it should sit to next with the application.
assuming (b) is not an option, since it is a solitary executable, (a) is the only option. in this way if the target machine does not have powerpacks the requirement is to notify it to the user in the first place.
apparently the dll will be deployed in when using the "VisualBasicPowerPacksSetup"
C:\Windows\assembly\GAC_MSIL\Microsoft.VisualBasic.PowerPacks.Vs\10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.PowerPacks.Vs.dll
so the blind approach is just to check if the above file not exist then prompt user to install "VisualBasicPowerPacksSetup". but i feel its more accurate if the application able to actually check in registry level.
in registry "Microsoft.VisualBasic.PowerPacks" records in several location, thus makes a confusion.
how to identify the correct key and what should be correct way of checking this reference in vb ?
You could just try to create an object defined in the dependency and catch the resulting exception.
Handling this you could ask the user to install the package. This is probably not considered good practice but should get the job done.

Custom Building Block Template wont load reliably

My small collection of document-specific macros and quickpart building blocks is growing! I'm starting to share these with employees, and am looking to be able to set up each remote computer once only. From there on, update collections on a network path. And because each computer looks to the shared location, everyone should always be working with up to date macros and quickparts etc.
So. What I already know:
- Required macros are saved in a separate module, ready to be shared/exported.
- Macros themselves occasionally reference local paths on my computer.
- I will need to reference paths with generic code or use Environ variables.
- Building blocks and quickparts are saved in a separate template file (currently located in Appdata, along with default building block file).
What I dont know:
a) How to point Word to a network path to retrieve macros from custom macro files. (Would I just have to import a fresh macro file at every important update, on each PC?)
b) What's the best way to load a building block item from a CUSTOM path?
My custom BuildingBlock template file is not loaded properly on occasion:
Dim objTemplate As Template
Dim objBB As BuildingBlock
'set template to store the building block
Set objTemplate = Templates("C:\Users\[USER]\AppData\Roaming\Microsoft_
\Document Building Blocks\1033\CustomBBlocks.dotx")
Set objBB = objTemplate.BuildingBlockEntries.Item("[EntryName]")
I know this because the code spits out a 'CollectionDoesntExist' error unless I click the Quickparts gallery prior to running the code for the first time. So it's like Word cant be bothered to open the template file and look inside unless I do it from the UI first.
Of course, if I first open the Quickparts gallery from the UI, prior to running my code, Word seems to figure it out, and inserts the correct Building Block entry without any issue.
In the past I've worked on a product that allows building blocks for Word too. Some sites have hundreds of templates and maybe 1.000 elements (see Composition). The approach we've taken was successful and was different.
You are trying to deploy software elements (macros) across a large number of workstations. You can try to get it working using the possibilities of Microsoft Word and Windows, but it will be sensitive to problems when things change. For instance, switching to Office 2013, splitting a domain into two, work at home without VPN, etc.
Option 1 - DIY deployment: Better put the macros and other stuff behind a webpage, webservice or alike. Deploy on each workstation a generic program that pulls in everything and deploys it locally. You might want to hand over some parameters to the webpage being called to restrict the amount of data. You might want to cache things locally.
Option 2 - Use ClickOnce: write a clickonce deployment script, include the necessary references and put it on a shared network drive or http address. ClickOnce automagically upgrades your software when it finds a new version. It even works across the internet. And it does nothing when there is no new version.
Option 3 - Database: put the elements centrally in a database, allowing end users to change building blocks through forms. Have Microsoft Word in combination with a ClickOnce program pull them in.
For Composition we've used option 2 and 3.

vb.net sequential file access

I'm working on finding a way to monitor a folder's files.
I want to get information on what files are used the most in a folder.
I've looked into using vb.net FileSystemWatcher but it doesn't seem to contain any classes for this. The articles I've found don't mention anything functions like this. I found one forum that said to use the timestamp from LastAccess in FileSystemWatcher. But the description doesn't really match that function.
Is there a way in vb.net to do this?
The FileSystemWatcher is indeed the class you want to use.
The msdn documentation contains an example of how to use it.
Just ensure you are setting the NotifyFilter to use the LastAccess filter:
watcher.NotifyFilter = NotifyFilters.LastAccess
This way you could create an application or service that monitors your folder and count how often each file is accessed.
But to have this work, you have to have the Last Access Time functionality enabled. By default, this is disabled on Windows Vista and up.
You can enable/disable this by either using this registry key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate
or by simply running
fsutil behavior set disablelastaccess 0
from a command prompt with administrator rights.

Cannot register an ActiveX control on only one computer

I have run into an odd problem while attempting to register a vendor-supplied ActiveX control on two different computers. On one computer, I can register the part using regsvr32, and then use it in an Access 2007 form with no problems. On the other computer, after I register the same DLL, it is simply not recognized as a valid ActiveX part by Access 2007, or any other Office 2007 program.
The ActiveX part is contained in a single DLL. I am not missing an additional file on one of the computers.
I cross-checked the exact version of the DLL on both computers using md5sum. Both DLL files are exactly identical.
I cross-checked all of the registry entries generated when the part is registered, using the Nirsoft ActiveX Helper utility. The entries are identical.
I checked Access to make sure that the part had a reference entry which pointed to the DLL.
I checked that the location of the DLL was specified as a Trusted Location in Access.
Unfortunately, I am not enough of a COM expert to know whether or not I am overlooking something odvious. Any additional ideas would be appreciated.
OK, total shot in the dark, but we have some computers in our organization the the IT has locked down pretty tight. When we run setup's they run OK and register our ActiveX components, but the first time we run the program it has to be as an administrator. After that the normal user is able to run the program.
You could try a simple VBS script to verify that the control can be created.
Using Notepad (or similar) save the following as test.vbs, and then double click it to run it.
set oTest = CreateObject("<YOUR PROGID HERE>")
MsgBox ("All Done Successfully")
You should get an reasonably descriptive error or "All Done Successfully".
This would at least point to whether its a system wide or Office specific problem.
And if you get an error it may well point to the actual problem.
OTH, if you don't get an error then you probably have an Office installation issue - which could be resolved by a re-install.