Mon
Jan 25
2010

Find Conflicting Assembly References

A small test to help resolve the compiler warning:

warning MSB3247: Found conflicts between different versions of the same dependent assembly.

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
Ctrl-Alt-T: ReSharper.ReSharper_ShowUnitTestExplorer
Ctrl-Alt-R: ReSharper.ReSharper_ShowUnitTestSessions
Ctrl-Alt-E: ReSharper.ReSharper_UnitTest_RunCurrentSession

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

For ReSharper 3.0

For ReSharper 4.5

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:

  • Use AVG Free for quick scanning of files I believe are already clean.
  • Turn off real-time scanning – it’s not worth the performance hit for such low detection rates.
  • Use VirusTotal for scanning suspicious files.
  • Use Chrome and respect the malware warnings.

To recover from an infection:

  • Unplug infected drive.
  • Reinstall Windows on a new drive.
  • Reattached infected drive.
  • Install a virus/malware scanner. Run full/deep scan. Repeat a minimum of 3 times or until you stop finding infections.
  • Copy data from old drive and reformat.

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
- 46% preferred it, 33% didn’t care

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.
- Don’t provide options unless the user really wants to choose
- Use real-world metaphors
- Affordances
- Consistency with existing standards (good or bad)
- Users don’t read manuals
- Users don’t read anything (make text concise)
- Users can’t control the mouse very well (large click targets)
- Users can’t remember anything

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:

  • The plugin created backups but provided the wrong link to download them. I had to use the FTP client to download them manually. I believe this is because I have installed WordPress into a wordpress\ subfolder rather than into the root.
  • The plugin did not reactivate my plugins. I had to reactivate them manually.

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;

Older Posts »

© 2009 Brian Low. All rights reserved.