Skip to content

Commit 763ce0e

Browse files
committed
Установка файловой ассоциации с *.log файлами и открытие приложение с параметром пути к лог файлу.
1 parent f90d8d2 commit 763ce0e

5 files changed

Lines changed: 152 additions & 53 deletions

File tree

LogViewer/FileAssociations.cs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using Microsoft.Win32;
2+
using System;
3+
using System.Diagnostics;
4+
using System.Windows;
5+
6+
namespace LogViewer
7+
{
8+
public class FileAssociations
9+
{
10+
// needed so that Explorer windows get refreshed after the registry is updated
11+
[System.Runtime.InteropServices.DllImport("Shell32.dll")]
12+
private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
13+
14+
private const int SHCNE_ASSOCCHANGED = 0x8000000;
15+
private const int SHCNF_FLUSH = 0x1000;
16+
private const string Extension = ".log";
17+
private const string ProgId = "Directum_Log_Viewer_File";
18+
private const string FileTypeDescription = "Directum Log Viewer File";
19+
20+
public static void SetAssociation()
21+
{
22+
try
23+
{
24+
var filePath = Process.GetCurrentProcess().MainModule.FileName;
25+
SetAssociation(Extension, ProgId, FileTypeDescription, filePath);
26+
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
27+
}
28+
catch (Exception ex)
29+
{
30+
MessageBox.Show($"Error setting file association: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
31+
}
32+
}
33+
34+
public static void RemoveAssociation()
35+
{
36+
try
37+
{
38+
RemoveAssociation(Extension, ProgId);
39+
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
40+
}
41+
catch (Exception ex)
42+
{
43+
MessageBox.Show($"Error remove file association: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
44+
}
45+
}
46+
47+
public static void SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath)
48+
{
49+
var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" + extension, true);
50+
key.DeleteSubKey("UserChoice", false);
51+
key.Close();
52+
53+
SetKeyDefaultValue(@"Software\Classes\" + extension, progId);
54+
SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription);
55+
SetKeyDefaultValue($@"Software\Classes\{progId}\shell\open\command", "\"" + applicationFilePath + "\" \"%1\"");
56+
}
57+
58+
public static void RemoveAssociation(string extension, string progId)
59+
{
60+
DeleteSubKeyTree(@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts", extension);
61+
SetKeyDefaultValue(@"Software\Classes\" + extension, string.Empty);
62+
DeleteSubKeyTree(@"Software\Classes", progId);
63+
}
64+
65+
private static bool SetKeyDefaultValue(string keyPath, string value)
66+
{
67+
using (var key = Registry.CurrentUser.CreateSubKey(keyPath))
68+
{
69+
if (key.GetValue(null) as string != value)
70+
{
71+
key.SetValue(null, value);
72+
return true;
73+
}
74+
}
75+
76+
return false;
77+
}
78+
79+
private static void DeleteSubKeyTree(string key, string subkey)
80+
{
81+
using (var keyroot = Registry.CurrentUser.OpenSubKey(key, RegistryKeyPermissionCheck.ReadWriteSubTree))
82+
{
83+
if (keyroot == null)
84+
return;
85+
86+
keyroot.GetAccessControl(System.Security.AccessControl.AccessControlSections.All);
87+
keyroot.DeleteSubKeyTree(subkey);
88+
}
89+
}
90+
}
91+
}

LogViewer/MainWindow.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
xmlns:local="clr-namespace:LogViewer"
77
xmlns:tb="http://www.hardcodet.net/taskbar"
88
mc:Ignorable="d"
9-
Title="{Binding WindowTitle}" Height="650" Width="1024" SizeToContent="Manual" WindowStartupLocation="CenterScreen" WindowState="Maximized">
9+
Title="{Binding WindowTitle}" Height="650" Width="1024" SizeToContent="Manual" WindowStartupLocation="CenterScreen" WindowState="Maximized" ContentRendered="Window_ContentRendered">
1010

1111
<Window.Resources>
1212
<Style x:Key="placeHolder" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">

LogViewer/MainWindow.xaml.cs

Lines changed: 55 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,12 @@ public MainWindow()
6868

6969
SettingsWindow.Load();
7070

71-
if (SettingsWindow.IsFirstRun() && !SettingsWindow.ShowSettingsDialog() == true)
71+
if (SettingsWindow.IsFirstRun())
7272
{
73-
Application.Current.Shutdown();
73+
if (SettingsWindow.ShowSettingsDialog() == true)
74+
ApplySettings();
75+
else
76+
Application.Current.Shutdown();
7477
}
7578

7679
notificationIcon = SaveNotifyLogoFromResource();
@@ -254,8 +257,8 @@ private void OpenLogFile(string fullPath)
254257
logWatcher.ReadToEndLine();
255258
LogsGrid.ItemsSource = logLines;
256259
Filter.Text = filterValue;
257-
gridScrollViewer = GetScrollViewer(LogsGrid);
258-
gridScrollViewer.ScrollToEnd();
260+
LogsGrid.ScrollIntoView(logLines.Last());
261+
259262
logWatcher.StartWatch(gridUpdatePeriod);
260263

261264
var tenants = logLines.Where(l => !string.IsNullOrEmpty(l.Tenant)).Select(l => l.Tenant).Distinct().OrderBy(l => l);
@@ -302,29 +305,9 @@ private void Files_SelectionChanged(object sender, SelectionChangedEventArgs e)
302305
dialog.Filters.Add(new CommonFileDialogFilter("Log Files (*.log)", ".log"));
303306

304307
if (CommonFileDialogResult.Ok == dialog.ShowDialog())
305-
{
306-
var logFiles = comboBox.Items.Cast<LogFile>().ToList();
307-
308-
var logFile = logFiles.FirstOrDefault(l => string.Equals(l.FullPath, dialog.FileName, StringComparison.InvariantCultureIgnoreCase));
309-
310-
if (logFile != null)
311-
{
312-
comboBox.SelectedItem = logFile;
313-
}
314-
else
315-
{
316-
// Создать фоновый обработчик для нового файла.
317-
LogHandlers.Add(new LogHandler(dialog.FileName, notificationIcon));
318-
319-
logFile = new LogFile(dialog.FileName);
320-
comboBox.Items.Insert(comboBox.Items.Count - 1, logFile);
321-
comboBox.SelectedItem = logFile;
322-
}
323-
}
308+
SelectFileToOpen(dialog.FileName);
324309
else
325-
{
326310
comboBox.SelectedItem = null;
327-
}
328311

329312
return;
330313
}
@@ -335,23 +318,6 @@ private void Files_SelectionChanged(object sender, SelectionChangedEventArgs e)
335318
OpenLogFile(openedFileFullPath);
336319
}
337320

338-
private ScrollViewer GetScrollViewer(UIElement element)
339-
{
340-
if (element == null)
341-
return null;
342-
343-
ScrollViewer result = null;
344-
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element) && result == null; i++)
345-
{
346-
if (VisualTreeHelper.GetChild(element, i) is ScrollViewer)
347-
result = (ScrollViewer)(VisualTreeHelper.GetChild(element, i));
348-
else
349-
result = GetScrollViewer(VisualTreeHelper.GetChild(element, i) as UIElement);
350-
}
351-
352-
return result;
353-
}
354-
355321
private void OnBlockNewLines(List<string> lines, bool isEndFile, double progress)
356322
{
357323
var convertedLogLines = Converter.ConvertLinesToObjects(lines);
@@ -413,19 +379,19 @@ private void LogsGrid_SelectionChanged(object sender, SelectionChangedEventArgs
413379
DetailText.Text = String.Empty;
414380

415381
if (!String.IsNullOrEmpty(line.UserName))
416-
DetailText.Text += $"UserName: {line.UserName} \n";
382+
DetailText.Text += $"UserName: {line.UserName}\n";
417383

418384
if (!String.IsNullOrEmpty(line.Tenant))
419-
DetailText.Text += $"Tenant: {line.Tenant} \n";
385+
DetailText.Text += $"Tenant: {line.Tenant}\n";
420386

421387
if (!String.IsNullOrEmpty(line.Pid))
422-
DetailText.Text += $"Pid: {line.Pid} \n";
388+
DetailText.Text += $"Pid: {line.Pid}\n";
423389

424390
if (!String.IsNullOrEmpty(line.Trace))
425-
DetailText.Text += $"Trace: {line.Trace} \n";
391+
DetailText.Text += $"Trace: {line.Trace}\n";
426392

427393
if (!String.IsNullOrEmpty(line.Version))
428-
DetailText.Text += $"Version: {line.Version} \n";
394+
DetailText.Text += $"Version: {line.Version}\n";
429395

430396
if (!String.IsNullOrEmpty(line.FullMessage))
431397
{
@@ -446,6 +412,7 @@ private void Settins_Click(object sender, RoutedEventArgs e)
446412
{
447413
if (SettingsWindow.ShowSettingsDialog() == true)
448414
{
415+
ApplySettings();
449416
// TODO сделать применение настроек без перезапуска приложения.
450417
MessageBox.Show("Settings will be applied after restarting the application");
451418
Application.Current.Shutdown();
@@ -618,5 +585,46 @@ private void ColumnVisibilityUnchecked(object sender, RoutedEventArgs e)
618585
columns.Visibility = Visibility.Collapsed;
619586
}
620587
}
588+
589+
private void ApplySettings()
590+
{
591+
if (SettingsWindow.AssociateLogFile == true)
592+
FileAssociations.SetAssociation();
593+
else
594+
FileAssociations.RemoveAssociation();
595+
}
596+
597+
private void SelectFileToOpen(string fileName)
598+
{
599+
var logFiles = LogsFileNames.Items.Cast<LogFile>().ToList();
600+
601+
var logFile = logFiles.FirstOrDefault(l => string.Equals(l.FullPath, fileName, StringComparison.InvariantCultureIgnoreCase));
602+
603+
if (logFile != null)
604+
{
605+
LogsFileNames.SelectedItem = logFile;
606+
}
607+
else
608+
{
609+
// Создать фоновый обработчик для нового файла.
610+
LogHandlers.Add(new LogHandler(fileName, notificationIcon));
611+
612+
logFile = new LogFile(fileName);
613+
LogsFileNames.Items.Insert(LogsFileNames.Items.Count - 1, logFile);
614+
LogsFileNames.SelectedItem = logFile;
615+
}
616+
}
617+
618+
private void Window_ContentRendered(object sender, EventArgs e)
619+
{
620+
var args = Environment.GetCommandLineArgs();
621+
if (args.Length > 1)
622+
{
623+
var fileName = args[1];
624+
625+
if (File.Exists(fileName) && Path.GetExtension(fileName) == ".log")
626+
SelectFileToOpen(fileName);
627+
}
628+
}
621629
}
622630
}

LogViewer/SettingsWindow.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
VerticalScrollBarVisibility="Visible"
3636
Text="{Binding Path=(local:SettingsWindow.WhitelistLogs), Mode=TwoWay}"/>
3737

38-
<CheckBox Grid.Row="4" Margin="0,5,0,0" x:Name="BackgroundConvertCheckBox" IsThreeState="False" Height="20" Content="Background conversion to file" IsChecked="{Binding Path=(local:SettingsWindow.BackgroundConvert), Mode=TwoWay}" />
38+
<CheckBox Grid.Row="4" Margin="0,5,0,0" x:Name="AssociateLogFileCheckBox" IsThreeState="False" Height="20" Content="associate *.log file with application" IsChecked="{Binding Path=(local:SettingsWindow.AssociateLogFile), Mode=TwoWay}" />
3939

4040
<WrapPanel Grid.Row="5" HorizontalAlignment="Right" Margin="0,0,0,0" VerticalAlignment="Bottom">
4141
<Button IsDefault="False" Click="Accept_Click" MinWidth="60" Margin="0,0,10,0">OK</Button>

LogViewer/SettingsWindow.xaml.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ public partial class SettingsWindow : Window
1313
{
1414
public static string LogsPath { get; set; }
1515
public static string WhitelistLogs { get; set; }
16-
public static bool BackgroundConvert { get; set; }
16+
public static bool AssociateLogFile { get; set; }
1717

1818
private static readonly string DefaultLogPath = @"D:\Projects\master\Logs";
1919
private static readonly string RegKey = @"SOFTWARE\JsonLogViewerSettings";
2020
private static readonly string LogsPathKey = "LogsPath";
2121
private static readonly string WhitelistKey = "WhiteList";
22-
private static readonly string BackgroundConvertKey = "BackgroundConvert";
22+
private static readonly string AssociateLogFileKey = "AssociateLogFile";
2323
private static readonly List<string> DefaultListLogs = new List<string>
2424
{
2525
"${machinename}.WebServer.${shortdate}",
@@ -56,7 +56,7 @@ public static bool IsFirstRun()
5656
using RegistryKey key = Registry.CurrentUser.CreateSubKey(RegKey);
5757
key.SetValue(LogsPathKey, dialog.LogsPathTextBox.Text);
5858
key.SetValue(WhitelistKey, dialog.WhiteListTextBox.Text);
59-
key.SetValue(BackgroundConvertKey, dialog.BackgroundConvertCheckBox.IsChecked);
59+
key.SetValue(AssociateLogFileKey, dialog.AssociateLogFileCheckBox.IsChecked);
6060
key.Close();
6161
}
6262

@@ -71,7 +71,7 @@ public static void Load()
7171

7272
WhitelistLogs = (string)key.GetValue(WhitelistKey, string.Join("\n", DefaultListLogs));
7373

74-
BackgroundConvert = Convert.ToBoolean(key.GetValue(BackgroundConvertKey, false));
74+
AssociateLogFile = Convert.ToBoolean(key.GetValue(AssociateLogFileKey, false));
7575

7676
key.Close();
7777
}

0 commit comments

Comments
 (0)