Skip to content

Commit a169cb0

Browse files
committed
#36: support .msg and .eml files
1 parent 5c08112 commit a169cb0

File tree

6 files changed

+273
-1
lines changed

6 files changed

+273
-1
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright © 2017 Paddy Xu
2+
//
3+
// This file is part of QuickLook program.
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
using System;
19+
using System.IO;
20+
using System.Windows;
21+
using System.Windows.Threading;
22+
using MsgReader;
23+
using QuickLook.Plugin.HtmlViewer;
24+
25+
namespace QuickLook.Plugin.MailViewer
26+
{
27+
public class Plugin : IViewer
28+
{
29+
private WebpagePanel _panel;
30+
private string tmpDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
31+
32+
public int Priority => int.MaxValue;
33+
public bool AllowsTransparency => false;
34+
35+
public void Init()
36+
{
37+
}
38+
39+
public bool CanHandle(string path)
40+
{
41+
if (Directory.Exists(path))
42+
return false;
43+
44+
switch (Path.GetExtension(path).ToLower())
45+
{
46+
case ".eml":
47+
case ".msg":
48+
return true;
49+
50+
default:
51+
return false;
52+
}
53+
}
54+
55+
public void Prepare(string path, ContextObject context)
56+
{
57+
context.PreferredSize = new Size {Width = 1000, Height = 600};
58+
}
59+
60+
public void View(string path, ContextObject context)
61+
{
62+
_panel = new WebpagePanel();
63+
context.ViewerContent = _panel;
64+
context.Title = Path.GetFileName(path);
65+
66+
_panel.Navigate(ExtractMailBody(path));
67+
_panel.Dispatcher.Invoke(() => { context.IsBusy = false; }, DispatcherPriority.Loaded);
68+
}
69+
70+
public void Cleanup()
71+
{
72+
GC.SuppressFinalize(this);
73+
74+
_panel?.Dispose();
75+
_panel = null;
76+
77+
if (Directory.Exists(tmpDir))
78+
Directory.Delete(tmpDir, true);
79+
}
80+
81+
private string ExtractMailBody(string path)
82+
{
83+
tmpDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
84+
Directory.CreateDirectory(tmpDir);
85+
86+
var msg = new Reader();
87+
88+
var files = msg.ExtractToFolder(path, tmpDir, true);
89+
90+
if (files.Length > 0 && !string.IsNullOrEmpty(files[0]))
91+
return files[0];
92+
93+
throw new Exception($"{path} is not a valid msg file.");
94+
}
95+
96+
~Plugin()
97+
{
98+
Cleanup();
99+
}
100+
}
101+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright © 2017 Paddy Xu
2+
//
3+
// This file is part of QuickLook program.
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
using System.Reflection;
19+
using System.Runtime.InteropServices;
20+
using System.Windows;
21+
22+
// General Information about an assembly is controlled through the following
23+
// set of attributes. Change these attribute values to modify the information
24+
// associated with an assembly.
25+
[assembly: AssemblyTitle("QuickLook.Plugin.MailViewer")]
26+
[assembly: AssemblyDescription("")]
27+
[assembly: AssemblyConfiguration("")]
28+
[assembly: AssemblyCompany("")]
29+
[assembly: AssemblyProduct("QuickLook.Plugin.MailViewer")]
30+
[assembly: AssemblyCopyright("Copyright © 2017")]
31+
[assembly: AssemblyTrademark("")]
32+
[assembly: AssemblyCulture("")]
33+
34+
// Setting ComVisible to false makes the types in this assembly not visible
35+
// to COM components. If you need to access a type in this assembly from
36+
// COM, set the ComVisible attribute to true on that type.
37+
[assembly: ComVisible(false)]
38+
39+
//In order to begin building localizable applications, set
40+
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
41+
//inside a <PropertyGroup>. For example, if you are using US english
42+
//in your source files, set the <UICulture> to en-US. Then uncomment
43+
//the NeutralResourceLanguage attribute below. Update the "en-US" in
44+
//the line below to match the UICulture setting in the project file.
45+
46+
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
47+
48+
49+
[assembly: ThemeInfo(
50+
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
51+
//(used if a resource is not found in the page,
52+
// or application resource dictionaries)
53+
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
54+
//(used if a resource is not found in the page,
55+
// app, or any theme specific resource dictionaries)
56+
)]
57+
58+
59+
// Version information for an assembly consists of the following four values:
60+
//
61+
// Major Version
62+
// Minor Version
63+
// Build Number
64+
// Revision
65+
//
66+
// You can specify all the values or you can default the Build and Revision Numbers
67+
// by using the '*' as shown below:
68+
// [assembly: AssemblyVersion("1.0.*")]
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{45E94893-3076-4A8E-8969-6955B6340739}</ProjectGuid>
8+
<OutputType>library</OutputType>
9+
<RootNamespace>QuickLook.Plugin.MailViewer</RootNamespace>
10+
<AssemblyName>QuickLook.Plugin.MailViewer</AssemblyName>
11+
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
12+
<FileAlignment>512</FileAlignment>
13+
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
14+
<WarningLevel>4</WarningLevel>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.MailViewer\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<DebugType>pdbonly</DebugType>
27+
<Optimize>true</Optimize>
28+
<OutputPath>..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.MailViewer\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
<ErrorReport>prompt</ErrorReport>
31+
<WarningLevel>4</WarningLevel>
32+
</PropertyGroup>
33+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
34+
<DebugSymbols>true</DebugSymbols>
35+
<OutputPath>..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.MailViewer\</OutputPath>
36+
<DefineConstants>DEBUG;TRACE</DefineConstants>
37+
<DebugType>full</DebugType>
38+
<PlatformTarget>x86</PlatformTarget>
39+
<ErrorReport>prompt</ErrorReport>
40+
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
41+
</PropertyGroup>
42+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
43+
<OutputPath>..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.MailViewer\</OutputPath>
44+
<DefineConstants>TRACE</DefineConstants>
45+
<Optimize>true</Optimize>
46+
<DebugType>pdbonly</DebugType>
47+
<PlatformTarget>x86</PlatformTarget>
48+
<ErrorReport>prompt</ErrorReport>
49+
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
50+
</PropertyGroup>
51+
<ItemGroup>
52+
<Reference Include="MsgReader, Version=2.0.11.0, Culture=neutral, PublicKeyToken=47f99f3a9a2648df, processorArchitecture=MSIL">
53+
<HintPath>..\..\packages\MSGReader.2.0.11\lib\MsgReader.dll</HintPath>
54+
</Reference>
55+
<Reference Include="System" />
56+
<Reference Include="System.Core" />
57+
<Reference Include="System.Xaml">
58+
<RequiredTargetFramework>4.0</RequiredTargetFramework>
59+
</Reference>
60+
<Reference Include="WindowsBase" />
61+
<Reference Include="PresentationCore" />
62+
<Reference Include="PresentationFramework" />
63+
</ItemGroup>
64+
<ItemGroup>
65+
<Compile Include="..\..\GitVersion.cs">
66+
<Link>Properties\GitVersion.cs</Link>
67+
</Compile>
68+
<Compile Include="Plugin.cs" />
69+
<Compile Include="Properties\AssemblyInfo.cs" />
70+
</ItemGroup>
71+
<ItemGroup>
72+
<ProjectReference Include="..\..\QuickLook\QuickLook.csproj">
73+
<Project>{8b4a9ce5-67b5-4a94-81cb-3771f688fdeb}</Project>
74+
<Name>QuickLook</Name>
75+
<Private>False</Private>
76+
</ProjectReference>
77+
<ProjectReference Include="..\QuickLook.Plugin.HtmlViewer\QuickLook.Plugin.HtmlViewer.csproj">
78+
<Project>{ce22a1f3-7f2c-4ec8-bfde-b58d0eb625fc}</Project>
79+
<Name>QuickLook.Plugin.HtmlViewer</Name>
80+
<Private>False</Private>
81+
</ProjectReference>
82+
</ItemGroup>
83+
<ItemGroup>
84+
<None Include="packages.config" />
85+
</ItemGroup>
86+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
87+
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<packages>
4+
<package id="MSGReader" version="2.0.11" targetFramework="net462" />
5+
</packages>

QuickLook.sln

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuickLook.WoW64HookHelper",
6464
EndProject
6565
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.CsvViewer", "QuickLook.Plugin\QuickLook.Plugin.CsvViewer\QuickLook.Plugin.CsvViewer.csproj", "{863ECAAC-18D9-4256-A27D-0F308089FB47}"
6666
EndProject
67+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.MailViewer", "QuickLook.Plugin\QuickLook.Plugin.MailViewer\QuickLook.Plugin.MailViewer.csproj", "{45E94893-3076-4A8E-8969-6955B6340739}"
68+
EndProject
6769
Global
6870
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6971
Debug|Any CPU = Debug|Any CPU
@@ -178,6 +180,14 @@ Global
178180
{863ECAAC-18D9-4256-A27D-0F308089FB47}.Release|Any CPU.Build.0 = Release|Any CPU
179181
{863ECAAC-18D9-4256-A27D-0F308089FB47}.Release|x86.ActiveCfg = Release|x86
180182
{863ECAAC-18D9-4256-A27D-0F308089FB47}.Release|x86.Build.0 = Release|x86
183+
{45E94893-3076-4A8E-8969-6955B6340739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
184+
{45E94893-3076-4A8E-8969-6955B6340739}.Debug|Any CPU.Build.0 = Debug|Any CPU
185+
{45E94893-3076-4A8E-8969-6955B6340739}.Debug|x86.ActiveCfg = Debug|x86
186+
{45E94893-3076-4A8E-8969-6955B6340739}.Debug|x86.Build.0 = Debug|x86
187+
{45E94893-3076-4A8E-8969-6955B6340739}.Release|Any CPU.ActiveCfg = Release|Any CPU
188+
{45E94893-3076-4A8E-8969-6955B6340739}.Release|Any CPU.Build.0 = Release|Any CPU
189+
{45E94893-3076-4A8E-8969-6955B6340739}.Release|x86.ActiveCfg = Release|x86
190+
{45E94893-3076-4A8E-8969-6955B6340739}.Release|x86.Build.0 = Release|x86
181191
EndGlobalSection
182192
GlobalSection(SolutionProperties) = preSolution
183193
HideSolutionNode = FALSE
@@ -195,5 +205,6 @@ Global
195205
{794E4DCF-F715-4836-9D30-ABD296586D23} = {D18A23FF-76BD-43BD-AC32-786D166EBAC9}
196206
{2C58F9B2-D8FA-4586-942B-5170CECE5963} = {D18A23FF-76BD-43BD-AC32-786D166EBAC9}
197207
{863ECAAC-18D9-4256-A27D-0F308089FB47} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93}
208+
{45E94893-3076-4A8E-8969-6955B6340739} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93}
198209
EndGlobalSection
199210
EndGlobal

QuickLook/ViewWindowManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ private void CurrentPluginFailed(ExceptionDispatchInfo e)
222222

223223
TrayIconManager.GetInstance().ShowNotification("", $"Failed to preview {Path.GetFileName(_path)}", true);
224224

225-
Debug.WriteLine(e.ToString());
225+
Debug.WriteLine(e.SourceException.ToString());
226226
Debug.WriteLine(e.SourceException.StackTrace);
227227

228228
if (plugin != PluginManager.GetInstance().DefaultPlugin.GetType())

0 commit comments

Comments
 (0)