public void Run()
        {
            // Set up paths and create required folders.
            try {             // Trycrash-Construct
                StorageKeyPath      = String.Format("{0}\\Keys", StoragePath);
                StorageDatabasePath = String.Format("{0}\\Sqlite.db", StoragePath);

                Directory.CreateDirectory(StoragePath);
                Directory.CreateDirectory(StorageKeyPath);
                //Directory.CreateDirectory(StorageDatabasePath);
            } catch (Exception e) {
                Console.WriteLine(e);
                throw;
            }

            // Connect or create Sqlite database and setup tables, if they don't exist.
            try {             // Trycrash-Construct
                Database = new SqliteConnection(new DbConnectionStringBuilder {
                    { "Uri", new Uri(@StorageDatabasePath).AbsoluteUri },
                }.ConnectionString);
                Database.Open();

                // Try create threads table.
                var createThreadsTableCmd = Database.CreateCommand();
                createThreadsTableCmd.CommandText = String.Format(TABLETHREADS, TABLETHREADSNAME);
                createThreadsTableCmd.ExecuteNonQuery();

                // Try create blocks table.
                var createBlocksTableCmd = Database.CreateCommand();
                createBlocksTableCmd.CommandText = String.Format(TABLEBLOCKS, TABLEBLOCKSNAME);
                createBlocksTableCmd.ExecuteNonQuery();

                // Try create stati table.
                var createStatiTableCmd = Database.CreateCommand();
                createStatiTableCmd.CommandText = String.Format(TABLESTATUS, TABLESTATUSNAME);
                createStatiTableCmd.ExecuteNonQuery();
            } catch (Exception e) {
                Console.WriteLine(e);
                throw;
            }

            DatabaseMutex = new Mutex();

            // Calculate Block limits.
            BlockMaximum = BigInteger.Divide(BigInteger.Pow(8, 48), BlockSize);

            // Create Threads.
            var crackerThreads = new CrackerThread[Environment.ProcessorCount];

            for (uint currentThreadId = 0; currentThreadId < Environment.ProcessorCount; currentThreadId++)
            {
                crackerThreads[currentThreadId] = new CrackerThread(this, currentThreadId);
                crackerThreads[currentThreadId].TryStart();
            }

            // Wait for user input to be 'stop'.
            String userCommand;

            while ((userCommand = Console.ReadLine()) != "stop")
            {
                Console.WriteLine("Unknown command: {0}", userCommand);
            }

            // Stop threads.
            for (uint proc = 0; proc < Environment.ProcessorCount; proc++)
            {
                crackerThreads[proc].TryStop();
            }

            Database.Close();
        }
		public void Run() {
			// Set up paths and create required folders.
			try { // Trycrash-Construct
				StorageKeyPath = String.Format("{0}\\Keys", StoragePath);
				StorageDatabasePath = String.Format("{0}\\Sqlite.db", StoragePath);

				Directory.CreateDirectory(StoragePath);
				Directory.CreateDirectory(StorageKeyPath);
				//Directory.CreateDirectory(StorageDatabasePath);
			} catch (Exception e) {
				Console.WriteLine(e);
				throw;
			}

			// Connect or create Sqlite database and setup tables, if they don't exist.
			try { // Trycrash-Construct
				Database = new SqliteConnection(new DbConnectionStringBuilder {
					{ "Uri", new Uri(@StorageDatabasePath).AbsoluteUri },
				}.ConnectionString);
				Database.Open();

				// Try create threads table.
				var createThreadsTableCmd = Database.CreateCommand();
				createThreadsTableCmd.CommandText = String.Format(TABLETHREADS, TABLETHREADSNAME);
				createThreadsTableCmd.ExecuteNonQuery();

				// Try create blocks table.
				var createBlocksTableCmd = Database.CreateCommand();
				createBlocksTableCmd.CommandText = String.Format(TABLEBLOCKS, TABLEBLOCKSNAME);
				createBlocksTableCmd.ExecuteNonQuery();

				// Try create stati table.
				var createStatiTableCmd = Database.CreateCommand();
				createStatiTableCmd.CommandText = String.Format(TABLESTATUS, TABLESTATUSNAME);
				createStatiTableCmd.ExecuteNonQuery();
			} catch (Exception e) {
				Console.WriteLine(e);
				throw;
			}

			DatabaseMutex = new Mutex();

			// Calculate Block limits.
			BlockMaximum = BigInteger.Divide(BigInteger.Pow(8, 48), BlockSize);

			// Create Threads.
			var crackerThreads = new CrackerThread[Environment.ProcessorCount];
			for (uint currentThreadId = 0; currentThreadId < Environment.ProcessorCount; currentThreadId++) {
				crackerThreads[currentThreadId] = new CrackerThread(this, currentThreadId);
				crackerThreads[currentThreadId].TryStart();
			}

			// Wait for user input to be 'stop'.
			String userCommand;
			while ((userCommand = Console.ReadLine()) != "stop") {
				Console.WriteLine("Unknown command: {0}", userCommand);
			}

			// Stop threads.
			for (uint proc = 0; proc < Environment.ProcessorCount; proc++) {
				crackerThreads[proc].TryStop();
			}

			Database.Close();
		}