I heard from a friend that asp.net relies on/uses a Windows forms class. I tried to figure out which class that might be.
The only class I found was System.Web.UI.WebControls.FontInfo
with the property public string[] Names
that has an Attribute Editor("System.Windows.Forms.Design.StringArrayEditor--snip")
Is there a reference to the Windows.Forms.dll from System.Web.dll?
I think there is a reference from System.Web, Version 2.0.0.0 to System.Windows.Forms.
Check out System.Web.Compilation.ResXBuildProvider.GetResourceReader(Stream) in Reflector.
On line one: ResXResourceReader reader = new ResXResourceReader(inputStream);
ResXResourceReader is from System.Windows.Forms, Version 2.0.0.0
I was curious because I noticed System.Windows.Forms in the loaded modules window in Visual Studio.
ildasm System.web.dll /out =System.Web.il let me quickly search for System.Windows.Forms references. I couldn’t quickly figure out a way to do it from reflector.
There is no reference, and not System.Windows.Forms either.
The StringArrayEditor is a UITypeEditor in the System.Design assembly. This does not get loaded unless used except at design time, when it will be 'lazy-loaded'.
First of all, I am not sure such an existence.
But Namespace or classname doesn't necessary mean you need a reference to Windows.Forms.dll. You can define "System.Windows.Forms.Design.StringArrayEditor" in an assembly outside Windows.Forms.dll.
If you look at the System.Web assembly in the handy Reflector tool, you will see that there is indeed a reference from System.Web to System.Windows.Forms. However, if you use one of the plugins for Reflector that will export the reverse engineered code to files (e.g. FileGenerator), and then search through that, there is no actual use of System.Windows.Forms. Since the .Net runtime will only load assemblies when they are actually needed, the WinForms assembly should never actually be loaded through any usage of System.Web.
Add me to the list of skeptics. But more importantly, it doesn't matter. The way the .Net framework is set up for linking adding or removing a dependance on any of the core assemblies that ship with the framework won't really impact performance in any meaningful way.
Related
I'm building an application that will load untrusted assemblies for inspection (i.e. retrieval of the assembly full name). For security reasons, I'm trying to think of a way that these assemblies could be written that would allow them to execute code when loaded. I haven't code up with a method yet, but wanted to throw it out here to see if anyone could.
I'm aware that I could load these assemblies into an untrusted app domain, effectively stopping them from doing almost anything, but I wanted to avoid the complexity if it's un-needed.
Specifically, I will be calling Assembly.Load and <LoadedAssebmly>.FullName. Maybe there's a better way to load the assembly name without using the Assembly class?
Thanks,
Matt
First of all, there's the AssemblyName class. It allows you to find the assembly's name without loading it. Second, you can load assemblies using Assembly.ReflectionOnlyLoad, which uses the reflection-only context -- no code can be executed from such an assembly.
Yes, it is possible: .Net: Running code when assembly is loaded
I suggest, you use a method to inspect the assembly, that doesn't load it, i.e. Mono.Cecil
I have a web project called "TestResourceApp" with Labels.resx in App_GlobalResources folder. I want to add another language by creating a satellite assembly.
Here are the steps I took to create the satellite assembly. The default text always get displayed. What did I do wrong ?
1) Create Labels.fr.resx in a different folder.
2) Generate resource file:
Resgen Labels.fr.resx TestResourceApp.App_GlobalResources.Labels.fr.resources
3) Generate satellite assembly:
AL /t:lib /embed:TestResourceApp.App_GlobalResources.Labels.fr.resources /out:french.dll /c:fr
4) Copy french.dll to TestResourceApp/bin/fr
I have uiculture set to auto in web.config and I have change the language on the browser.
I was able to use this page to solve some satellite assembly issues I was having. I'll throw in a few more things to check.
It's helpful to decompile the "neutral" assembly and see how it's put together. A tool like ILDASM.exe is helpful for this purpose. Once you get it decompiled, look through the text output for ".mresource", and you should see one with your naming. For example, if you add a resource to a Visual Studio project, they're named MyAssemblyName + ".Properties.Resources" + a language (if any) + ".resources" Examples:
MyAssembly.Properties.Resources.resources (neutral language)
MyAssembly.Properties.Resources.en-US.resources (English (US))
In my case, I had the file named properly, and in the appropriate folder (such as Bin\en-US). I was able to verify that much by using ProcMon.exe (by the SysInternals guys) and could see the worker process finding and reading in my DLL file (instead of just saying "PATH NOT FOUND"). However, it was not finding the resource by the name that it expected it to. That's when some disassembly helped to get to the bottom of the naming problem.
So, use ProcMon.exe to narrow down the kind of problem you might have. Hopefully that's helpful to someone.
It's complicated but here are a few tips for those who run into this problem:
Try to include the resx in the web project and let VS do the job for you.
Reflector is your friend. Compare satellite assemblies you created and those created by VS.
If you web app is targetting ASP.NET 2.0, you should use Resgex and AL that come with .net 2.0. Open the assemblies in Reflector and check the "references". It should reference mscorlib version 2.0.
If you deploy your web app using web deployment project, make sure the namespace for the resources in your satellite assemblies is correct. Again, compare with what VS creates. In my case, I used the wrong tool to generate the designer.cs file because I wanted them to be accessible from a different assembly. Make sure you are using GlobalResourceProxyGenerator. Otherwise, the namespaces won't match and the deployment code will not be able to find your resource. The namespace in the designer.cs should simply be "Resources", not "XXXX.App_GlobalResources"
Did you have set enableClientBasedCulture to true in globalization ?
I have an C# ASP.NET Web Application Project where all the pages are in the global/default/top-level namespace. (I have no explicit namespace declarations. And when I look at my compiled web application's DLL in Red Gate's .NET Reflector, I can verify that all the classes are in the top-level .NET namespace.) Is there any good, automated way to move all the pages and custom controls into a new namespace, say "MyWebApplication"? Ideally it'd be nice to do it with just Visual Studio, but I'd be open to considering a commercial refactoring tool if necessary.
I thought maybe by setting the "Default namespace" property in the project's Application properties I could get the compiler to implicitly put all pages into the specified namespace, but this appears not to be the case; this "Default namespace" setting seems to make Visual Studio insert explicit namespace declarations into new pages, rather than implicitly affecting the namespace of any existing pages.
If it matters, my immediate motivation here is to try to run a static analysis tool (CAT.NET) on my web application; the tool seems to have a quirk or two with code in the global namespace.
Chris it may look silly as you are ready to pay for the refactoring tool to do it. But consider this:
The namespace is declared in the code-behind file by default as the project/application name. So if you project name is MyWeb the default namespace will be
namespace MyWeb
{
public partical class MyWebPage....
Now this is refered in ASPX page as follows:
<%Page ... CodeBehind="MyWebPage.aspx.cs" Inherits="MyWeb.MyWebPage"
You only need to change these two things to put into effect the namespace migration. And frankly this can be achieved using Find/Replace dialog. Please make a copy of your complete solution and try it!!
Cheers
I have a ASP.net application that is referencing a external assembly that I need to dynamically load and discover any types implementing a known interface. The problem I am having is that the type I reflect does not match the same interface that is running and so I cannot cast it.
Example:
This code is run in ASP.net app.
var assembly = Assembly.LoadFile(Path.Combine(HttpRuntime.BinDirectory, "ExternalAssembly.dll"));
var type = assembly.GetExportedTypes().First<Type>(x => x.Name == "AClass"); // AClass implements IAInterface
var reflectedInterface = type.GetInterface(typeof(IAmAInterface).ToString());
if (reflectedInterface != typeof(IAmAInterface))
throw new Exception("This makes me sad"); // This code gets run
The only difference I can see between the reflected interface I loaded from the bin and the interface returned from typeof is that the typeof assembly has a location in the temp ASP.net path (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\08c43c8b\3adac8cf\assembly\dl3\eb7a4127\0235ea60_a3c8c901\ReflectionTest.DLL)
Thanks Paul Alexander I have changed the code to use the Assembly.Load method not Assembly.LoadFile which solves the problem.
wwilden: I also tried extracting the interface into it's own assembly and this does also solve the problem.
When you use LoadFile the assembly is not loaded into the same context as your other assemblies at runtime so to the CLR interface runtime types are different. You can read more in Suzanne Cook's Debugging Assembly Load Failures.
If the assembly that you're loading is already in the Bin directory - you can load it by name. You don't need to know the exact path as the Bin folder is already in the assembly probing path.
Where is your interface type defined? Does it exist both in the reflected assembly as well as in the application itself? Then you actually have two different interfaces, even though they have the same namespace and name.
What you need to do is extract the interface from the reflected assembly and put it into another assembly that you refer to both from the reflected assembly as well as your application. Then it should work.
Apart from your problem, if you have a lot of assemblies to dynamically load, remember that they will remain in memory until the ASP.NET worker process reloads. This could influence your server's performance.
You could load the assemblies in a separate AppDomain (the smallest unit that is possible to unload), load a proxy class in that AppDomain which you reference with .NET remoting. Once finished, you unload the AppDomain.
There is an interesting article over at CodeProject about a situation like this. Where you have a class that has a structure that is identical with an interface without implementing the interface itself. The article outlines a method of dynamically creating wrapper classes that implement the needed interface. It could be helpful in your situation.
I'm looking for the simplest (and most complete) mechanism to move a class from one to another assembly with reference (dependency) fixing capability.I know some manual ways to do that like :
- use built-in move rename, then cutpaste, multiple save ...
- use resharper rename namespace, cutpaste , the same as above
but with the problem is the same with those : in a web environment (namely ASP.Net) almost all of the references (for user controls for example, let's suppose with assembly name in their path for a virtual path provider scenario) are coded a string references (not to mention the configuration files and other external reference sources) - unfortunately even resharper doesn't found all. Other problem is with the designer files - you know they're generated on at least save action accordingly to the specifications in control and sometimes they're somehow mixed with the rename action I mean here's the old there's the new assembly name etc.
Thanks in advance,
Nicolai
If you are using Resharper try the Test Driven Development
It Allows a number of refactors like that.