We recently had a developer leave our organization. We're not sure if the version of an executable he put on a production server is the same that is currently in TFS. Is there any way (besides using something like Just Compile or ILDASM) to build the project from TFS and compare that executable to the one currently on our production server?
UPDATE: I'm trying out Just Decompile, and I've loaded both binaries, so I'm stepping through each namespace, member, etc to compare them against each other. I'm used to using Schema Compare in Visual Studio to compare the schemas of 2 databases and seeing the updated, removed and added items with the differences highlighted. Isn't there some tool that would take these 2 decompiled binaries and somehow highlight the differences?
Right now I can only think of this approach:
Use dotPeek to decompile the live assembly
Use dotPeek to decompile the same assembly freshly built from TFS
Use a tool like Beyond Compare on the two decompiled sources
Merge the changes as necessary
Hope this is what you were looking for??
Other reading that may be beneficial for the future in terms of versioning so you know what dll contains what functionality (may or may not be useful for you, forgive me if I am telling you something obvious):
Best practices/guidance for maintaining assembly version numbers
Good luck
Yes using NDepend you can diff between two .Net assemblies. Although even compiling exactly the same source twice will not generate exactly the same assemblies.
A product we use for detailed comparisons, including comparisons of binary files, is Beyond Compare. When we first got the product I thought it would be something of limited utility, but it has helped us solve some very tricky problems. It compares directories, text files, binary files, mp3's, pictures, and software versions. It's not particular expensive either.
I just ran the product against the binaries of an application in both Release and Debug and it highlighted every diff.
I am sure that you could run ILDASM against two binaries and do an eyeball comparison, but a tool like this will probably pay for itself over and over again.
Related
I wrote a windows application using C# .Net 2.0 and i want to do something which hide the source code, so when any one use refactor tool can't see the source code.
I used dotfuscator but it just changed the function names but not all the source code.
UPDATE:
I want to hide the source code, not because of hiding the key, but to hide how the code is working.
Thanks,
IL is by definition very expressive in terms of what remains in the body; you'll just have to either:
find a better (read: more expensive) obfuscator
keep the key source under your control (for example, via a web-service, so key logic is never at the client).
Well, the source code is yours and unless you explicitly provide it, youll perobably only be providing compiled binaries.
Now, these compiled binaries are IL code. To prevent someone "decompiling" and reverse engineering your IL code back to source code, you'll need to obfuscate the IL code. This is done with a code obfuscator. There are many in the marketplace.
You've already done this with dotfuscator, however, you say that it only changed the function names, not all the source code. It sounds like you're using the dotfuscator edition that comes with Visual Studio. This is effectively the "community edition" and only contains a subset of the functionality of the "professional edition". Please see this link for a comparison matrix of the features of the community edition and the professional edition.
If you want more obfuscation of your code (specifically to protect against people using tools such as Reflector), you'll need the professional edition of Dotfuscator, or another code obfuscator product that contains similar functionality.
As soon as people get a hand on your binaries they can reverse-engineer it. It’s easier with languages that are compiled to bytecode (C# and Java) and it’s harder with languages that are compiled to CPU-specific binaries but it’s always possible. Face it.
Try SmartAssembly
http://www.smartassembly.com/index.aspx
There are limits to the lengths obfuscation software can go to to hide the contents of methods, fundamentally changing the internals without affecting the correctness (and certainly performance) is extremely hard.
It is notable that code with many small methods tends to become far harder to understand once obfuscated, especially when techniques for sharing names between methods that would appear to collide to the eye but not to the runtime are employed.
Some obfuscators allow the generation of constructs which are not representable in any of the target languages, the set of all operations allowable in CIL for example is way more than that expressible through c# or even C++/CLI. However this often requires an explicit setting to enable (since it can cause problems). This can cause decompilers to fail, but some will just do their best and work around it (perhaps inlining the il it cannot handle).
If you distribute the pdb's with the app then even more can inferred due to the additional symbols.
Just symbol renaming is not enough of a hindrance to reverse-engineering your app. You also need control flow obfuscation, string encryption, resource protection, meta data reduction, anti-reflector defenses, etc, etc. Try Crypto Obfuscator which supports all this and more.
Create a setup project for your application and install the setup on your friends computer like a software. There are 5 steps to creating the setup project using microsoft visual studio.
Step 1: Create a Sample .Net Project. I have named this project as "TestProject" after that build your project in release mode.
Step 2: Add New Project using right click on your solution and select setup project and give the name this as "TestSetup".
Step 3: Right click on setup project and Add primary Output and select your project displayed.
Step 4: Right Click the setup project and select View-> File System -> Application Folder. Now copy what you want to be in installation folder.
Step 5: Now go to our project folder and open the release folder you can get the setup.exe file here. Double click on the "TestSetup" file and install your project to your and other computer.
We have a project that uses a couple of assemblies.
Is there an easy way of handling the version of all those assemblies at once?
We have a version like
major.minor.patch.revision
Most of the times on a release, just the minor version gets a change.
A critical part is the revision which is the fileversion in the repository.
At the moment I think this makes impossible to use one AssemblyInfo.cs for all assemblies.
How can I avoid to change the AssemblyInfo.cs of all those assemblies?
If you want all of the assemblies to have the same version, you can make a single .cs file for the versioning in one of your libraries, and add it as a link to the other projects.
This will cause the single file to be part of all three assemblies, and keep the version constant across them all.
I've found that this is easiest to do when you're going to create your build artifacts. From a process standpoint, you would:
1. Tag/Label Source
2. Get by Tag/Label
3. Edit AssemblyInfo files
4. Build, Test, Etc
5. Capture Build Artifact
This is all pretty easy to do in BuildMaster(disclaimer: I work for Inedo as a set of actions. In this case it'd be just using the Write Assembly Versions action after doing a Get Latest action.
You can see this pattern used a lot in the specifics libraries. When we build ProGet, for example, you'll notice that Write Assembly Versions shortly after comparing the directories for changings, and right before running msbuild.
When I recompile my project (asp.net, c#) with aspnet_compiler the rebuilt binaries change (when compared to the previous build) even if no code changes have been made.
This, I understand, is due to the build generating a new Module Version ID (guid) each time it builds (to distinguish between builds), another similar question talks about this: Can i specify the module version id (MVID) when building a .net assembly?
The above linked question seems to suggest there is no way to rebuild a project and have the binaries match a previous build of the same unchanged code.. ok, fine, I understand - but why are all the binaries being rebuilt at all?
I would think, according to the documentation ( http://msdn.microsoft.com/en-us/library/ms229863(v=vs.80).aspx ), that unless -c is specified as an argument the aspnet_compiler should only rebuild those binaries that actually need to be (due to changed code). Am I misunderstanding or maybe missing something?
The aspnet_compiler arguments I'm using:
aspnet_compiler -f -u -fixednames -nologo -v / -p .\myproject\ .\mybuild\
Note that this issue occurs only with a WebSite project, not a Web Application project (they are compiled differently).
Also this issue occurs even if you create a WebSite project and page with no functionality, and never open it or change it in anyway between builds.
Decompiling the binaries that are produced shows no differences. Comparing the binaries of two "identical" builds shows small differences in the same part of the binaries each time - which I believe is probably related to the random build guid. I've found no way of avoiding this change between builds.
Check out this excellent answer by Eric Lippert on how does the C# compiler makes multi passes to compile the source code. There can me many reasons why your build was not identical to the previous one, although the functionality is same.
Compilers replace special language features such as using block with with IL equivalents
The compilers does many optimizations on your code, each iteration may produce slightly different output.
Compilers have to create materialized names for anonymous method names and they are different each time you compile
And many more reasons you could easily figure it out using a dis-assembler
Check out these dis-assemblers and decompile your library or executable to gain better understanding.
http://ilspy.net/ , http://www.telerik.com/products/decompiler.aspx
I've found in many cases using the aspnet_compiler especially in situations where my projects have references to other project in the same solution results in full rebuilds that are often hard to explain. (though the few times I've investigated there were "changes" even if they don't truly effect anything such as changes to whitespace, comments, etc)
I've also had problems with a number of plugins in visual studio that have done everything from manipulate tabulation and other white space, the actual project file, etc. While these changes have no noticeable change to us humans, the compiler takes one look and goes "I see a change! REBUILD ALL THE THINGS!!!"
Not sure my answer is any help, but I would disable your plugins, run the compiler, then run the compiler again and see what happens...
I've got a bunch of .dll assemblies, such as HtmlAgilityPack and MoreLinq. Where am I supposed to put these files? I usually toss them somewhere in my Projects folder, but then I'm always digging around for them. Is there a standard place to put them?
There's no standard place to put them, but make sure you:
Put them in one place
Include them in source control.
I put all my required dll's in a top level directory in my solution called "Dependencies", parallel to the project folders. I have them in source control such that when new developers check out the solution, it all compiles and works right off. It's the only way to go.
I include only the .dll files absolutely needed. This keeps it light, which is good, but then when I find some other part of MVC Contrib or whatever that I need, I have to go find the unzipped directory, which might not even be on my computer! Others put entire library directories (readme.txt and all) as part of their source control linked to the solution. This ensures you and future developers will have everything they need, but adds a little dead weight. Either is a good strategy.
Having a "Lib" folder at the same level as source projects is a common way.
To be honest, it's not the dependencies my projects have that I find hard to manage, it's the dependencies the dependencies have. I'd just like to mention NHibernate, Castle Windsor and the various Castle Windsor Facilities in particular. Getting all of those to play together on my last project cost me a lot of time.
For open source projects, I also like to have the source code handy because sometimes its useful to debug into the source code. (And sometimes because the documentation is so poor, you have to read the source code to find out how it works). I've seen VS projects arranged so that the project references the DLL yet at the same time, VS knows where to find the source code, as I write I can't quite remember how to do that.
So, a Lib folder for DLLs works for me; I often call it "Shared Dependencies".
As for open-source source code, I don't have a standard way to version that because each project is structured differently and has a different build process. I don't like to tinker with the open-source project structure or build method because then, I take responsibility for it. If for some reason, it won't build, or builds incorrectly, or produces a faulty DLL, the cause would be exceedingly difficult to track down, and I'd have to get deep into troubleshooting all of that which I dont care about at all.
In a folder UNDER your solution directory, e.g. "external" or "library". That way your continuous integration system (or other team members) can do a pull of one root from your source control system and have everything they need.
In SVN, use svn:externals to pull that directory from a different root so you can easily share library DLLS (and library projects) between solutions.
In the office we have a share on the network for referenced asseblies. These could be 3rd party or assemblies of our own that could be shared between projects.
I also, don't like the idea of putting the dll files in source control. If all the developers have access to the share all will work fine.
The visual studio directory in My Documents seems like a logical place to put them. I don't know if it's the best or anything wrong with it but at least all the libraries are found in one place.
%USERPROFILE%\My Documents\Visual Studio XXXX\Libraries
At my company we place all our shared DLL assemblies onto a network drive in a folder called Assemblies. From there, we use SyncToy to mirror changes between that folder and a folder on our local development machines (in my case C:\Assemblies with subfolders for different versions or useful third party assemblies). Using the "Reference Paths" feature of Visual Studio projects makes it very easy to select different assembly versions based only on locations.
For projects at home, I would definitely go with the idea mentioned by Jeff M of placing them in the Visual Studio folder under My Documents.
I don't have a hard and fast rule on the location. However, I would encourage consistency!
For example, I needed to to this for a small tool I'm writing for a client at the moment, so I checked their other code bases in Bitbucket which seemed to use a dependencies folder in the solution folder (alongside the other projects), so I copied that.
I am building a C# solution in Visual Studio 2008 that has several projects and project dependencies. I am looking for a way to change dll version numbers ONLY when the code that builds the project changes. I currently use Beyond Compare to compare my locally built version to the production file system. The goal is to ONLY deploy updated dlls. I am using autoincrementing version numbers, and each time you open visual studio and do a build, all dll version numbers increment. The same goes for a full solution rebuild and when a different developer does a build and tries to deploy. Is there a way that i can configure Visual Studio to ONLY increment the build number based on changed file contents? Is there an add in that will do this?It seems a binary comparison of these files will also fail because of the different version numbers within the dlls. Does anyone know of a better tool compare only the contents of dlls?Thanks in advance.
One option is to move to a continuous integration solution such as Cruise Control .Net this allows builds to be triggered on check in to a source control system.
Regarding assembly versioning what I usually do is create a single SolutionVersion.cs (to replace the default assembly version cs) that is linked to each project (use the add existing item but change the button to add as link)
Then I use a NAnt or MSBuild task to take the cruise control build label number and overwrite the SolutionVersion.cs verison numbers before the solution gets built
That way I can take an assembly and trace it back to the code via CruiseControl build version (even better I usually get CC.net to label the source with the same number in source control)
Its not quite what you are asking, but I found this helpful in dealing with large solutions: Versioning Controlled Build. According to its doc it detects the changes you are interested in :
"If there is a file with a more recent timestamp (which means that the source code has been modified after the previous version change), the project will be marked for version update."
The recommended, supportable solution would be for your project to NOT auto-increment the build number using the visual studio way. Then you would need to manually, or write a pre-build script/ MS Build Task to do the increment.
There is an interesting sample in this codeproject article which you should check it out... it involves a prebuild task which does the task of updating the build number based on the day of the year
I would suggest that you look into options that your revision control system provides to embed revision information into source files. I've had enough problems with auto-increment in the past that I promised myself never again. These days I prefer something a little more concrete than a build number though and embed unique identifiers into every product of the build system.
I describe my own system in Embedding mercurial revision information in Visual Studio c# projects automatically. While my solution probably isn't right for you, there were other interesting options suggested in response to my question, so some of the solutions I rejected may, nevertheless, be useful to you, even if you have to adapt them to whatever VCS you use.