Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging C# Custom Installer Classes

I have written an installation class that extends Installer and overrides afterInstall, but I'm getting a null pointer exception. How can I go about debugging my class?

like image 304
Deano Avatar asked Nov 10 '08 23:11

Deano


People also ask

What is debugging in C?

Debugging is a methodical process of finding and reducing the number of bugs (or defects) in a computer program, thus making it behave as originally expected.

Can you debug C code?

Set up a break point inside C program Places break point in the C program, where you suspect errors. While executing the program, the debugger will stop at the break point, and gives you the prompt to debug.

Is debug hard C?

Compared to other programming languages, C can be a more difficult language to debug and figure out errors within code, no matter if it is logic or syntax-based.


2 Answers

Something that is handy for hard to debug sections of code is

System.Diagnostics.Debugger.Break() 

Will throw a breakpoint caught by any installed debugger (VStudio, WinDbg, Remote debugger etc...).

Use it to debug really tricky areas where regular F5+Go or "Attach to Process" is difficult or impossible to perform, some examples include:

  • short-lived processes
  • time-sensitive processes
  • breaking into spawned sub-processes
  • installers
  • service stop/start
  • distributed systems
like image 138
2 revs Avatar answered Oct 16 '22 21:10

2 revs


The best way I've found is to write a unit test, and new up and initialize your installer class from your unit test:

[TestClass] public class InstallerTest { [TestMethod] public void InstallTest() {   // substitute with your installer component here   DataWarehouseInstall installer = new DataWarehouseInstall();    string assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);    string installLogFilePath = Path.Combine(assemblyDirectory, "install.log");   installer.Context = new System.Configuration.Install.InstallContext(installLogFilePath, null);          // Refactor to set any parameters for your installer here   installer.Context.Parameters.Add("Server", ".");   //installer.Context.Parameters.Add("User", "");   //installer.Context.Parameters.Add("Password", "");   installer.Context.Parameters.Add("DatabaseName", "MyDatabaseInstallMsiTest");   //installer.Context.Parameters.Add("DatabasePath", "");    // Our test isn't injecting any save state so we give a default instance for the stateSaver   installer.Install(new Hashtable()); } } 

At least then it takes advantage of the IDE tooling better. This is especially helpful for very large installers with LOTS of components. Then you can also create ordered unit tests and run them in sequence to mimic your installer during debug or your automated builds.

Another tip would be general SOLID/GRASS software principles...develop in neat/thin layers, keeping your actual "custom action" installer logic very simple and instead call into any reusable API stuff you have that is specific to your installer(s), just as we are used to with UI development. (The installer is just another UI anyway.) This is especially key if your goal is to have a certain UI experience shared across all installers of your products.

like image 38
Timex Avatar answered Oct 16 '22 19:10

Timex