VB.net Setup Issue - vb.net

While creating the setup for VB.net application I am getting the following warning:
"Warning 1 'msado15.dll' should be excluded because its source file 'C:\Program Files\Common Files\System\ado\msado15.dll" is under Windows System File Protection.
Please suggest me how to over come this type of issue.
Thanks,

This is a classic case of IDE components not talking to each other.
One component says "you reference msado15.dll in your code, therefore I should include it in the project".
An unrelated component says "msado15.dll is on my list of protected DLLs, therefore I should warn you not to include it".
However, no component thinks like a human and says "hang on, this DLL is part of the framework, therefore I should silently remove it from the installer".
It's up to you to do the last part yourself.

That means that file is normally already on the operating system, so it should not be necessary to install it. If you remove the user's original protected file in your app uninstall, it can cause problems on the user machine.

Related

Getting out of DLL Hell with Microsoft.VC90.CRT?

I've built a inproc com server dll which I can package as 1 file or many via the build utility py2exe. When I allow all the dependencies to remain external, I have no issues, but bundling as 1 file produces problems.
When the dll is utilized (either registering it or instantiating a com object from it), it immediately loads MSVCR90.DLL from the path c:\windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6871_none_50944e7cbcb706e5\MSVCR90.DLL no matter what I do, I can't change that. There is no information that I can find (using Dependency Walker) to indicate what is causing that to load. It just happens magically...
Then, later on it loads that dll again via an explicit call to LoadLibraryA("MSVCR90.dll") (part of some py2exe black box?), but this time it does not look into the winsxs manifests / directory. Instead it looks to the system path and/or will respect a dll redirection. That's when the problem occurs. If I set the system path to start with c:\windows\winsxs\x86_microsoft.vc90.crt...\ it will load the exact same dll and be happy - but if ANY other file is utilized - inclusive of a copy of the EXACT same dll - but at a different path - then the whole thing blows up. It can't handle using two different files.
How can I fix this? Ideally, I've love to make the initial magic loading of the dll draw upon a private assembly, but no matter what I do with manifests or .dll.local etc it will not respect that until this second dll loading takes place.
Note that with the non-bundled dll (external dependencies) it always uses the winsxs MSVCR90.DLL.
I can "fix" my failure to use the dll by forcing the system path to load the winsxs copy, but that is pretty useless for a deployable com server!
The reason is that you DLL has a manifest that tells the module loader to search also in the SxS storage.
You have several choices
Build your DLL using static linkage. Not using any of the MFC-DLLs (see project settings)
Don't use a side by side manifest for the DLL and still use the MFC DLLs. But beware you have to ship those DLL with your DLL in the local path (see DLL search sequence docs)
Use a later build of VS. Later versions of VS don't use the SxS storage any more and there are no manifests for those DLLs any more.
For the 2. see this article in code project. There is an update for VS-2008 [here].
2
Build your DLL

Is File.Open directory behavior different in x86 vs x64

I am working on a application built in VB.Net that allows a document to be uploaded and saved into a database. I did not build this application, but I do maintain it, put enhancements in it here and there. The target framework is .Net4
One of the functionalities within this process when uploading and saving the document it uses the method File.Open() to access the file and run other methods to compress it. The method that uses File.Open takes in a parameter that passes just the filename, not the entire path of where it came from.
When this application is running on an x64 machine I receive an error (System.IO.FileNotFoundException) when the code hits the File.Open method, complaining that it cannot find the file to open. It is expecting the file to be in the programs executing directory, which does make sense because it is only given the filename to go off, not the entire directory that it came from.
What's getting to me, is that this exact same application (exact same built assemblies) will run fine when run on an x86 system. It does not fail on File.Open() It still passes just the filename, but somehow, it will know the directory information.
How is this possible?
It's worth noting, that the method that contains the File.Open() method is in a different project in the same solution. It's a referenced DLL. e.g. MyApp.exe (Windows Form Application) references MyUtil.dll (Class Library). I have built against x86, x64 and AnyCPU configurations.
I understand that the fix to this would be to just pass the entire directory to the method, but what I need to know is how this is even possible? I want to better understand why this would happen, and hopefully this would help someone else better understand how assemblies may differ between different system environments.
EDIT: Using an absolute path did fix the underlying issue. See the comments below for some good information on this scenario
Windows has special handling for certain folder names on 64bit systems depending on whether you have a 32bit or 64bit process. Notably, the Program Files folder and the System32 folders map differently depending on what kind of process you have.
Note that this is a difference in Windows itself. It's not a behavior that is unique to .Net or Visual Basic. Any program platform that uses Windows native file handling will give you these results.
This is why you should use appropriate relative paths or the SpecialFolders enumeration, rather than hard-coding full path names, and be careful about where you put things you expect to reference later; you might find they end up in a different location than you expected. Often, the AppData or ProgramData folders are the more correct location, instead of the Windows or Program Files folders.

regsvr32 Custom ocx file not Registering

I've been asked to install an old VB program on an XP computer, but when I do I get an error when I run the program saying that Component 'filename.ocx' or one of its dependencies is not correctly registered: a file is missing or invalid.
This is a custom file (I did not create it), I have tried regsvr32 and I get no error messages but no successfully registered messages either.
This program also runs on another computer which this ocx file is not registered but opens without error. So my question would be what could cause the file to not be recognized by regsvr32, and run on another client with the same os, but without error. Any ideas, or new paths to look into would be very helpful.
Also if you dislike something about this question, let me know what it is, so I can fix it in the future. Down voting a question gives me no insight on why this upsets the community, it just discourages me to want to help others in areas I do understand.
If you do get the error "Component 'filename.ocx' or one of its dependencies is not correctly registered: a file is missing or invalid" from a custom dll or ocx file, it may just need that file and its dependent files in the directory that your running the executable, as was the problem in my case.
After adding the file to the root directory, and not registering any files the program opened fine. Maybe this helps someone else.

libc.dll files is required but can not find it

I am trying to publish my application using installShield utility. Every thing works fine but it gives warning that it asks for two files:
libc.dll
Flash32_11_7_700_224.ocx
Those two files are prerequisite according to the package but I could not find them.
I tried to search in the web for those two files with no luck.
Can any one help in this?
Explanation of Error
This error can be encountered in Flexera's InstallShield. The specific error is:
ISEXP : warning -6248: Could not find dependent file <dependent file>,
or one of its dependencies of component <component>
The official troubleshooting information from helpnet.installshield.com did not help me, but it says to:
Use the "Build Tables & Refresh Files" option to build the release
if the release location is in <ISProjectDataFolder>
or <ISProjectFolder>. For more information, see "How the Run time
Locates Assemblies", available in the .NET Framework SDK help or on MSDN.
Workaround
If the application works fine, and you just want to get rid of the warnings, you can follow this Stack Overflow Q&A.
(InstallShield, Installation Designer, Left Panel) Specify Application Data > Files
(Destination computer's files panel) Right click primary output > Dependencies from scan at build... > Uncheck dependencies you do not want
The above picture from the Stack Overflow answerer #Tom Wilson shows what you should see. Note that primary output was the central .exe of my project. When I used this technique on my primary output, the other components in my project were also fixed.
Resolution
If this problem is crashing your application, and not just an annoying warning...
In the case of libc.dll, I would direct you to add Redistributables to your project.
(InstallShield, Installation Designer, Left Panel) Specify Application Data > Redistributables
For instance, I use Microsoft .NET Framework 4.7.1 Full.
I believe this solution will work for libc.dll, but cannot verify. I base this on reading support.microsoft.com, which I think implies libc.dll is contained in C Run-Time (CRT), which I would also believe is part of the .NET Framework.
In the case of flash32_11_7_700_224.ocx, I would direct you to System Software Requirements. This ocx is installed with many Adobe products. You may want to prompt the user that they need to install this, at the time software installation.
(InstallShield, Installation Designer, Left Panel) Define Setup Requirements and Actions > Requirements
(Central Panel) System Software Requirements > Right click > Create New Launch Condition (System Search Wizard)
Follow the wizard there to block installment if it does not exist, or use one of the premade requirements if that helps your case. Tip: remember to supply a link to Adobe in your prompt, so your end-user can quickly download it!

WIX: COM registration fails when installing COM dll into another folder

I am using heat to harvest the COM dll and tlb files (let's call them MyLib.*, developed in VB.NET) to do the COM registration. Everything was working fine, when I install MyLib.dll and MyLib.tlb into my application's installation folder, i.e., INSTALLDIR. However, since we want to allow different versions of our SW to be installed on the same machine, and if they are using the same version of COM component, only one copy of the dll (I think each version of our SW should have its own tlb, please correct me if I am wrong) should be installed, we now want to install MyLib.dll into another folder, specifically PROGRAM_FILES\Common Files\SHARED_FOLDER_NAME, so now if one version of our SW is uninstalled, the MyLib.dll will not be removed and can still be used by other versions.
But here comes the problem: my COM registration is just simply not working any more after I install this dll into this another folder, and it keeps saying that can't find file specified when I am calling the COM function which indicates registration failure. In the WIX installer project, everything is the same except this folder for MyLib.dll.
Here is the registry structure after installation:
Firstly I have HKCR\CLSID{MYCLSIDs}, each of them represents one of my COM class. in the sub-key named "InprocServer32", I have Assembly, Class, CodeBase, RuntimeVersion, threadingModel. And the CodeBase is either common file folder (not working) or MyApp's installation folder(working), which is the different locations I put the dll. I thought there would be another sub-key TypeLib under {MYCLSIDs}, since Access only sees the TypeLib and I think there should be some link from the TypeLib to the actual dll, however, at both cases this sub-key is missing but in the second case it is still working. Is there a problem of it?
Secondly I have HKLM\Software\Classes\CLSID{MYCLSIDs}, these keys are of course the same structure as described above.
Thirdly, the HKCR{MYPROGIDs}, these are just ProgIDs of my classes
Fourthly, HKCR\Typelib{LibID}, which includes the information from tlb file, and this ID is from the Assembly GUID of COM component project.
Finally, the HKEY_CLASSES_ROOT\Interface{InterfaceID}, there is sub-keys named ProxyStubClsid32 with value {00020424-0000-0000-C000-000000000046}, and the one named TypeLib and the value is my LibID.
As I mentioned, the only difference is the CodeBase, which stores where MyLib.dll is located. In order to verify that, I did two tests: after I install MyLib.dll into the shared folder, the COM calling fails. But if I replace all the CodeBase values for SHARED_FOLDER\MyLib.dll to INSTALLDIR\MyLib.dll, and copy MyLib.dll into INSTALLDIR, it actually works. Vise versa, after I install MyLib.dll into INSTALLDIR(in which case COM is working), I change the CodeBase values from INSTALLDIR\MyLib.dll to SHARED_FOLDER\MyLib.dll, and make a copy to SHARED_FOLDER, this time it fails. So it seems that it is exactly the installation location's problem, which is the opposite to my understanding of COM. And I don't think there is a permission issue for the SHARED_FOLDER(I could be wrong) since it is in a folder that my installer creates.
Please help, thanks!
It turned out that MyLib.dll is using some other libraries, which are still installed in the MyApp installation folder. And so in that case that MyLib.dll is installed in the shared folder, it tries to find those libraries in the same libraries, which of course fails. When I install those libraries in the shared folder too, it is working.
BTW I found fulogvw.exe very helpful when tracking down the assembly loading problem. For example in my case in the failed log it says can't load file xxx.dll in SHARED_FOLDER, the xxx.dll is some library that MyLib.dll is using, and I had no idea that MyLib.dll needs it until I see the log.