i have a problem regarding InternalsVisibleTo.
I have an Assembly named A with an internal test class
I have a Wcf Service (WcfService1) hosted on iis that is referencing this assembly via static linking (add reference on visual studio).
i have the A - AssemblyInfo.cs file with:
[assembly: InternalsVisibleTo("WcfService1")]
I build and add the A.dll to the WcfService1.
Obviously, on WcfService1 class, i call the internal method of the A.dll, and the intellisense signal me correctly the name of the method, the variables etc.
It compile smoothly and no problem is shown.
however, when i build and run on his, the server give me a compilation error:
CS0122 'method called' is inaccessible due to its protection level
so i'm confused: in the Visual Studio IDE i got correctly the autocompletion and no build errors. When run, it cannot use the internal methods?!
Other info: i tried with Strong naming and without(public key calculated via command prompt), with the same result (on IDE is ok, when run it crash).
Found the solution.
I was calling the internal method from the method initialize() of the IIS.
This method is used to do inizialization, and the class with initialize() must be placed in App_Code folder.
I moved the offending call to another class, in my friend assembly, et voilĂ , problem solved :) hope it will help someone!
Related
I am getting System.IO.FileNotFoundException in my .Net Core Web API. So I've set up the below project to demonstrate the problem.
I created a.Net Standard library named DemoLibrary and added QRCoder dependency via NuGet.
Disclaimer: Reason for choosing the QRCoder is that the Web API doesn't use it by default. I don't use it in my project. In fact, I'm getting this exception for EntityFrameworkCore.
I created a new .Net Core Web API DemoWebAPI which has no other dependencies.
Then added the DemoLibrary to DemoWebAPI via Add Reference -> Browse -> DemoLibrary.dll.
This is my solution:
The DemoMethod method in Calculate class just creates the object of QRCodeGenerator.
public class Calculate
{
public static string DemoMethod()
{
QRCodeGenerator qrGenerator = new QRCodeGenerator();
return "";
}
}
And my ValuesController in DemoWebAPI just calls the method:
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2", DemoLibrary.Calculate.DemoMethod() };
}
Now, when I run the DemoWebAPI project I get below exception upon the call to the DemoMethod:
System.IO.FileNotFoundException: 'Could not load file or assembly 'QRCoder, Version=1.3.5.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.'
I understand the fact that I have to copy the QRCoder.dll file somewhere. But I fail to understand where to put it. I've already tried putting it in "bin/debug/netcoreapp2.2" of the DemoWebAPI and "bin/debug/netstandard2.0" of the DemoLibrary.
But I couldn't get it working.
Request: Please post your answer as descriptive as you can because I am new to .Net Core.
Edit:
I am aware of the NuGet servers. I have read topics like hosting a NuGet server in IIS and Azure. The reason behind DLL reference is I want to use my DLLs in two projects one of them is a .net core API and the other is .net framework class library which is compiled by NMAKE. I couldn't find any way to restore NuGet packages in the .MAK files.
It looks like you've merely added the DLL for DemoLibrary to your DemoWebApi project. That's not how you should be adding references. Since these are in the same solution, you should add a project reference. That will fix your issue.
Now, let me explain what's actually going on here. Your DemoLibrary has a dependency on QRCoder. It's a NuGet reference, which means that package will be restored (i.e. downloaded) and included in your DemoLibrary build output. However, it will be included as one or more DLLs along side your DemoLibrary.dll. When you then just reference DemoLibrary.dll, you're missing all these other DLLs that are part of DemoLibrary and thus, things don't work properly.
Now, when it comes to a project reference, things are little more complex. A project reference essentially wraps the referenced project into your other project. You can think of it as sort of a sub project. For all intents and purposes, it's like any dependency of the sub project becomes a dependency of the main project. That means that DemoWebAPI now technically has a NuGet package reference to QRCoder even though there's no explicit package reference in its project file. The dependency comes from your DemoLibary project. As such, with a project reference, all the necessary dependencies will be included, because it's as if the main project included those itself, by way of the sub project.
For what it's worth, you should virtually never include a DLL as a reference directly. That used to be required, but the concept of NuGet packages has all but eliminated the practice. Even if DemoLibrary was not in the same solution as DemoWebAPI (meaning you could no longer do a project reference), the correct way to use it would be to turn DemoLibary into a NuGet package, and then reference it in DemoWebAPI via a package reference, like any other NuGet package. You do not simply add the DLL.
I am trying to create a ManagedWrapper dll that can be called from an MFC application that will not be compiled using /clr switch. In a header of my test MFC, I have declared the following:
#import "ManagedProxy.tlb"
using namespace ManagedProxy;
When I try to compile the test MFC application, I get error C2871: 'ManagedProxy' : a namespace with this name does not exist. I am sure this has worked as recently as yesterday. If I specify a wrong tlb file name, I get compile error C1083, which indicates to me that the tlb file is being loaded correctly.
Why is Visual Studio now complaining and why did it work before?
Addition:
I just found out that my proxy stopped working after I changed the namespace to ManagedProxy. I have recompiled the Managed project, and the native application has as an Additional Include Path, the Debug folder of the managed project, so it should be referencing the latest tlb but it is not. I tried an absolute path to the tlb, cleaned and rebuilt project with no luck.
Why is the tlb not the namespace change?
Addition
Used Object Browser to see what is in TLB and the namespace ManagedProxy is somehow renamed to something else. I am also missing a couple of interfaces although they are marked with ComVisible(true).
Someone please help....
TIA.
You can rename the namespace when you import.
#import "ManagedProxy.tlb" rename_namespace("ManagedProxy")
The interfaces not showing up are likely not marked public.
I'm really struggling with WiX. I have .NET assemblies to install that require registration for COM Interop, AND they must be registered with another framework that requires calling a Register() method in a .NET assembly that's in the GAC. This registration method is a 'black box' with a hidden storage mechanism so I can't perform this operation declaratively.
I get that the declaritive approach is best for COM registration, but I have two problems with using heat.exe:
RegAsm works, but Heat.exe chokes on my assembly with the message:
heat.exe : warning HEAT5151 : Could
not harvest data from a file that was
expected to be an assembly:
C:[...].dll.
If this file is not an assembly you
can ignore this warning. Otherwise,
this error detail may be helpful to
diagnose the failure: Exception has
been thrown by the t arget of an
invocation.
The secondary registration that I need to do relies on the [ComRegisterFunction] attribute, which normally triggers further actions at the time the assembly is registered for COM Interop. This normally happens when the assembly is registered by RegAsm.exe or by calling System.Runtime.InteropServices.RegistrationServices. So, I need that ComRegisterFunction in my assembly to execute during the installation.
I don't mind taking the declarative approach to COM registration (or I wouldn't mind if heat worked on my assembly) but I need to call that ComRegisterFunction as part of the install. Ideally, I'd like to look at all of the executables I'm installing, reflect on them for any methods with the [ComRegisterFunction] attribute and call those methods, this would be done after all files are installed.
How can I achieve this in WiX? Or, is there another approach? If it makes any difference, I am using the 'Votive' Visual Studio integration with project references.
These are opposing goals. The point of using the declarative approach is to not use Regasm.exe or Regsvr32.exe to call the registration function. In other words, your [ComRegisterFunction] attributed method won't be called. You can't have both.
The exception that heat.exe dies on isn't healthy, it indicates that there's something wrong with your registration function or class contructor. Debug this by making your DLL the startup project. Project + Properties, Debug tab and make heat.exe the startup program. Set the command line to your DLL. Debug + Exceptions and tick the Thrown box for CLR exceptions, the debugger will stop when the exception is thrown.
Oh, and don't forget to call RegistrationServices.RegisterAssembly in your register function. Regasm.exe won't do it automatically anymore since you used the attribute.
I'll caveat my answer by stating that the correct way to do this is as Hans states - via heat.
An alternative however is to use the SelfRegCost attribute of the File element under a Component element.
Below is an example from one of our older setup kits that's thus far been working with no issues.
<File Source="..\..\External References\MSCAL.OCX" SelfRegCost="1"/>
As with any SO answer, best to check this works in your situation and test thoroughly.
This call
// this._cfg is an NHibernate Configuration instance
this._sessionFactory = this._cfg.BuildSessionFactory();
Gives me this exception at runtime (NOT at compile time).
Could not load file or assembly 'NHibernate.ByteCode.Castle' or one of its dependencies. The system cannot find the file specified.":"NHibernate.ByteCode.Castle
OK so far. But the thing is, this code is running in a class library project, and I have referenced NHibernate.ByteCode.Castle (along with all the other NHibernate dll's) in that project.
Wierder: I can fix the exception by additionally referencing the NHibernate dll's in the Windows WPF executable project that calls my class library. But the Windows WPF executable contains no code that directly uses NHibernate (as evidenced by: It compiles fine without any NHibernate references). So what's going on? Apparently it's insufficient to reference NHibernate.ByteCode.Castle in the project that actually uses the NHibernate stuff. Anyone know why?
I know this is old, but what I've done to fix the dependency problem is simple:
In my UnitOfWork I added one static method:
private static void bringCastleDamnit()
{
var pf = new NHibernate.ByteCode.Castle.ProxyFactoryFactory();
}
Then, and only then, would MSBuild see that it was needed and copy it to my output directory for my (asp.net and console) apps that references my Data project.
I wouldn't reference the castle byte code factory at all; just ensure it (and all other needed dependancies) are copied to the output directory using a post-build step.
my issue is very similar to:
http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-vb/54944/VB-Net-project-throwing-errors-when-executing-Clean-Solution
Typical errors: Unable to load referenced library X
Type IWshRuntimeLibrary.WshShell is not defined.
Interface System.IDisposable is not implemented by this class.
Namespace of type specified in the Imports Z does not contain any public members or cannot be found. Make sure the imported element name does not use any aliases.
This must have to do with a VB.net project configuration. Currently there is a setting "Treat all warnings as errors". I would like to keep that setting, but also resolve these annoying "errors".
I've experienced a similar problem and fixed it by running the following command in the VS command line tool
devenv /resetskippkgs
I'ev had problems executing Clean's via MSBuild in VS2008 when projects were registered for COM interop.
The problem is that the "Clean" target auto-generated for a solution cleans projects in the same order in which they were built.
This causes problems for projects registered for COM when MSBuild attempts to load and then unregister the assembly from COM during a "Clean".The issue occurs if the assembly has a dependency on another project because the dependency will be deleted first and therefore loading the assembly will fail and MSBuild will be unable to unregister it.
A workaround is to change the solution .cache file (which contains the targets auto-generated by MSBuild during "Build") and reverse the order of the "Clean" target. I hacked-together a quick-fix custom build task to do this as a post-build step.
No idea if this was fixed in VS2010 or indeed if this matches your problem since you don't give many specifics in your question ;)