How do WPF Markup Extensions raise compile errors? - c#

Certain markup extensions raise compile errors. For example StaticExtension (x:Static) raises a compile error if the referenced class cannot be found. Anyone know the mechanism for this? Is it baked into the XAML compiler or is such functionaility available to custom markup extensions?
EDIT: mfeingold below suggested that I need to look into the IVsErrorList interface, but I can't immediately see how that would help someone white a markup extension that generates a compile-time error. Any examples?

Extending the BAML compile process to log additional errors
I encountered this same problem last year. I was writing my own extension for which I wanted compile-time errors in certain scenrios and discovered that just throwing an exception from ProvideValue didn't work because ProvideValue isn't called until the XAML is actually loaded and the object tree is created.
I did some experiments and discovered that the compiler error message for x:Static is a byproduct of an optimization done by the the BAML compiler. The BAML format actually has a concept of a specific member of a specific type, so when the XAML contains x:Static the compiler actually replaces it with a special record that directly references the member rather than containing the type and method name. It does this by explictly recognizing the StaticExtension class. TypeExtension has a similar optimization.
I searched for hooks that would allow me to have my own code called during BAML compilation, but I didn't find any. BAML compilation is mostly just a straight transliteration into a binary format that corresponds to the XAML, with a few specific optimizations but mostly ignoring what it sees.
I ended up adding an extra step to the build process, modeling my code off of Microsoft.WinFX.targets and the other built-in targets files. This step scans the XAML for my markup extension, checks the parameters, and generates a compile error if they are not correct. This is done completely independently of the translation into BAML. It was a couple days' extra work to implement this when all was said and done, but I learned a lot.
Caveat about creating your own .targets file
If you're thinking about adding your own .targets file, you should be aware that unless you include the target in the local machine's SafeImports registry key, both Visual Studio and Expression Blend will complain that about any project that includes your .targets file. This key requires Administrator access on the machine to update. This may or may not be an issue depending on your deployment scenario. (For example, a machine-wide MSI install would fix it, or you could manually set the key if you only have a few development machines). In my case it didn't matter since I already needed the custom .targets file for some other things I was doing in that project.
Error logging from a build task
You don't need IVsErrorList to add errors to Visual Studio during a build (and if you did, you would not properly support command-line builds, Expression Blend, and other tools).
All you need to do is to call Log.LogErrror Log.LogWarning from inside your build task, like this:
public class CheckForErrorsInMyMarkupExtension : Task
{
... parameters here ...
public override Execute()
{
... code to load XAML and scan it for markup extension errors ...
... when you discover an error ...
Log.LogError("I saw an error");
}
}

There are several VisualStudio integration API which allows you to generate your own diagnostic messages from a MEF extension (VS2010 only) a VSIntegration Package or an add-in.
check out IVsErrorList interface as well as OutputTaskItemString method of the IVsOutputWindowPane interface. The latter is what I used in my django editor.
The calls to these methods of course are baked into XAML compiler - how could they not be, they are based on results of the XAML parsing

Related

Project in VS 2015 decompiled by dotpeek reporting ambiguous error on same class

i have some small app, created in C# and its working. But when i decompile it with jetbrains dotpeek and open it in Visual Studio 2015 it shows me error
The call is ambiguous between the following methods or properties 'MainWindow.InitializeComponent()' and 'MainWindow.InitializeComponent()'
Application is easy, just one class and im curious why it shows error, that method is in same class? I made a tripple check and code contains only single declaration of this method.
Also it contains error
The type 'MainWindow' already contains a definition for '_contentLoaded'
which will be probably caused by same issue... Also in same class, and only one copy of this class, and triple checked for another occurence of declaration
A lot of times debuggers and decompillers give result code with errors. They are maded only for understanding and fixing problems in programs without source code. If you have sources - you can debug your app without decompilation and save a lot of time. If you want compare code (original/decompiled), you can use WinMerge or other programs for it. Also you can try other decompilers, like ILSpy or .NET Reflector.

Throw build error if a specific word is found anywhere within the project code or html views

I have an MVC project that is prone to spelling mistakes with short acronyms. i.e. people writing "ZED" instead of "DEZ".
Is it possible to get Visual Studio to throw an error during a build if a specific word is found anywhere within the code being built? My biggest concern is checking to see if it appears in any of the views more than anything else. i.e. If any view contains "ZED" the compiler would throw an error and prevent anything from being published.
Any ideas?
You can use code analysis automation tools like fxcop or stylecop. Build your custom dictionary of allowed words and enable the code analysis policy during builds.

MissingManifestResourceException with Silverlight application referencing resx files in other project

I'm having difficulty getting a Silverlight application working. The project is quite large, and was recently handed to me. It consists of (among other things):
A class library containing resources (let's call this MyResources). This contains a number of .resx files that contain translated strings for various labels/text in the app.
A Silverlight class library that links to all the resource files in the regular class library. (let's call this project MyResourcesSilverlight)
A Silverlight app that references MyResourcesSilverlight
From what I understand, with Silverlight you can't directly reference a regular .Net assembly because of security concerns. This makes sense, and explains the two nearly identical projects - the Silverlight class library and the regular class library. (There's a bunch of other projects that use the regular class library).
The problem I'm having is when I'm attempting to run the Silverlight app, it is failing to load any of the localized strings, and I'm getting the following error message:
Uncaught Error: Unhandled Error in Silverlight Application
Code: 4004
Category: ManagedRuntimeError
Message: System.Resources.MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "MyResources.resources" was correctly embedded or linked into assembly "MyResourcesSilverlight" at compile time, or that all the satellite assemblies required are loadable and fully signed.
From the error message, it would appear that it is having difficulty pulling in the resource files - and this is also apparent from the missing text on buttons, labels, etc.
To fix this, I've tried doing the following:
Cleaning/rebuilding the solution. This had no effect.
Right clicking on the resource files and selecting "Run Custom Tool". The Custom Tool for all the resource files is set to PublicResXFileCodeGenerator. This has no effect as well, other than regenerating the code, which causes the class constructor to be internal (despite being set to public. Another problem for another day - or from what I've seen - a known issue that Microsoft is refusing to fix).
Setting all the resource files to Embedded Resource. This had no effect.
I've been looking around at other people who have had this similar issue, and have tried pretty much anything I can get my hands on, but nothing seems to work. Either I get the error message above, or I get an error message like The name 'MyResources' does not exist in the current context..
If it helps to know, the project was originally a Visual Studio 2010 project, but I've converted it to be a Visual Studio 2012 project. To the best of my knowledge, nothing has changed namespaces, which is a common cause of this problem.
Can anyone shed some light on what might be happening here? I'm quite stumped.
EDIT:
Perhaps also worth noting: I'm not seeing any sort of text on any of the forms in the Visual Studio designer. When I mouse over the supposedly missing StaticResource, it says "The resource ___ could not be resolved.". I suspect this may be an indication of a larger problem with the resource files in general. Anyone have any thoughts?
I eventually got this sorted out, but I'm still not 100% sure on what I did to fix it. This is what I did, though:
Because of the odd layout with the two library projects, whenever I would touch the MyResources project, it would automatically update the MyResourcesSilverlight project. This meant that if I did the "Run Custom Tool" on MyResources, it would regenerate the resource designer files with a namespace of MyResources. If I then went into the MyResourcesSilverlight project and did the "Run Custom Tool" on the resources there, it would then rebuild the files with the MyResourcesSilverlight namespace.
When I started digging through the XAML files that were having issues, I noticed that they were referring to things like so:
xmlns:resources="clr-namespace:MyResources.Resouce;assembly=MyResourcesSilverlight"
This made me look twice at the namespace in the files being generated inside the MyResourcesSilverlight project. Sure enough, when doing the "Run Custom Tool" on the resource files, it was generating them in the MyResourcesSilverlight namespace rather than the MyResources namespace. I set the default namespace on the MyResourcesSilverlight project to MyResources, then did the "Run Custom Tool" again to regenerate the auto-generated code. Despite manually setting the auto-generated code to create things as public, I still had to manually go in and switch the class constructor from internal to public. Once I did that, things seemed to start working.
So if I were to sum this up, I'd say look at the following:
Verify the namespace that your XAML files are using and the namespace of the auto-generated code in the resource files. They should match.
Verify that the constructor of the auto-generated code is public. Don't trust the Custom Tool.
Hopefully this helps out anyone else who might be stuck on a similar issue.

Script# and compiler problems

I've just come across a pretty strange problem with VS2010 and Script#, which most of the time I am able to re-create.
In my simple scenario I have 2 projects in my solution; a standard Asp.Net MVC2 Web Application, and a Script# jQuery Class Library. I created a static class (attributed with [Imported]) with a static method on it, the intention being that I can map this class in code to an external Javascript library, as described in the documentation.
However, it seems that whenever I decorate such a class with [IgnoreNamespace] to achieve this goal, the project stops successfully compiling but doesn't give me any feedback as to why it's failing (no errors in the error window, for example). It's not easy to get rid of either, as Visual Studio seems to get into a permanent state of not build failure; removing the classes and project files doesn't solve it, nor restarting visual studio. The only way I can get VS to build the project successfully is to delete the project entirely, create a new one then add the files back in, which is annoying to say the least.
With a verbose build output setting, I get the following:
Target "AfterCompile" in file "C:\Program Files (x86)\ScriptSharp\v1.0\ScriptSharp.targets" from project "e:\project\local\ScriptSharpDemo\Scripts\Scripts.csproj" (target "Compile" depends on it):
Task "ScriptCompilerTask"
Done executing task "ScriptCompilerTask" -- FAILED.
Done building target "AfterCompile" in project "Scripts.csproj" -- FAILED.
.. which doesn't tell me whole lot.
There have been a couple of times where I have managed to create this type of class and then successfully build, but mostly I can reproduce this problem pretty reliably.
At this point I'm inclined to think that the bug lies with Script#, but would just like to have that confirmed, and to find a possible work around if there is one.
Just in case anyone is having a similar issue, I've found the cause of the problem.
When adding a class using this method, or copying in a file from another project for use within Script#, this causes a reference to System.dll to be added to the project. This (understandably) causes the project to stop compiling without error.
It would be nice to have a warning about this or for Script# to somehow detect when this situation occurs and/or create a new template for when I use 'Add class' or import a file, but it is just a convenience issue and at least now I can painlessly get my project compiling again just by removing this reference.
When trying to make my project build again, I came across the following, possible solutions:
The "Home\HomePage.cs" and "Shared\Utility.cs" must not be deleted and remain where they wre initially created
The "Home\HomePage.cs" and "Shared\Utility.cs" must be the last entries in the "*.csproj"-file. After them, no "Compile" tag should follow
Problematic calls to "Script.Literal" might cause silent fails - especially be careful when having parameters (like Script.Literal("{0}.doFoo()", variable))
The same seems to be true for "String.Format" when the format parameters are invalid
Namespaces and folders seem to cause many problems, putting all classes into the same namespace and all classes into the same folder might help
I tried all of the suggestions that have been given here, but continued to see the issue. Eventually, I determined that the cause in my situation was that I had added an [IntrinsicProperty] attribute to one of my properties. Removing it solved the issue. Don't ask me why this was causing a problem, but I thought I would share this solution in case others run into it.

How do C/C++/Objective-C compare with C# when it comes to using libraries?

This question is based on a previous question: How does C# compilation get around needing header files?.
Confirmation that C# compilation makes use of multiple passes essentially answers my original question. Also, the answers indicated that C# uses type and method signature metadata stored in assemblies to check code syntax at compile time.
Q: how does C/C++/Objective-C know what code to load at run time that was linked at compile-time? And to tie it into a technology I'm familiar with, how does C#/CLR do this?
Correct me if I'm wrong, but for C#/CLR, my intuitive understanding is that certain paths are checked for assemblies upon execution, and basically all code is loaded and linked dynamically at run time.
Edit: Updated to include C++ and Objective-C with C.
Update: To clarify, what I really am curious about is how C/C++/Objective-C compilation matches an "externally defined" symbol in my source with the actual implementation of that code, what is the compilation output, and basically how the compilation output is executed by the microprocessor to seamlessly pass control into the library code (in terms of instruction pointer). I have done this with the CLR virtual machine, but am curious to know how this works conceptually in C++/Objective-C on an actual microprocessor.
The linker plays an essential role in C/C++ building to resolve external dependencies. .NET languages don't use a linker.
There are two kinds of external dependencies, those whose implementation is available at link time in another .obj or .lib file offered as input to the linker. And those that are available in another executable module. A DLL in Windows.
The linker resolves the first ones at link time, nothing complicated happens since the linker will know the address of the dependency. The latter step is highly platform dependent. On Windows, the linker must be provided with an import library. A pretty simple file that merely declares the name of the DLL and a list of the exported definitions in the DLL. The linker resolves the dependency by entering a jump in the code and adding a record to the external dependency table that indicates the jump location so that it can be patched at runtime. The loading of the DLL and setting up the import table is done at runtime by the Windows loader. This is a bird's-eye view of the process, there are many boring details to make this happen as quickly as possible.
In managed code all of this is done at runtime, driven by the JIT compiler. It translates IL into machine code, driven by program execution. Whenever code executes that references another type, the JIT compiler springs into action, loads the type and translates the called method of the type. A side-effect of loading the type is loading the assembly that contains the type, if it wasn't loaded before.
Notable too is the difference for external dependencies that are available at build time. A C/C++ compiler compiles one source file at a time, the dependencies are resolved by the linker. A managed compiler normally takes all source files that create an assembly as input instead of compiling them one at a time. Separate compilation and linking is in fact supported (.netmodule and al.exe) but is not well supported by available tools and thus rarely done. Also, it cannot support features like extension methods and partial classes. Accordingly, a managed compiler needs many more system resources to get the job done. Readily available on modern hardware. The build process for C/C++ was established in an era where those resources were not available.
I believe the process you're asking about is the one called symbol resolution. In the common case, it works along these lines (I've tried to keep it pretty OS-neutral):
The first step is compiling of individual source files to create object files. The source code is turned machine language instructions, and any symbols (ie. function or external variable names) that aren't defined in the source file itself result in placeholders being left in the compiled machine language code, wherever they are referenced. The unknown symbol is also added to a list in the object file - at the end of compilation, this list contains every unresolved symbol in the object file, cross-referenced with the location in the object file of all the placeholders that were added. Each object file also contains a list of the symbols exported by that object file - that is, the symbols defined in that object file that it wants to make visible to code outside that object file - along with the values of those symbols.
The second step is static linking. This also happens at compile-time. During the static linking process, all of the object files created in the first step and any static library files (which are just a special kind of object file) are combined into a single executable. The static linker does a pass through the symbols exported by each object file and static library it has been told to link together, and builds a complete list of the exported symbols (and their values). It then does a pass through the unresolved symbols in each object file, and where the symbol is found in the master list, replaces all of the placeholders with the actual value of the symbol. For any symbols that still remain unresolved at the end of this process, the linker looks through the list of symbols exported by all dynamic libraries it knows about. It builds a list of dynamic libraries that are required, and stores this in the executable. If any symbols still haven't been found, the link process fails.
The third step is dynamic linking, which happens at run time. The dynamic linker loads the dynamic libraries in the list contained in the executable, and replaces the placeholders for the remaining unresolved symbols with their corresponding values from the dynamic libraries. This can either be done "eagerly" - after the executable loads but before it runs - or "lazily", which is on-demand, when an unresolved symbol is first accessed.
The C and C++ Standards have nothing to say about run-time loading - this is entirely OS-specific. In the case of Windows, one links the code with an export library (generated when a DLL is created) that contains the names of functions and the name of the DLL they are in. The linker creates stubs in the code containing this information. At run-time, these stubs are used by the C/C++ runtime together with the Windows LoadLibrary() and associated functions to load the function code into memory and execute it.
By libraries you are referring to DLLs right?
There are certain patterns for OS to look for required files (usually start from application local path, then proceed to folder specify by environment variable <PATH>.)

Categories