Created
April 12, 2023 22:39
-
-
Save guillaC/4eb7f0e8a5184a8b95caa3230f6db91d to your computer and use it in GitHub Desktop.
This app allows you to browse all SQLite files on a machine. Note: it is not possible to read a file that is already in use, you would need to make a copy before reading.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Data; | |
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder; | |
using System.Data.SQLite; | |
using Spectre.Console; | |
using Rule = Spectre.Console.Rule; | |
using Color = Spectre.Console.Color; | |
class ReadAllSQLiteFiles | |
{ | |
static void Main(string[] args) | |
{ | |
var options = new EnumerationOptions() | |
{ | |
IgnoreInaccessible = true, | |
RecurseSubdirectories = true, | |
}; | |
foreach (string drive in Environment.GetLogicalDrives()) | |
{ | |
var rule = new Rule($"[red]Processing drive {drive}[/]"); | |
rule.Justification = Justify.Left; | |
AnsiConsole.Write(rule); | |
var files = Directory.EnumerateFiles(drive, "*", options); | |
files = files.Where(file => !file.Contains("\\Windows\\")).ToList(); | |
int nbFScan = 0; | |
try | |
{ | |
foreach (string file in files) | |
{ | |
Console.Title = $"{nbFScan}/{files.Count()}"; | |
if (IsSQLiteFile(file)) | |
{ | |
var path = new TextPath(file).RootColor(Color.Red).SeparatorColor(Color.Green).StemColor(Color.Blue).LeafColor(Color.Yellow); ; | |
AnsiConsole.Write(path); | |
ShowTablesNRows(file); | |
} | |
nbFScan++; | |
} | |
} | |
catch (Exception ex) | |
{ | |
AnsiConsole.WriteException(ex); | |
} | |
} | |
} | |
static bool IsSQLiteFile(string file) | |
{ | |
byte[] header = new byte[16]; | |
try | |
{ | |
using (FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read)) | |
{ | |
stream.Read(header, 0, 16); | |
} | |
} | |
catch | |
{ | |
return false; | |
} | |
string headerText = System.Text.Encoding.UTF8.GetString(header); | |
return headerText.StartsWith("SQLite format"); | |
} | |
static void ShowTablesNRows(string file) | |
{ | |
SQLiteConnection connection = new SQLiteConnection($"Data Source={file};Version=3;"); | |
try | |
{ | |
connection.Open(); | |
DataTable table = connection.GetSchema("Tables"); | |
foreach (DataRow row in table.Rows) | |
{ | |
string tableName = (string)row[2]; | |
Console.WriteLine(tableName); | |
using (var command = new SQLiteCommand($"SELECT * FROM {tableName}", connection)) | |
{ | |
using (var reader = command.ExecuteReader()) | |
{ | |
var consTab = new Table(); | |
int nbCol = reader.FieldCount; | |
for (int i = 0; i < nbCol; i++) | |
{ | |
string colName = Markup.Escape(reader.GetName(i)); | |
consTab.AddColumn(colName); | |
} | |
while (reader.Read()) | |
{ | |
List<string> oneRow = new(); | |
for (int i = 0; i < nbCol; i++) | |
{ | |
string dataRow = Markup.Escape(reader.GetValue(i).ToString()); | |
oneRow.Add(dataRow); | |
} | |
consTab.AddRow(oneRow.ToArray()); | |
} | |
AnsiConsole.Render(consTab); | |
} | |
} | |
Console.WriteLine(); | |
} | |
} | |
catch (Exception ex) | |
{ | |
AnsiConsole.WriteException(ex); | |
} | |
finally | |
{ | |
connection.Close(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Il n'est pas possible d'utiliser SearchOption.AllDirectories et EnumerationOptions.IgnoreInaccessible simultanément dans la méthode Directory.EnumerateFiles de .NET.
Il faut donc utiliser cette méthode custom pour l'énumération des fichiers pour accéder aux répertoires spéciaux (comme APPDATA, qui est exclu par défaut de la méthode Directory.EnumerateFiles).