|
Mon
Jan 25 2010 |
Find Conflicting Assembly References |
|
A small test to help resolve the compiler warning:
Point it to the build folder of your project and it will look for referenced assemblies with the same short name but different full names. using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using NUnit.Framework; namespace MyProject { [TestFixture] public class UtilityTest { [Test] public void FindConflictingReferences() { var assemblies = GetAllAssemblies(@"E:\dev\myapp\myproject\bin\debug"); var references = GetReferencesFromAllAssemblies(assemblies); var groupsOfConflicts = FindReferencesWithTheSameShortNameButDiffererntFullNames(references); foreach (var group in groupsOfConflicts) { Console.Out.WriteLine("Possible conflicts for {0}:", group.Key); foreach (var reference in group) { Console.Out.WriteLine("{0} references {1}", reference.Assembly.Name.PadRight(25), reference.ReferencedAssembly.FullName); } } } private IEnumerable<IGrouping<string, Reference>> FindReferencesWithTheSameShortNameButDiffererntFullNames(List<Reference> references) { return from reference in references group reference by reference.ReferencedAssembly.Name into referenceGroup where referenceGroup.ToList().Select(reference => reference.ReferencedAssembly.FullName).Distinct().Count() > 1 select referenceGroup; } private List<Reference> GetReferencesFromAllAssemblies(List<Assembly> assemblies) { var references = new List<Reference>(); foreach (var assembly in assemblies) { foreach (var referencedAssembly in assembly.GetReferencedAssemblies()) { references.Add(new Reference { Assembly = assembly.GetName(), ReferencedAssembly = referencedAssembly }); } } return references; } private List<Assembly> GetAllAssemblies(string path) { var files = new List<FileInfo>(); var directoryToSearch = new DirectoryInfo(path); files.AddRange(directoryToSearch.GetFiles("*.dll", SearchOption.AllDirectories)); files.AddRange(directoryToSearch.GetFiles("*.exe", SearchOption.AllDirectories)); return files.ConvertAll(file => Assembly.LoadFile(file.FullName)); } private class Reference { public AssemblyName Assembly { get; set; } public AssemblyName ReferencedAssembly { get; set; } } } } |
|
Tue
Jul 28 2009 |
Resharper Shortcuts |
|
A few custom shortcuts because I can never remember which Resharper command they are… Alt-N: ReSharper.ReSharper_UnitTest_ContextRun Visual Studio macro for resetting these bindings: Imports System Imports EnvDTE Imports EnvDTE80 Imports EnvDTE90 Imports System.Diagnostics Public Module Module1 Public Sub BindShortcuts() Bind("ReSharper.ReSharper_UnitTest_ContextRun", "Alt+n") Bind("ReSharper.ReSharper_ShowUnitTestExplorer", "Ctrl+Alt+T") Bind("ReSharper.ReSharper_ShowUnitTestSessions", "Ctrl+Alt+R") Bind("ReSharper.ReSharper_UnitTest_RunCurrentSession", "Ctrl+Alt+E") Bind("File.CloseAllButThis", "Ctrl+Alt+Shift+W") MsgBox("Done.") End Sub Private Sub Bind(ByVal commandName As String, ByVal globalBinding As String) Dim command As Command command = DTE.Commands.Item(commandName, 1) command.Bindings = "Global::" & globalBinding End Sub End Module |
|
Mon
Apr 6 2009 |
Resharper live templates for NUnit |
aae Assert.AreEqual aane Assert.AreNotEqual aif Assert.IsFalse ait Assert.IsTrue ain Assert.IsNull ainn Assert.IsNotNull setup NUnit [Setup] method teardown NUnit [TearDown] method test NUnit [Test] method |
|
Mon
Jan 26 2009 |
EvoLisa Video |
|
Here is a video of Roger Alsing’s EvoLisa project evolving an image of the Mona Lisa using random polygons. The video was made using Roger’s source code modified with Dan Bystrom’s FitnessCalculator written in assembler. The program was changed to output a frame whenever the image improves by 5%. The program was run for 16 hours to generate the 660 frames used in the video below. The final image uses 242 polygons (average 6.9 points per polygon) and is the 7,052,061th generation. It only took 48 seconds to generate the first half of this video and the remaining 16 hours to generate the second half. I used VirtualDub to combine the frames into a video. The music clip is Company I from Philip Glass. By the way, Vimeo kicks butt on YouTube – higher quality videos and a better interface for uploading/managing videos. |
|
Sun
Jan 25 2009 |
Anti-Virus Software is Useless |
|
Over the holidays I was infected with multiple viruses. One them was Trojan.Vundo.GCY. It’s job is to download other viruses and malware. I had over a dozen files infected with various viruses causing popups and network slowdown. I tried 6 or 7 anti-virus / anti-malware products and found they had abysmally low detection rates. The best only finding 30% of infected files. This included software from Symantec Online Security Scan, Eset Nod32 Online Scanner, BitDefender Free Edition, AVG Free Edition, Spyware Doctor from the Google Pack, Malware Byte’s Anti-Malware and Ad-Aware Free. Perhaps using installed, retail versions would have given better results but I doubt it. All of the companies claim the free/online scanners use the same core engine and virus definitions as their retail products. I suspect this is true as it looks like these companies are competing on features like email integration, phishing protection and real-time scanning. I ran these scans from a fresh, uninfected install so its unlikely that any viruses were actively attempting to hide from a scan. As a result, I won’t be purchasing anti-virus software in the near future. I will keep AVG Free for quick scanning of files I believe are already clean. That statement shows how little confidence I have in these scanners. Despite this I think they are still good for catching the older viruses propagating among completely unprotected machines. I did find a useful website: VirusTotal.com lets you upload a file and scan it with almost 50 scanners. Here is an here is an example report). They also have a small utility you can install to get a right-click -> Send To target. You are limited to scanning one file at a time though can you can upload a zip archive to scan several. There are a number of similar websites, but VirusTotal appears to be the best. My anti-virus/malware strategy:
To recover from an infection:
How do you prevent infections? |
|
Fri
Nov 7 2008 |
Zebra striping |
|
From the article Zebra Striping: Does it Really Help?: - no difference in speed or accuracy If you are going to use zebra striping, keep it subtle. Update: a followup post with more research confirming this approach. |
|
Thu
Nov 6 2008 |
User Interface Design for Programmers |
|
From Joel Spolsky’s article User Interface Design for Programmers: - A user interface is well-designed when the program behaves exactly how the user thought it would. |
|
Sun
Aug 31 2008 |
Build ASP.NET WebService from the Command-line |
|
This NAnt target will build the project into a new folder with a (single) precompiled DLL. All source files and other non-deployment files are removed. <target name="publish.webservice"> <exec basedir="." program="${msbuild.exe}" commandline=" ${web.project.file} /nologo /p:OutDir=${publish.webservice.dir}bin /p:WebProjectOutputDir=${publish.webservice.dir}" workingdir="." failonerror="true" /> </target> |
|
Wed
Apr 30 2008 |
Upgrading to WordPress 2.5 on BlueHost |
|
WordPress 2.5 was released last month. Why can’t we upgrade using Fantastico? It turns out BlueHost has started their own Fanastico competitor called SimpleScripts. I doubt we’ll be seeing any new Fantastico updates. While Fantastico has had WordPress 2.5 scripts for at least three weeks, BlueHost’s tech support claims they are waiting on Fantastico to release updated scripts. This is the first problem. The second problem is the recommended migration procedure here and here. It involves FTP clients and pulling database configuration bits from php files. This does not leave a good first impression of a product that is supposed to provide one-click installation and upgrades. I ended up using the Wordpress Automatic Upgrader Plugin. I still needed to use an FTP client to install the plugin but now I am not dependent on Fanastico or SimpleScripts. This plugin downloads the latest files directly from WordPress so updates should be available as soon as WordPress releases them. I encountered two problems while upgrading to 2.5:
On the positive side, SimpleScripts appears to be a more polished product compared to Fantastico. |
|
Tue
Apr 29 2008 |
Reset Sequence From Table |
|
This procedure will lookup the maximum value used in a table then set the sequence to this value + 1. Based on code from from http://www.psoug.org/reference/sequences.html. CREATE OR REPLACE PROCEDURE reset_sequence ( seq_name IN VARCHAR2, startvalue IN PLS_INTEGER) AS cval INTEGER; inc_by VARCHAR2(25); BEGIN EXECUTE IMMEDIATE 'ALTER SEQUENCE ' ||seq_name||' MINVALUE 0'; EXECUTE IMMEDIATE 'SELECT ' ||seq_name ||'.NEXTVAL FROM dual' INTO cval; cval := cval - startvalue + 1; IF cval = 0 THEN RETURN; ELSIF cval < 0 THEN inc_by := ' INCREMENT BY ' || ABS(cval); ELSE inc_by := ' INCREMENT BY -' || cval; END IF; EXECUTE IMMEDIATE 'ALTER SEQUENCE ' || seq_name || inc_by; EXECUTE IMMEDIATE 'SELECT ' ||seq_name ||'.NEXTVAL FROM dual' INTO cval; EXECUTE IMMEDIATE 'ALTER SEQUENCE ' || seq_name || ' INCREMENT BY 1'; END reset_sequence; / CREATE OR REPLACE PROCEDURE reset_sequence_from_table ( seq_name IN VARCHAR2, column_name IN VARCHAR2, table_name IN VARCHAR2) AS cval INTEGER; BEGIN EXECUTE IMMEDIATE 'SELECT MAX(' || column_name ||') FROM ' || table_name INTO cval; IF (cval IS NULL) THEN cval := 1; ELSE cval := cval + 1; END IF; RESET_SEQUENCE(seq_name, cval); END reset_sequence_from_table; / Setup some test data to verify the proc: DROP sequence mytable_seq; DROP TABLE mytable; CREATE TABLE mytable ( id NUMBER ); CREATE sequence mytable_seq; INSERT INTO mytable VALUES (1); INSERT INTO mytable VALUES (2); INSERT INTO mytable VALUES (3); INSERT INTO mytable VALUES (4); INSERT INTO mytable VALUES (5); INSERT INTO mytable VALUES (6); INSERT INTO mytable VALUES (7); INSERT INTO mytable VALUES (8); INSERT INTO mytable VALUES (9); INSERT INTO mytable VALUES (10); SELECT mytable_seq.NEXTVAL FROM dual; SELECT mytable_seq.NEXTVAL FROM dual; SELECT mytable_seq.NEXTVAL FROM dual; SELECT mytable_seq.NEXTVAL FROM dual; SELECT mytable_seq.NEXTVAL FROM dual; SELECT mytable_seq.NEXTVAL FROM dual; SELECT mytable_seq.NEXTVAL FROM dual; SELECT mytable_seq.NEXTVAL FROM dual; SELECT mytable_seq.NEXTVAL FROM dual; COMMIT; A test: exec reset_sequence_from_table('MYTABLE_SEQ', 'ID', 'MYTABLE'); -- should return 11 because mytable has a record with id 10 SELECT mytable_seq.NEXTVAL FROM dual; |