We have this Biztalk 2009 solution that, amongst other things, writes flat text files (tab separated) to a directory (a Send Port I believe).
Prior to writing the file, some logic is being performed on different fields (stripping unwanted characters, parsing, etc.) and this logic is held in standard C# classes.
Now that I have located this logic, where can I see where it is being used and referenced from?
I'm asking this as I would want to implement the same idea to other fields prior to the file being written.
The solution is quite huge.
I have looked through orchestrations and pipelines and could not find any mention of said classes and its methods.
I also, tried VS's seach "Entire Solution", found some mentions in some XSD/XML files, but nothing that tells me where the previous dev decided this logic would be used. Also tried "Find all references" but being a Biztalk application, it's not doing the same as in a standard .NET solution.
Turns out those classes and their methods are referenced in functoids.
If you open a .BTM file (mapping) you will see how data can be manipulated by these between the source and target schema.
By "Configuring Functoid Script" you can select either Inline C#, JScript.NET and others to perform certain operations on the flow of data between the source and target schema. One of these options is "External Assembly" where you'll be able to select a method from a class that you have referenced in your project.
By "Configuring Functoid Inputs", you'll be able to configure the parameters to be sent to the "External Assembly"'s referenced method.
By searching in "Entire Solution" for the method's name, you eventually find it mentionned in the XML content of the .BTM file. Open the BTM file (by just double clikcing on it in your solution) from there, look for all these "S" symbols in the grid, that's where it'll likely happen.
Related
I'm working on a Visual Studio extension that should listen for events when the user adds, removes, or renames files in the current solution.
The answer to this question notes that VS provides infrastructure for listening to document events like saving, opening and closing through the DocumentEvents interface. For example:
Dte.Events.DocumentEvents.DocumentSaved
Are there similar events that would allow me to listen to the user adding/removing/renaming documents?
First, don't use DTE if you can help it. It's a very incomplete, shaky abstraction papered over an extremely complex interface. Having said that, I admit that sometimes it's super handy because the equivalent either can't be done without it (rare) or the alternate code would be quite long (less rare).
There are two concepts being conflated here. The first is the Running Document Table (RDT). The RDT represents all the open files (including the open .sln and project files). You can subscribe to RDT events to be notified of files being opened, closed, renamed, etc. But these events are for open files only!
The second concept is the project system. Each project loaded and displayed in the solution explorer is loaded by the project system for that project's type. C++ projects, C# projects, F# projects, WIX installer projects, etc. all have different project systems. There can even be custom project systems implemented by extensions. It sounds like you want to know about events in the project system, and not events for (just) open files. So your focus is the project system. However, since all project systems have different implementations, this becomes very tricky. VS is moving towards a common project system (CPS), but it's not 100% there yet, and even when it is there remains the problem of all the legacy extensions, etc.
You can subscribe to general "hierarchy" events which all project systems must furnish. They'll tell you for example when a file is added or removed (really, when a hierarchy item (node) is added or removed, since there's not necessarily a correspondence between files and hierarchy items). There's also an event that says the entire hierarchy has been invalidated -- a sort of refresh where you have to discard everything you know about the project and gather up new info.
Rename is probably the hardest thing to detect. Every project system implements it differently. In some project systems, a rename will present itself as a node deletion followed by a node addition, with no solid way to identify that it was due to a rename.
To sum up, nothing is as simple as it seems, particularly when it comes to project systems (one of the least extensible parts of Visual Studio). You'll likely end up with code that is specific to one or a handful of project systems, but won't work universally. (After all, not all projects even represent file hierarchies! And those that do still have folders, special reference nodes, etc. that aren't files.)
Some concrete pointers in the right direction:
Implement IVsSolutionEvents3 to be notified of a project being loaded/unloaded (and IVsSolutionEvents4 to be notified of a project itself being renamed). Register that object as a listener in your package initialization code (make sure your package is loaded before a solution is opened) via the SVsSolution service (cast to IVsSolution and call AdviseSolutionEvents on it).
Implement IVsHierarchyEvents to be notified of project changes like node properties changing (use the __VSHPROPID enum to find out which is which), nodes being added, removed, invalidated, etc. Call AdviseHierarchyEvents on the IVsHierarchy object passed to the IVsSolutionEvents3's OnAfterProjectOpen implementation to register the event listener object.
You can subscribe to the EnvDTE.ProjectsEvents, EnvDTE.ProjectItemsEvents or IVsHierarchyEvents.
I know this is an old post by now, but for anyone else, who is searching for a fast solution. Take a look at the IVsTrackProjectDocuments2 class and it's matching IVsTrackProjectDocumentsEvents2 event interface.
You will receive notifications for all project items (Not solution items!), including Solution Items, which match the following actions:
Rename Directories
Rename Files
Add Directories
Add Files
Remove Directories
Remove Files
SccStatusChanged (I am guessing, that it will fire after a file's source-control state changed.)
These will contain an array of the changed items, their new state and the projects in which updates occurred. Additionally you will get a VS*FLAGS array, which contains more information about the current operation.
I'm writing custom language service as described in
https://msdn.microsoft.com/en-us/library/bb166533.aspx
Now I'm writing code for AuthoringScope (https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.package.authoringscope.aspx) My problem is in GetDeclarations method.
I have access to text of current file via ParseRequest.Text property.
It allows me to list all methods and variables in my file but how can I access other files content? I need to get access to other file content for building AST tree of this file but I don't know how can I do this.
Personally I find the MPF "helper" classes (like AuthoringScope) to be a bit restrictive, and implement everything manually (which, I admit, does take more time, but is a lot more flexible in the end).
In any case, it sounds like your language (like most!) has dependencies between files at the semantic parsing level. This means you'll either have to:
a) reparse a lot of text all the time, which is likely too slow in large projects
or b) maintain a global aggregate parse of a project's files, and update it dynamically when the files (or the project's properties) change
b) is obviously a lot harder, but is almost certainly the best way to do it. A general outline would be to discover all projects after a solution is opened via EnvDTE, parse them all (discover all files in each project, again via EnvDTE), and store everything in some sort of indexable data structure so that you can do fast queries against it (for semantic syntax highlighting, go to definition, etc.). Then you need to listen for changes everywhere and reparse appropriately -- you'll need to check for solution open/close (IVsSolutionEvents), projects being added/removed/renamed/unloaded/loaded (IVsSolutionEvents/IVsSolutionEvents4), files being added/removed/renamed (IVsHierarchyEvents), files being edited (IVsTextViewCreationListener + ITextBuffer.Changed), and project configurations changing (IVsUpdateSolutionEvents, IVsHierarchyEvents).
Whether you choose a) or b), you still need to be able to check if a file is opened in the editor (potentially with unsaved changes) or not. You can check if a file is already open in the Running Document Table (but don't forget to normalize the path first using Path.GetFullPath()) via the IVsRunningDocumentTable service, which will return an IntPtr to the document data, which can be coaxed into yielding an ITextBuffer for the file, which contains the text (and entire buffer history!) of the file. Of course, if it's not open you'll have to read it from disk.
Short version:
I want my program to be able to (read-only-)access its own source code during runtime. Is there a way to automatically package the source code into the dll during compilation?
Long version:
The background is that when an exception occurs, I want to automatically create a file containing some details of what happened. This file should, among other things, include the source code of the function that caused the problem. I want to send this file to other people by email, and the receiver will most likely not have (or not want to install) Visual Studio, so anything using symbol servers and the likes is out of question. It needs to be a plain text file.
Ideally I would somewhere find the related source code files and just copy out the relevant lines. You can safely assume that as long as I have a folder containing the entire source code, I will be able to locate the file and lines I want.
The best idea I could come up with so far -- and I have not looked into it in much detail because it seems messy to no end -- is to modify the MSBuild files to create a .zip of the source during compilation, and require .dll and .zip to reside in the same folder.
Most of the similar-sounding questions on stackoverflow that I found seem to deal with decompiling .dll files, which is not what I want to do. I have the source code, and I want to ship it together with the .dll in a convenient way.
Update: The really long version
Seems some people are seriously questioning why I would want to do that, so here's the answer: The main purpose of my software is testing some other software. That other software has a GUI. For an easy example, let's say the other software were the standard Windows calculator, then my testcase might look something like this:
calculator.Open();
calculator.EnterValue(13);
calculator.PressButtonPlus();
calculator.EnterValue(38);
calculator.PressButtonEnter();
int value = calculator.GetDisplayedValue();
Assert.That(value == 51);
calculator.Close();
These tests are intentionally written in a very human-readable way.
What I want to do when a problem occurs is to give the developer of the calculator a detailed description of how to reproduce the problem, in a way that he could reproduce by hand, without my software. (In this example, he would open the calculator, enter 13, press plus, and so on.)
Maybe another option would be to have each function calculator.Something() write out an information line to a log, but that would a) be a lot more work, b) only include the test run up to the point where it aborted, and c) bear some risk that writing the line is forgotten in one function, thereby giving an incorrect representation of what was done. But I'm open to other solutions than copying source code.
Take a look at this question: Do __LINE__ __FILE__ equivalents exist in C#?
C++ offers macros (__LINE__, __FILE__, and so on) that replace with the representing information during compile time. This means if you write something like this:
throw new CException(__FILE__);
it will compile to something like this:
throw new CException("test.cpp");
resulting in a hardcoded value. The C# compiler does not offer those macros and you are forced to use reflection to get the information about where the exception has been thrown. The way you can do it is described in the question linked above.
If you are not able to supply .pdb symbols then the default behaviour of Exception.ToString() (or StackTrace.ToString()) will not return you the line number, but the MSIL offsets of the operation that failed. As far as I can remember you can use the Stack Trace Explorer of ReSharper to navigate to the representing code (Not 100% sure about that, but there also was a question here on stackoverflow that mentioned this fact).
You can include copies of the source files as resources.
In the project folder, create a subfolder named Resources. Copy the source files there.
Create in the project a resource file, and then include the source copies you made into it.
Setup a pre-build event to copy the actual source files to Resources folder, so you always have updated copies. In the example I created, this worked well:
copy $(ProjectDir)*.cs $(ProjectDir)Resources
In your code, now you can get the content of the files like this (I suppose the name of the resources file is Resource1.resx:
// Get the source of the Program.cs file.
string contents = Resource1.Program;
The project ended up like this:
Yes, I also recommend packing up the sources in a .zip or whatever during MSBuild, and packaging that .zip with your application/dll. In runtime, when an exception occurs, you get the file and method name like Aschratt describes, extract the file from the .zip and find the method in it.
Application is a C# .Net 3.5 WCF Service.
I'd like during the build process to dynamically add some build information to the final binary and assemblies that can then be read programatically and sent back to the WCF client when it sends a GetVersionInfo request to the web service.
.Net assembly versioning isn't enough. I want to include additional string data that contains the state of the system at the time the application was built.
I'm thinking that I'd do this by adding a post build event to call a script to update the app.config file with the data I want. Does this sound about right, or should I be considering some other approach?
Update
I'd additionally like this string to appear in the "Special Build Description" property of the final exe. I.e. I'd like to right click on the file and see this information in the version tab for the file.
Thanks in advance.
I suspect a pre-build event may be more appropriate than post-build... have you considered adding a buildinfo.xml file (or similar) to be built into the assembly as an embedded resource? You could then load it with Assembly.GetManifestResourceStream. That way you don't need to worry about fitting in with existing files or anything like that - just overwrite buildinfo.xml with a new file in the pre-build step.
You have to decide how important it is that the information you want to exchange is tied to the executable file itself.
Updating the config file during the built is a workable model, but it places the information in a location where it could be altered by anyone with access and a text editor.
Updating information after a build in a compiled assembly is certainly possible, but it's fragile and breaks down if you ever decide to sign the assemblies. It's also a lot of work, since there's no built it support for re-writing assembly files in this manner.
An alternative you should consider, is creating your own custom assembly-level metadata attributes and assigning them during the build process. You could even place them in a separate code file (or append them to AssemblyInfo.cs) as part of you build.
You could also consider creating an embedded resource (an XML file, for instance), and retrieving it from the assembly manifest at runtime.
Either of the above approaches would require you to use a pre-build custom step rather than a post-build step.
Personally, I find the metadata attributes a convenient approach if there isn't a lot of data. Otherwise, I would consider using an embedded resource file.
I am working with a very big project (a solution that contains 16 projects and each project contains about 100 files).
It is written in C++/C# with Visual Studio 2005.
One of the projects has around 2000 resources out of which only 400 are actually used.
How do I remove those unused resources?
I tried to accomplish the task by searching for used ones.
It worked and I was able to build the solution, but it broke at runtime.
I guess because enums are used. (IMPORTANT)
How can I make sure that it doesn't break at runtime?
EDIT:
I think one method could be to generate the resource (that is not found) on the fly at runtime (somehow).
But I have no idea about ... anything.
NOTE: It's okay if a few unnecessary resources are still there.
What I would do is write a custom tool to search your source code.
If you remove a resource ID from a header file (i.e. possibly called resource.h) and then recompile and get no warnings: then that's a good thing.
Here is how I would go about writing the app. Take as input the resource file (resource.h) you want to scrutinize. Open the header file (*.h) and parse all the resource constants (Or at least the onces you are interested in). Store those in a hash table for quick look up later.
For each code file in your project, search the text for instances of each of your resource ID's. When a resource ID is used, increment the value in the hash table otherwise leave it at zero.
At the end, dump all the resource ID's that are zero out a log file or something. Then test that indeed you can remove those specified resource ID's safely. Once you do that, then write another tool that removes the specified resource ID's given the results of your log file.
You could write such a tool in perl and it would execute in about 0.3 seconds: But would take days to debug. :)
Or you could write this in .NET, and it would execute a little slower, but would take you an hour to debug. :)
You can use third party plug-in for Visual Studio as ReSharper. This add-in will analyze your C# code and point out unused resources. But it only works with C#.
For C++ projects, check out The ResOrg from Riverblade.
"The Resource ID Organiser (ResOrg for short) is an Add-in for Visual C++ designed to help overcome one of the most annoying (and unnecessary) chores of developing/maintaining Windows applications - maintaining resource symbol ID values"
http://www.riverblade.co.uk/products/resorg/index.html
I've never had one that bad. My method in compiled programs is to use a REXX script which emulates GREP looking for references to source that I suspect is not being used, remove them from the program and see what breaks. I use the REXX script because I can pre-filter the list of files I want to search. Which allows me to do a search across folders and computers.
If your code contains dynamic loading of resources (e.g. via strings) at runtime, then there is no way to automatically determine which resources can be safely removed from the source. A dynamic loading statement could load any resource.
Your best bet is to start with your trimmed down version of the app, run it, and identify which resources are missing when you test it. Then add them back in and retest.
You may want to take a look at the tool Reflector (free), not to be confused with ReSharper (expensive). It can show you which DLLs are dependent on another. Then if you want you may be able to remove the DLL that is not being referenced by anything else. Watch out if you are using dependency injection or reflection which then could break your code without your knowledge.
Reflector:
http://www.red-gate.com/products/reflector/.
This add-in draws assembly dependency graphs and IL graphs:
http://reflectoraddins.codeplex.com/Wiki/View.aspx?title=Graph.
In the "Resources View" of the Solution Explorer, right-click and select "Resource Symbols". Now you get a list where you can see which resources constants are used in the .RC-file. This help you might be a bit on the way to cleanup your Resource.h (although it does not show you which resources are not used in the actual C++ code).
Maybe Find Unused Resources in a .NET Solution helps here? Basically, you'll have to check which resources are used (e.g. by comprehensive code coverage checks) and remove the unused ones.
And probably you should not be afraid by using the trail-and-error approach to cleaning up.
In the Solution Explorer, right click and on a Reference and click on the menu item Find Dependent Code.
If it can't find any dependent code then you can remove this reference from the project. (The Remove operation is also under the right-click menu.)
EDIT: For a large project, the Find Dependent Code operation will take a long time. So since you have 2000 resources and most likely value your time this probably is not a viable option....
For C++ resources, did you try right-clicking the project in "Resource View" and then deleting the ones which do not have a tick mark next to them? It is unsafe to delete unused dialog resources since they are referenced as "enum"s in code (like the following).
enum { IDD = IDD_ABOUTBOX };
..however for all the others it should be safe.