Check whether the DLL is used by another application - installshield

I'm registering capicom.dll through my installer and unregistering it while uninstallation of my product. There is another third party software "ABC", also registers and uses this DLL.
But the problem is, when I uninstall my own product, I unregister capicom.dll. Because of this the another third party software "ABC" is not working properly.
So how I can check if this DLL is used by another product/application while unregistering it?

There is no great 100% answer to this problem. There are various conventions, depending on the underlying technology in play, that try to address a related problem. These include:
The SharedDLLs registry key, which tracks reference counts
Windows Installer component counts (if multiple .msi packages install the identical component, such as from a merge module)
Other package-level reference schemes
Never uninstalling from the System folder
However these only work when there's a single location for a given file. In your case, reading between the lines, I suspect there are multiple file locations for capicom.dll, but only a single registry location for its COM registration. Thus when you install your copy, you may be overwriting existing COM registration. While your copy is in place, all is well. But when you remove your copy, and/or unregister it, the COM registration does not revert to the previous copy.
Assuming you cannot ensure there's only a single file copy of capicom.dll, the best option I can think of is to use a registration-free COM manifest on your executables that references a private copy of capicom.dll, and skip registering your private copy of capicom.dll. InstallShield can help you create an external manifest, or you can instead create and embed the manifest in your executables yourself. Take additional care to verify that the activation context works if you are exposing inproc COM servers yourself that need to load capicom.

Related

How should I go about using a temporarily changed copy of a DLL locally when it's been checked in to TFS?

We have a Libraries folder where we keep third-party DLLs and our own utility DLLs for all applications to reference. I want to do development against one of our utility DLLs and an application that consumes it at the same time. But if I check out the library DLL to change it for temporary local use, TFS insists on checking it out exclusively, which trips other people up. I understand the reasoning behind it doing that (hard/impossible to merge a DLL, so two people shouldn't be working on one at the same time), but I just want to mess with my local copy while I'm working on the library it represents.
I suppose I could delete my application's reference to the DLL and recreate the reference pointing to some other place, but of course this just begs for me to forget and check it in like that, which would obviously be bad. Not to mention that this is a pain in the neck.
How should I proceed in such a situation?
You are using a server workspace that does not allow editing outwith TFS. In TFS 2012 local workspaces were introduced which do not have a read only flag for files and you are free to edit at will.
You can change your existing workspace in a few clicks: http://msdn.microsoft.com/en-us/library/bb892960.aspx
You could just go into the file system and mark the file as writeable. Once you are happy the binary is good you could check it out, copy the new version of the file over and check it back in again. TFS marks binary files like this as locked for good reason, as you can't merge them in the way you can with textual content.
The best approach would be to use a NuGet repository to manage your binary dependencies, instead of relying on binaries checked into source control.

Missing dll when deploying ClickOnce

When I publish a ClickOnce application, one of the references that is included in one of my projects is missing.
If I go to my project's Properties -> Application Files, this missing reference is not even listed here.
My bin/Release folder has an .exe.manifest file, and I noticed it that it is also missing from here.
However, when I build the project, the DLL is in fact copied to my bin/Release folder.
How can I ensure it also deploys this required dependency?
I finally found a solution for this problem and I hope it will solve your problem to.
In my case, I'm editing an old application at work which have multiple projects, but the main project and it's back end project are the most important here.
The back end is added in the References section of the main project.
In the back end, a third party dll was imported, but this dll requires 2 other dlls.
So those 3 dlls were added in the References section of the back end project.
At that point, one of the 2 other dlls was not showing in the Application Files section for ClickOnce.
I've come up with a couple of ways of fixing it, but the most elegant one was to add this dll in the Reference section of the main project.
As stated in How to: Specify Which Files Are Published by ClickOnce, change the Copy Local property value on the reference to True.
References to assemblies (.dll files) are designated as follows when you add the reference: If Copy Local is False, it is marked by default as a prerequisite assembly (Prerequisite (Auto)) that must be present in the GAC before the application is installed. If Copy Local is True, the assembly is marked by default as an application assembly (Include (Auto)) and will be copied into the application folder at installation. A COM reference will appear in the Application Files dialog box (as an .ocx file) only if its Isolated property is set to True. By default, it will be included.
I know is this an old question, but for anybody having similar issues. I think this is a cleaner way around the problem.
I had a similar issue and everything I did to get ClickOnce to deploy with the offending .dll failed.
Eventually, I had to deploy manually.
See walk-through here.
That worked for perfectly for me. But, for the life of me, I still wonder why that process can't be added to VS (I'm using 2017 community).

Detect Visual C++ runtime without registry permission

I need to find all Visual C++ runtime installed on a machine. The exe will be run by a user who is not in the administrator group.
All solutions I've found rely on registry keys or scanning the c:\Windows folder (which I don't think is very reliable). In addition, if user cannot read the registry, chances are they don't have permission to access the system folder either.
Q1. Is there a 3rd method?
Q2. If multiple versions of VC++ are installed, is there a way to determine which one is used when an application is executed?
A1: Depends on what you mean by "installed". If you mean "used by some application", then even those methods won't tell you. If you mean "automatically found during application loading", then you really have to check the registry settings used by the loader.
A2: Sure, check whether the application imports MSVCRT80.DLL or MSVCRT90.DLL, etc.

Unable to deploy my custom DLL to Sharepoint site

I created my custom assembly that has a simple HttpModule in it that I'd like to use in my Sharepojnt 2010 site.
I added my module to sharepoint site's web.config/system.webServer/modules section.
I then also copied my DLL directly to bin folder since that's how suual asp.net applications work. I got an exception about failed AspNetHostingPermission.
I copied the same DLL to _app_bin folder and it worked. My module did get initialized and was running.
I then added two permissions to my module class:
[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
and also added these two to assembly
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
[assembly: AllowPartiallyTrustedCallers]
and strongly signed my assembly with a key I created.
Then I copied the DLL back to bin but it still didn't work. Copying it to _app_bin worked.
What do I have to do, to deploy my DLL directly to bin folder?
The problem you're running into is that SharePoint is using Code Access Security (CAS) to make it possible for really well educated Admins to make sure that they don't put their environment to unnecisary risk when adding functionallity to it.
The problem is then that even though CAS has been in .Net since the beginning nearly nobody has used it before SharePoint, so most developers don't know how to deal with it.
Everything in _app_bin is running with full trust, which explains why your dll works there.
Everything in bin is running with a lot less trust depending on the trust level specified in web.config (in fact this is also the one that specifies _app_bin has full trust, but thats common in all of the out of box trust levels).
In order to get your dll to work from bin (without changing trust level to full which is bad) you need to modify the policy file which the trust level is pointing to with the right xml for the right your dll need.
Adding the attributes don't help you directly, initially they in fact just makes the problem worse, because now your dll demands the rights even though it might not call anything which requires them.
Where the attributes help you is if you use WSPBuilder to build your WSP package for deploying to SharePoint (You're using a WSP right), then it'll look for security attributes and make the corresponding entries in manifest.xml which then get SharePoint to add the corresponding entries to the policy file on deployment.
In order for you attributes to work with WSPBuilder I think they have to be changed to SecurityAction.Demand though.

How can we protect ourselves from other third parties installing DLLs with the same names as some of ours into C:\WINDOWS?

Our product includes several DLLs built from open source into files with default names as delivered by the open source developers. We're careful to install the files in our own directories and we carefully manage the search path (only for our processes) to keep the loader happy.
Another developer -- a towering intellect -- decided it would be easier to install their own build of some of the same open source into C:\WINDOWS under the same default DLL filenames. Consequently, when we launch a process which depends on these open source DLLs, the system searches C:\WINDOWS before our directories and finds the DLLs installed by the other developer. And they are, of course, incompatible.
Ideas which have occurred to me so far:
rename all our DLLs to avoid the default names, which would only make
it less likely we would encounter collisions
load all our DLLs by full path so the loader captures their names into
RAM and doesn't search anywhere else the next time they are requested
For various reasons, neither of these options is palatable at the moment.
What else can we do to defend ourselves against the towering intellects of the world?
You've got only two options: deploy the DLL in the same directory as the EXE (that's where Windows looks first) or using manifests and deploy the DLL to the Windows side-by-side cache. I don't think the latter option is common in the Open Source world but it is the only real fix if you want to share DLLs between different apps.
To add to the already excellent answers, you have a couple more choices:
The preferred solution(s) to this problem, supported since Windows XP, is to turn your dll's into a win32 assembly (They don't have to be .NET but the documentation on creating win32 assemblies with strong names is appallingly light so its easy to get confused and think this is a .NET only technology).
An assembly is noting more complicated than a folder (With the name of the assembly) containing the dlls and a .manifest (With the name of the assembly) that contains an assemblyIdentiy element, and a number of file nodes for each dll in the assembly.
Assembly based searching works even when dlls are statically linked!
The easiest option is to create unversioned assemblies and store them in the same folder as your .exe files (Assuming all your exe's are in a single folder).
If the exe's are in different folders, then there are two ways to access shared assemblies:
You can store your assemblies in a private alternate location if you expect your application to be used on Windows 7 and higher. Create a app.exe.config file for each of your exe's, and point a probing privatePath element to a common folder where you are storing the assemblies.
If you are ok with requiring administrative access to perform installs, (via MSI's) then you can deal with the appallingly bad documentation (well, absent documentation) that deals with giving your assemblies a strong name, and then store the assembly in WinSxS.
If you can't, or do not want to bundle your dlls as assemblies then this page covers dll search order
Using functions like SetDllDirectory are only going to help for dlls loaded dynamically at runtime (via LoadLibrary).
Dll search order used to be:
Directory containing the process exe
Current directory
various windows folders
PATH
Which you could have used to your advantage - launch each exe, setting the "current" directory to the folder containing the OSS dlls.
With the advent of SafeDllSearchMode the search order now is:
Directory containing the process exe
various windows folders
Current directory
PATH
Meaning theres now less control than ever :( - It goes even faster to the "untrusted" c:\windows & System32 folders.
Again, if the initial dll is being loaded via LoadLibrary, and its the dependent dll's that are the problem, LoadLibraryEx with the LOAD_WITH_ALTERED_SEARCH_PATH flag will cause the following search order (Assuming you pass a full path to LoadLibraryEx) :-
Directory part of the Dll path passed to LoadLibraryEx
various windows folders
Current directory
PATH
The directory from which the application loaded is normally the first directory searched when you load a DLL. You can, however, use SetDllDirectory to get the "alternate search order". In this case, the directory you specify to SetDllDirectory gets searched first.
There is also a SafeDllSearchMode that affects this to a degree. Turning it on excludes the current directory from the search.
Maybe just compile them to a static library?
Why not?
Also, the current directory, where the exe is activated from is searched before c:\windows.

Resources