Wednesday, May 31, 2017

string.Format with params trap

Lately i have seen this code

        static void LogError(string error, params object[] details)
        {
            var message = string.Format(error, details);
            Console.WriteLine(message);
        }

The code compiles and runs without problems, and if p is passed as a single string, would work fine. If someone knows that it should be a single string.
If someone else is using the same method he might fall into a trap assuming that the params is optional, which would also compile but would give exception during runtime.

Ex:
        static void Main(string[] args)
        {
            var message = "Error occurred, details: {0}";
            LogError(message, "details");
            LogError(message);
        }

        static void LogError(string error, params object[] details)
        {
            var message = string.Format(error, details);
            Console.WriteLine(message);
        }

It would compile and run, but would give an error

An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll

Additional information: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.

Another developer might assume that he can pass multiple params, which would only take the first one and ignore the others

Ex:
        static void Main(string[] args)
        {
            var message = "Error occurred, details: {0}";
            LogError(message, "details");
            LogError(message, "details", "more details ");
        }

        static void LogError(string error, params object[] details)
        {
            var message = string.Format(error, details);
            Console.WriteLine(message);
        }


Would output:
Error occurred, details: details
Error occurred, details: details

Registering all ocx files

I had an old app that is using windows controls ocx libraries, like comctl32.ocx, comdlg32.ocx And others
The program was complaining about missing comctl32.ocx, then i did register it with the below command, running it in elevated command prompt 
regsvr32 c:\Windows\SysWOW64\comctl32.ocx

Starting the app again it complained about another missing ocx. 


In that case it might be better to register all the ocx files in the SysWOW64 folder by running the below command

forfiles /p "c:\Windows\SysWOW64" /m *.ocx /c "cmd /c regsvr32 @file"