How to tell which application(s) have a given assembly registered in the GAC? - gac

When trying to remove a given assembly (log4net.dll in this case, but it should apply to any similar case) using gacutil.exe, the action fails due to the assembly being required by an application. However, I can't figure out how to tell which application(s) actually require it. Since the output seems to indicate that the requirement is logged in the MSI database / Windows Installer, it would seem like some util would be able to either list all the GAC assemblies registered in the MSI database (and I could just search for entries with log4net.dll) or allow me to specify a particular GAC'd assembly and it would list the dependencies (ideally with any related dependency chains if they exist :)
C:\ ยป gacutil /u log4net
Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly: log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL
Unable to uninstall: assembly is required by one or more applications
Pending references:
SCHEME: <WINDOWS_INSTALLER> ID: <MSI> DESCRIPTION : <Windows Installer>
Number of assemblies uninstalled = 0
Number of failures = 0
Thanks!

I never found anything good for this. What I did (that worked, but sucks) was to run procmon to see what gacutil was accessing and noticed it hit a key HKCR\Installer\Products\098D637EEF1AFF14586E779FE4C38C4D. When I looked under that key in regedit, it showed that the product was "Plantronics Spokes Software".
I went into appwiz.cpl and removed that app, then afterwards gacutil /l log4net showed that log4net wasn't in the GAC anymore.
I'd still love to find out a better answer, but I guess for now 'run procmon, filter to process=gacutil.exe and path under HKCR\Installer\Products' is at least better than nothing.

Related

SSIS 2016 Visual Basic Component Runtime Failure: "The system cannot find the file specified. IBM.Data.Informix.4.0.410.02

I'm struggling to find any meaningful information on this issue so any thoughts would be greatly appreciated.
I have a SSIS 2016 package that has a Visual Basic Script Component that requires connectivity to a remote Informix database via an ADO.Net connection. The necessary project reference to the IBM.Data.Informix.dll has been added and the project builds without error. However when the package executes a runtime failure occurs:
"Could not load file or assembly 'IBM.Data.Informix.4.0.410.02, Version=4.0.410.2, Culture=neutral, PublicKeyToken=7c307b91aa13d208' or one of its dependencies. The system cannot find the file specified.":"IBM.Data.Informix.4.0.410.02, Version=4.0.410.2, Culture=neutral, PublicKeyToken=7c307b91aa13d208"
I have tried some of the suggested solutions I have come across including setting the reference property, "Copy Local = False" as well as repointing the reference to the various versions of the installed dll. File locations include the GAC, "C:\Program Files\IBM Informix Client SDK\bin..." and "C:\Program Files (x86)\IBM Informix Client SDK\bin...". Both 32 and 64 bit versions are installed and the dll files do exist in the referenced locations. All attempted solutions failed.
Any suggestions where I can go to from here?
Thanks in anticipation.

How to check GAC assembly details on Windows Server 2012?

How can you check GAC assembly details Windows Server 2012? I managed to register a DLL via Powershell, now I need to verify that it is really done.
You are probably looking for the custom look of the GAC directory that you were familiar with in .NET versions prior to 4.0. Which stored the GAC in the c:\windows\assembly window and used a custom shell extension to flatten the directory structure into a list of assemblies.
The shell extension is no longer used for .NET versions 4.0 and up. You have .NET 4.5 on that machine, its GAC is stored in c:\windows\microsoft.net\assembly. You just get to see the actual directory structure. Locating the assembly isn't that difficult, start in the GAC_MSIL directory and you should have no trouble locating your assembly there by its name. Locate the folder with the same display name as your assembly. It will have a subdirectory that has an unspeakable name that's based on the version and public key token, that subdirectory contains the DLL.
If your assembly is a mixed-mode assembly created with C++/CLI then you'd start from either the GAC_32 or GAC_64 directory.
just try with this path
C:\Windows\Microsoft.NET\assembly
An option would be to use PowerShell. I've created a PowerShell module which allows you to see and manipulate the GAC contents. You can find it here.
# Show the assemblies in the GAC, including the file version
Get-GacAssembly SomeCompany* | Format-Table -View FileVersion
The gacutil.exe has a parameter to do this. If you run
gacutil.exe /l
You will get a list of registrations.

How do I use COM reference within SSIS package?

I'm trying to use the Microsoft Shell Controls And Automation COM object library (C:\Windows\System32\shell32.dll) from within an SSIS Script Task to manipulate .zip archives.
Unfortunately, although I have successfully added the relevant Reference and the Script Task compiles OK. I'm using VB.NET, for what it's worth. I get the following runtime error as soon as I try to create any objects defined within the library:
Error: 0x1 at Archive File: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: Could not load file or assembly 'Interop.Shell32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'Interop.Shell32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
at ST_a2650b7f39504eaa8c80e37a6736d957.vbproj.ScriptMain.Main()
I thought the Interop DLL would all be taken care of for me - does anyone know what step am I missing?
SSIS needs all .dll references to be registered with the GAC, you are correct.
You have different options regarding installing this dll into the GAC:
Drag and drop the .dll into the %windir%\assembly\ folder.
Use the gacutil.exe you are thinking about using: Regarding installing into the GAC using the gacutil, there is alot of useful information here: Global_Assembly_Cache. Basically, if you have the .NET framework installed (you are using VB.NET so no problem there), you will have a gacutil.exe in your Microsoft.NET folder.
(What I normally use when all else fails) Create a windows MSI project in Visual Studio that automatically does all this for you, useful info here: How to install assembly in the GAC using MSI
If you install that .dll in the GAC and you are still having problems, another option is to actually create a separate visual studio project that contains your logic for manipulating the needed zip files build it and call its exe from SSIS using the Execute Process Task. You can pass arguments specified in the SSIS package. Not very elegant, but it gets the job done if you are keen on using SSIS.
UPDATE:
The solution in this question did the trick SSIS Script Task COMException / FileNotFoundException error. The problem was in adding a signed reference of the dll, this answer provides a good step-by-step workaround for adding a COM reference within the SSIS Script Task.

MSBuild Using Wrong Version of Assembly to Compile RDLC File

I am using the reportviewer control from VS 2010 to create client side reports (rdlc). Everything is working fine on my development machine, and when I manually compile (via VS2010) and manually deploy to a test machine that doesn't have development tools installed.
In order to get the test machine to work (without installing VS2010 or ReportViewer.exe), I had to add references in my project to Microsoft.ReportViewer.Winforms, Microsoft.ReportViewer.Common and Microsoft.ReportViewer.ProcessingModel and have them all "Copy Local".
I have the rdlc files configured for Build Action => embedded resources. This is the default setting when adding a new rdlc to the project. I am open to configuring this otherwise if this would resolve this problem (no idea if its related).
The problem: since adding the rdlc files, the solution no longer builds on the build server. I have installed ReportViewer.exe on the build server, and have verified that the required assemblies exist in the GAC. The .Net 4 framework is NOT installed on the build server--I don't think this is required because the solution targets the 3.5 runtime.
I believe the root of the problem is the following from the build log:
Target "RunRdlCompiler": Building
target "RunRdlCompiler" completely.
Output file
"obj\Release\RdlCompile.compiled" does
not exist. Using "RdlCompile" task
from assembly
"Microsoft.ReportViewer.Common,
Version=9.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a". Task
"RdlCompile":
Report\RDLC\GreenReport.rdlc (0,0):
error rsInvalidReportDefinition: The
report definition is not valid.
Details: The report definition has an
invalid target namespace
'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition'
which cannot be upgraded.
From what I can tell, Microsoft.ReportViewer.Common version 10.0.0.0 is what should be used to "compile" the rdlc, but MSBuild appears to be using 9.0.0.0. I believe if I could force it to use the right version (which IS installed in the GAC), the solution would compile.
This is because your Microsoft.Common.Targets file is pointing to the 9.0 version of the assembly.
If you look in [sysdir]\Microsoft.NET\Framework\v3.5 you will find Microsoft.Common.targets, which is driving a lot of what MSBuild does. This verion of the common targets file points to [Program Files]\MSBuild\Microsoft\VisualStudio\v9.0\ReportingServices\Microsoft.ReportingServices.targets forcing MSBuild to run with the 9.0 version.
When you installed .NET 4.0, you got a new common targets file in the v4.0.x directory, this new one now points to [Program Files]\MSBuild\Microsoft\VisualStudio\v10.0\ReportingServices\Microsoft.ReportingServices.targets which points to the 10.0 version of the ReportViewer assemblies.
The 10.0 ReportViewer is compiled against .NET 3.5 and intended to work in both 3.5 and 4.0. You could very likely get rid of the .NET 4.0 framework, and alter your 3.5 common targets file to point to the new ReportingServices target file, and it should work. In theory anyway, I've never actually tried it. You may be best off just sticking with 4.0, as that's what we intended when we designed the MSBuild support for the new viewer.
Just install Microsoft Report Viewer 2010 SP1.
I had a very similar issue. Just all of a sudden I could no longer build a VS2010 project that contained an .rdlc file. I wasn't converting any reports or using a report server, everything was local. I tried creating a brand new project and adding an empty new rdlc report and hit build and it wouldn't work. Just one day it stopped compiling and gave me the following error:
The report definition is not valid. Details: The report definition has an invalid target namespace 'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition' which cannot be upgraded.
Turns out the issue was my "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\ReportingServices\Microsoft.ReportingServices.targets" file had somehow changed. The top of my file was:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.Common, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
And it should have been:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
I changed that one "Using Task" line in the file and everything builds again. REALLY frustrating and it ate up two days of my life. Hoping posting this comment may help someone else in a similar situation.
Jim Lafler
I have tried re-installing all and it didnt work. Then, I tried updating Microsoft.ReportingServices.targets as per Jim's post but even didnt work for me.
At the end, I just copied Microsoft.ReportingServices.targets from other machine (where it was running without error). And surprisingly, it is working.
The additional difference I noticed while comparing, to change PublicKeyToken along with Version.
This may be the case for me only but Jim's post was much useful.
SFUH
Turns out I did need the .Net 4.0 Framework, and more specifically the 4.x version of MSBuild, which uses the newer version of the Microsoft.ReportViewer.Common library.
So even if you are targeting the 3.5 framework, if you create the rdlc with VS2010 it will expect to be "compiled" using 4.0 tools.
I have the same problem: we using ReportViewer 2012 (version of assemblies starts with 11). Both on local machines and on build machine are installed ReportViewer 2012 package and VisualStudio 2013. On local machines compilation in VS succeeds, but on build machine during queued build MSBuild throws such error:
The report definition is not valid. Details: The report definition has an invalid target
namespace 'http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition'
which cannot be upgraded.
I tried to modify Microsoft.Common.targets from .NET 3.5 folder in way, that is described in this post, but no effect. Then I opened Microsoft.Common.targets from .NET 4.0 folder, and found there such strings:
<!-- VS10 without SP1 and without VS11 will not have VisualStudioVersion set, so do
that here -->
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)'
==''">10.0</VisualStudioVersion>
</PropertyGroup>
Then I realized that problem may be in incorrect value of variable $(VisualStudioVersion), so I added to build definition in section "Process" this MSBuild parameter:
/p:VisualStudioVersion=12.0
And it worked! Build completed successfully.
Hope this will help someone.
Pasting file paths doesn't seem to be going through... how about this:
Was:
TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.Common, Version=8.0.0.0...
And is now:
TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.WebForms, Version=10.0.0.0...
James
The NetFx40_LegacySecurityPolicy was enabled in my devenv.exe.config, and when I commented this line out, the project built successfully.
We had enabled the legacy security policy on our team to enable our team to work with DevExpress 7.2 controls from within Visual Studio 2010, but in this case, it shows that the approach we took is not always the best.
I lost 2 full days of development due to a similar issue. On building my project it would succeed, but on rebuild it failed with no errors. On investigating the verbose build log in the Output window it directed me towards a problem with the rdlcompile function (so reporting services local report embedding issue). After trying every thing I finally manage to resolve the issue, but disabling my virus scanner. The Antivirus was somehow interfering with my rebuild and caused the rebuild to fail.
After disabling virus scan, rebuild works 100%
I have same problem on my Visual Studio 2013.
The dll version of reporting service on my project is Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
When i checked my ReportingServices targets
C:\Program Files\MSBuild\Microsoft\VisualStudio\v12.0\ReportingServices\Microsoft.ReportingServices.targets
I found the task version is 11.0.0.0
<UsingTask TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
When i changed the task version to 10.0.0.0 corresponding to dll version on my proejct.
<UsingTask TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
It' worked.
I just removed this file from my file system. The reports are simply ambedded no need to be compiled.
c:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\V11.0\ReportingServices\Microsoft.ReportingServices.targets
this worked fine for me and for my build server.

Microsoft Assembly configuration for 32-bit mixed C/C++ application

We have a 32 bit mixed C/C++ application that we are trying to deploy to the world.
It naturally uses C and C++ runtime DLLs. We are using VS 2005.
The manifest constructed by VS2005 is the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.42" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
We ship this as a file in the same directory as the "application", named
(changed to protect the innocent) "application.exe.manifest".
On the face of it, it is sort of reasonable. But, in installing on some
systems, we get the message when "application.exe" is launched:
This application has failed to start because the application configuration is incorrect
One way to cure this is to run VCRedist_x86.exe from MSDN. (Unfortunately,
while we can run it, we don't know exactly what it is doing.
It appears to be parking DLLs in the SxS directories. But what else
does it do?)
a) The MS docs seem to indicate that the assembly must have an assemblyIdentity
tag directly underneath the assembly tag, that names the application itself.
This is clearly missing here, but the manifest seems to partially work in that
if we remove it, the application doesn't start even if the DLLs are present.
b) Remarkably the assembly doesn't mention the C runtime DLL. Do I need to just add that by hand?
c) We dont want to be dependent on whether the right version DLL is present on the target machine. Assuming that the assembly makes it clear which DLLs to use, how is that we can ensure the DLLs we need are on the target system? (In particular, we don't want run VCRedist or ask our customer to do this). Before assemblies came along, we solved this problem by simply placing the C and C++ DLLs in the same directory as the application .exe file, and Windows would look there first to pick them up. Can we still ship the C and C++ DLLs in the same directory? I can't figure out from the MS docs I can find how the SxS finds the appropriate dependent assemblies.
Any help appreciated.
a) The manifest xml validation clearly has some problems. Depending on the version of Windows this may or may not be an issue. Since so many applications don't correctly follow the schema (and because it was never properly enforced), I doubt it will ever be strict here.
b) The C runtime DLL is referenced in the Microsoft.VC80.CRT.manifest file, pulling it in to to the loader dependency graph. Providing you have a dependency on the manifest, you will also implicitly have a dependency on the DLL.
c) Per my earlier comment, the correct thing to do (aside from installing the latest redist system wide) is to put the CRT manifest and all three DLLs in your application directory. This is poorly documented under SxS: Private Assemblies and Installing Side-by-side Assemblies as Private Assemblies. The probe order is defined in Assembly Searching Sequence.
Generally a SxS binding failure will put an entry in the Application (for Vista+) or System Event Log (pre Vista) describing the error.
Activation context generation failed for "C:\TEMP\sxs\PEVerify.exe".Error in manifest or policy file "C:\TEMP\sxs\Microsoft.VC90.CRT.MANIFEST" on line 4.
Component identity found in manifest does not match the identity of the component requested.
Reference is Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a18e3b",type="win32",version="9.0.21022.8".
Definition is Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.30729.1".
Please use sxstrace.exe for detailed diagnosis.
You can use sxstrace.exe in (Vista+) to see what the loader is actually doing. Junfeng covers this in more detail in Diagnosing SideBySide failures.
To get a better understanding of what is happening at runtime (after the manifest has been parsed and dependencies located), enable "Show Loader Snaps" for your image file (just the filename and extension, do not enter a directory name, like so: "notepad.exe") using gflags.exe. Run your application under windbg (Visual Studio's debugger may also work) and look at the output. Make sure to disable loader snaps when you're done debugging since it will slow down the application even when no debugger is attached. Sample output looks like this:
2d6c:36b4 # 1246428223 - LdrpHandleOneOldFormatImportDescriptor - INFO: DLL "C:\Program Files\Microsoft SDKs\Windows\v6.1\Bin\PEVerify.exe" imports "MSVCR90.dll"
2d6c:36b4 # 1246428223 - LdrpMapDll - INFO: Mapping static redirected DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll"
ModLoad: 4fbd0000 4fc73000 C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll
2d6c:36b4 # 1246428285 - LdrpMapDll - INFO: Mapped DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll" at address 4FBD0000
2d6c:36b4 # 1246428285 - LdrpHandleOneOldFormatImportDescriptor - INFO: DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll" imports "KERNEL32.dll"
You could link the C/C++ runtime statically.
You can change the library linkage in the C/C++ compiler options in the Code Generation section. Change the entry from Multithreaded [Debug] DLL to Multithreaded [Debug].
Your DLL will then contain the required parts of the runtime, and the separate installation is not required.
I've never understood how the manifest stuff all hangs together ... but instead of placing the C runtime DLLs in the same directory as your exe try copying the whole 'Microsoft.VC90.CRT' folder from the redist folder in the Visual Studio install (C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT on my machine).
I believe Microsoft encourages the use of shared libraries and running the official redist since it installs the libraries 'properly' and means they can patch security issues that may be found in them.