Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25110f29bc | ||
|
|
66ffeb4fb8 | ||
|
|
6266bc65e7 | ||
|
|
6e14b08e6f | ||
|
|
948e857158 | ||
|
|
5130a58196 | ||
|
|
ac7e305de5 | ||
|
|
4d55aaff37 | ||
|
|
a974e41ce3 | ||
|
|
79d01d70cd | ||
|
|
eccc0edcc9 | ||
|
|
45d41e11f4 | ||
|
|
767c2ddad2 | ||
|
|
348eb169c2 | ||
|
|
b2e5184e0a | ||
|
|
3dae15e1e0 | ||
|
|
6aa633b501 | ||
|
|
89c6883d00 | ||
|
|
f5367c826d | ||
|
|
d42bf9a332 | ||
|
|
d8ca0f01ca | ||
|
|
edddd01a21 | ||
|
|
45d4dad22a | ||
|
|
a5ef763617 | ||
|
|
49ea2ba2a6 | ||
|
|
03b620ecec | ||
|
|
ab758cd85f | ||
|
|
ed3a2bb5b9 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -7,3 +7,12 @@
|
|||||||
/.vs
|
/.vs
|
||||||
/TwitchDesktopNotifications/App.config
|
/TwitchDesktopNotifications/App.config
|
||||||
/TwitchDesktopNotifications/TwitchDetails.cs
|
/TwitchDesktopNotifications/TwitchDetails.cs
|
||||||
|
/Twitchy-SetupFiles/TwitchySetup.msi
|
||||||
|
/Twitchy-SetupFiles/TwitchySetup.exe
|
||||||
|
/Twitchy-cache/part1/Twitchy1.cab
|
||||||
|
/Twitchy-cache/part1/output-info.ini
|
||||||
|
/Twitchy-cache/part1
|
||||||
|
/Twitchy-cache/cacheIndex.txt
|
||||||
|
/Twitchy-cache
|
||||||
|
/TwitchDesktopNotifications/Twitchy.zip
|
||||||
|
/SetupFiles
|
||||||
|
|||||||
789
CodeDependencies.iss
Normal file
789
CodeDependencies.iss
Normal file
@@ -0,0 +1,789 @@
|
|||||||
|
; -- CodeDependencies.iss --
|
||||||
|
;
|
||||||
|
; This script shows how to download and install any dependency such as .NET,
|
||||||
|
; Visual C++ or SQL Server during your application's installation process.
|
||||||
|
;
|
||||||
|
; contribute: https://github.com/DomGries/InnoDependencyInstaller
|
||||||
|
|
||||||
|
|
||||||
|
; -----------
|
||||||
|
; SHARED CODE
|
||||||
|
; -----------
|
||||||
|
[Code]
|
||||||
|
// types and variables
|
||||||
|
type
|
||||||
|
TDependency_Entry = record
|
||||||
|
Filename: String;
|
||||||
|
Parameters: String;
|
||||||
|
Title: String;
|
||||||
|
URL: String;
|
||||||
|
Checksum: String;
|
||||||
|
ForceSuccess: Boolean;
|
||||||
|
RestartAfter: Boolean;
|
||||||
|
end;
|
||||||
|
var
|
||||||
|
Dependency_Memo: String;
|
||||||
|
Dependency_List: array of TDependency_Entry;
|
||||||
|
Dependency_NeedRestart, Dependency_ForceX86: Boolean;
|
||||||
|
Dependency_DownloadPage: TDownloadWizardPage;
|
||||||
|
procedure Dependency_Add(const Filename, Parameters, Title, URL, Checksum: String; const ForceSuccess, RestartAfter: Boolean);
|
||||||
|
var
|
||||||
|
Dependency: TDependency_Entry;
|
||||||
|
DependencyCount: Integer;
|
||||||
|
begin
|
||||||
|
Dependency_Memo := Dependency_Memo + #13#10 + '%1' + Title;
|
||||||
|
Dependency.Filename := Filename;
|
||||||
|
Dependency.Parameters := Parameters;
|
||||||
|
Dependency.Title := Title;
|
||||||
|
if FileExists(ExpandConstant('{tmp}{\}') + Filename) then begin
|
||||||
|
Dependency.URL := '';
|
||||||
|
end else begin
|
||||||
|
Dependency.URL := URL;
|
||||||
|
end;
|
||||||
|
Dependency.Checksum := Checksum;
|
||||||
|
Dependency.ForceSuccess := ForceSuccess;
|
||||||
|
Dependency.RestartAfter := RestartAfter;
|
||||||
|
DependencyCount := GetArrayLength(Dependency_List);
|
||||||
|
SetArrayLength(Dependency_List, DependencyCount + 1);
|
||||||
|
Dependency_List[DependencyCount] := Dependency;
|
||||||
|
end;
|
||||||
|
<event('InitializeWizard')>
|
||||||
|
procedure Dependency_Internal1;
|
||||||
|
begin
|
||||||
|
Dependency_DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil);
|
||||||
|
end;
|
||||||
|
<event('PrepareToInstall')>
|
||||||
|
function Dependency_Internal2(var NeedsRestart: Boolean): String;
|
||||||
|
var
|
||||||
|
DependencyCount, DependencyIndex, ResultCode: Integer;
|
||||||
|
Retry: Boolean;
|
||||||
|
TempValue: String;
|
||||||
|
begin
|
||||||
|
DependencyCount := GetArrayLength(Dependency_List);
|
||||||
|
if DependencyCount > 0 then begin
|
||||||
|
Dependency_DownloadPage.Show;
|
||||||
|
for DependencyIndex := 0 to DependencyCount - 1 do begin
|
||||||
|
if Dependency_List[DependencyIndex].URL <> '' then begin
|
||||||
|
Dependency_DownloadPage.Clear;
|
||||||
|
Dependency_DownloadPage.Add(Dependency_List[DependencyIndex].URL, Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Checksum);
|
||||||
|
Retry := True;
|
||||||
|
while Retry do begin
|
||||||
|
Retry := False;
|
||||||
|
try
|
||||||
|
Dependency_DownloadPage.Download;
|
||||||
|
except
|
||||||
|
if Dependency_DownloadPage.AbortedByUser then begin
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
DependencyIndex := DependencyCount;
|
||||||
|
end else begin
|
||||||
|
case SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
|
||||||
|
IDABORT: begin
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
DependencyIndex := DependencyCount;
|
||||||
|
end;
|
||||||
|
IDRETRY: begin
|
||||||
|
Retry := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Result = '' then begin
|
||||||
|
for DependencyIndex := 0 to DependencyCount - 1 do begin
|
||||||
|
Dependency_DownloadPage.SetText(Dependency_List[DependencyIndex].Title, '');
|
||||||
|
Dependency_DownloadPage.SetProgress(DependencyIndex + 1, DependencyCount + 1);
|
||||||
|
while True do begin
|
||||||
|
ResultCode := 0;
|
||||||
|
if ShellExec('', ExpandConstant('{tmp}{\}') + Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then begin
|
||||||
|
if Dependency_List[DependencyIndex].RestartAfter then begin
|
||||||
|
if DependencyIndex = DependencyCount - 1 then begin
|
||||||
|
Dependency_NeedRestart := True;
|
||||||
|
end else begin
|
||||||
|
NeedsRestart := True;
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end else if (ResultCode = 0) or Dependency_List[DependencyIndex].ForceSuccess then begin // ERROR_SUCCESS (0)
|
||||||
|
break;
|
||||||
|
end else if ResultCode = 1641 then begin // ERROR_SUCCESS_REBOOT_INITIATED (1641)
|
||||||
|
NeedsRestart := True;
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
break;
|
||||||
|
end else if ResultCode = 3010 then begin // ERROR_SUCCESS_REBOOT_REQUIRED (3010)
|
||||||
|
Dependency_NeedRestart := True;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
case SuppressibleMsgBox(FmtMessage(SetupMessage(msgErrorFunctionFailed), [Dependency_List[DependencyIndex].Title, IntToStr(ResultCode)]), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
|
||||||
|
IDABORT: begin
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
IDIGNORE: begin
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Result <> '' then begin
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if NeedsRestart then begin
|
||||||
|
TempValue := '"' + ExpandConstant('{srcexe}') + '" /restart=1 /LANG="' + ExpandConstant('{language}') + '" /DIR="' + WizardDirValue + '" /GROUP="' + WizardGroupValue + '" /TYPE="' + WizardSetupType(False) + '" /COMPONENTS="' + WizardSelectedComponents(False) + '" /TASKS="' + WizardSelectedTasks(False) + '"';
|
||||||
|
if WizardNoIcons then begin
|
||||||
|
TempValue := TempValue + ' /NOICONS';
|
||||||
|
end;
|
||||||
|
RegWriteStringValue(HKA, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', '{#SetupSetting("AppName")}', TempValue);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Dependency_DownloadPage.Hide;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
<event('UpdateReadyMemo')>
|
||||||
|
function Dependency_Internal3(const Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
if MemoUserInfoInfo <> '' then begin
|
||||||
|
Result := Result + MemoUserInfoInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoDirInfo <> '' then begin
|
||||||
|
Result := Result + MemoDirInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoTypeInfo <> '' then begin
|
||||||
|
Result := Result + MemoTypeInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoComponentsInfo <> '' then begin
|
||||||
|
Result := Result + MemoComponentsInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoGroupInfo <> '' then begin
|
||||||
|
Result := Result + MemoGroupInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoTasksInfo <> '' then begin
|
||||||
|
Result := Result + MemoTasksInfo;
|
||||||
|
end;
|
||||||
|
if Dependency_Memo <> '' then begin
|
||||||
|
if MemoTasksInfo = '' then begin
|
||||||
|
Result := Result + SetupMessage(msgReadyMemoTasks);
|
||||||
|
end;
|
||||||
|
Result := Result + FmtMessage(Dependency_Memo, [Space]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
<event('NeedRestart')>
|
||||||
|
function Dependency_Internal4: Boolean;
|
||||||
|
begin
|
||||||
|
Result := Dependency_NeedRestart;
|
||||||
|
end;
|
||||||
|
function Dependency_IsX64: Boolean;
|
||||||
|
begin
|
||||||
|
Result := not Dependency_ForceX86 and Is64BitInstallMode;
|
||||||
|
end;
|
||||||
|
function Dependency_String(const x86, x64: String): String;
|
||||||
|
begin
|
||||||
|
if Dependency_IsX64 then begin
|
||||||
|
Result := x64;
|
||||||
|
end else begin
|
||||||
|
Result := x86;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
function Dependency_ArchSuffix: String;
|
||||||
|
begin
|
||||||
|
Result := Dependency_String('', '_x64');
|
||||||
|
end;
|
||||||
|
function Dependency_ArchTitle: String;
|
||||||
|
begin
|
||||||
|
Result := Dependency_String(' (x86)', ' (x64)');
|
||||||
|
end;
|
||||||
|
function Dependency_IsNetCoreInstalled(const Version: String): Boolean;
|
||||||
|
var
|
||||||
|
ResultCode: Integer;
|
||||||
|
begin
|
||||||
|
// source code: https://github.com/dotnet/deployment-tools/tree/master/src/clickonce/native/projects/NetCoreCheck
|
||||||
|
if not FileExists(ExpandConstant('{tmp}{\}') + 'netcorecheck' + Dependency_ArchSuffix + '.exe') then begin
|
||||||
|
ExtractTemporaryFile('netcorecheck' + Dependency_ArchSuffix + '.exe');
|
||||||
|
end;
|
||||||
|
StringChangeEx(Version, ' ', ' -v ', True)
|
||||||
|
Result := ShellExec('', ExpandConstant('{tmp}{\}') + 'netcorecheck' + Dependency_ArchSuffix + '.exe', ' -n ' + Version, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0);
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet35;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-framework/net35-sp1
|
||||||
|
if not IsDotNetInstalled(net35, 1) then begin
|
||||||
|
Dependency_Add('dotnetfx35.exe',
|
||||||
|
'/lang:enu /passive /norestart',
|
||||||
|
'.NET Framework 3.5 Service Pack 1',
|
||||||
|
'https://download.microsoft.com/download/2/0/E/20E90413-712F-438C-988E-FDAA79A8AC3D/dotnetfx35.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet40;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-framework/net40
|
||||||
|
if not IsDotNetInstalled(net4full, 0) then begin
|
||||||
|
Dependency_Add('dotNetFx40_Full_setup.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.0',
|
||||||
|
'https://download.microsoft.com/download/1/B/E/1BE39E79-7E39-46A3-96FF-047F95396215/dotNetFx40_Full_setup.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet45;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-framework/net452
|
||||||
|
if not IsDotNetInstalled(net452, 0) then begin
|
||||||
|
Dependency_Add('dotnetfx45.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.5.2',
|
||||||
|
'https://go.microsoft.com/fwlink/?LinkId=397707',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet46;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-framework/net462
|
||||||
|
if not IsDotNetInstalled(net462, 0) then begin
|
||||||
|
Dependency_Add('dotnetfx46.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.6.2',
|
||||||
|
'https://go.microsoft.com/fwlink/?linkid=780596',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet47;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-framework/net472
|
||||||
|
if not IsDotNetInstalled(net472, 0) then begin
|
||||||
|
Dependency_Add('dotnetfx47.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.7.2',
|
||||||
|
'https://go.microsoft.com/fwlink/?LinkId=863262',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet48;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-framework/net48
|
||||||
|
if not IsDotNetInstalled(net48, 0) then begin
|
||||||
|
Dependency_Add('dotnetfx48.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.8',
|
||||||
|
'https://go.microsoft.com/fwlink/?LinkId=2085155',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddNetCore31;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-core/3.1
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App 3.1.22') then begin
|
||||||
|
Dependency_Add('netcore31' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Core Runtime 3.1.22' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/c2437aed-8cc4-41d0-a239-d6c7cf7bddae/062c37e8b06df740301c0bca1b0b7b9a/dotnet-runtime-3.1.22-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/4e95705e-1bb6-4764-b899-1b97eb70ea1d/dd311e073bd3e25b2efe2dcf02727e81/dotnet-runtime-3.1.22-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddNetCore31Asp;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-core/3.1
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App 3.1.22') then begin
|
||||||
|
Dependency_Add('netcore31asp' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'ASP.NET Core Runtime 3.1.22' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/0a1a2ee5-b8ed-4f0d-a4af-a7bce9a9ac2b/d452039b49d79e8897f272c3ab34b875/aspnetcore-runtime-3.1.22-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/80e52143-31e8-450e-aa94-b3f8484aaba9/4b69e5c77d50e7b367960a0079c90a99/aspnetcore-runtime-3.1.22-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddNetCore31Desktop;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet-core/3.1
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 3.1.22') then begin
|
||||||
|
Dependency_Add('netcore31desktop' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Desktop Runtime 3.1.22' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/e4fcd574-4487-4b4b-8ca8-c23177c6f59f/c6d67a04956169dc21895cdcb42bf344/windowsdesktop-runtime-3.1.22-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/1c14e24b-7f31-42dc-ba3c-83295a2d6f7e/41b93591162dfe556cc160ae44fbe75e/windowsdesktop-runtime-3.1.22-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet50;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/5.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App 5.0.13') then begin
|
||||||
|
Dependency_Add('dotnet50' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Runtime 5.0.13' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/4a79fcd5-d61b-4606-8496-68071c8099c6/2bf770ca40521e8c4563072592eadd06/dotnet-runtime-5.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/fccf43d2-3e62-4ede-b5a5-592a7ccded7b/6339f1fdfe3317df5b09adf65f0261ab/dotnet-runtime-5.0.13-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet50Asp;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/5.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App 5.0.13') then begin
|
||||||
|
Dependency_Add('dotnet50asp' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'ASP.NET Core Runtime 5.0.13' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/340f9482-fc43-4ef7-b434-e2ed57f55cb3/c641b805cef3823769409a6dbac5746b/aspnetcore-runtime-5.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/aac560f3-eac8-437e-aebd-9830119deb10/6a3880161cf527e4ec71f67efe4d91ad/aspnetcore-runtime-5.0.13-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet50Desktop;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/5.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 5.0.13') then begin
|
||||||
|
Dependency_Add('dotnet50desktop' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Desktop Runtime 5.0.13' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/c8125c6b-d399-4be3-b201-8f1394fc3b25/724758f754fc7b67daba74db8d6d91d9/windowsdesktop-runtime-5.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/2bfb80f2-b8f2-44b0-90c1-d3c8c1c8eac8/409dd3d3367feeeda048f4ff34b32e82/windowsdesktop-runtime-5.0.13-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet60;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/6.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App 6.0.11') then begin
|
||||||
|
Dependency_Add('dotnet60' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Runtime 6.0.11' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/719bfd7c-bce2-4e73-937c-cbd7a7ace3cb/d4f570d461711d22e277f1e3487ea9c2/dotnet-runtime-6.0.11-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/8cf88855-ed09-4002-95db-8bb0f0eff051/f9006645511830bd3b840be132423768/dotnet-runtime-6.0.11-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet60Asp;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/6.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App 6.0.11') then begin
|
||||||
|
Dependency_Add('dotnet60asp' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'ASP.NET Core Runtime 6.0.11' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/94504599-143a-4d53-b518-74aee0ebecca/dac4a7b1f7bdc7b4e8441d6befa4941a/aspnetcore-runtime-6.0.11-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/e874914f-d43d-4b61-8479-f6a5536e44b1/7043adfe896aa9f980ce23e884aae37d/aspnetcore-runtime-6.0.11-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet60Desktop;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/6.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 6.0.11') then begin
|
||||||
|
Dependency_Add('dotnet60desktop' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Desktop Runtime 6.0.11' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/2a392287-fd51-4ee8-9c15-a672ab9bc55d/03d4784b3a543a0fb9ce5677ed13a9a3/windowsdesktop-runtime-6.0.11-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/0192a249-3ec8-4374-a827-e186dd58d55d/cec046575f3eb2247a10ba3d50f5cf6c/windowsdesktop-runtime-6.0.11-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet70;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/7.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App 7.0.3') then begin
|
||||||
|
Dependency_Add('dotnet70' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Runtime 7.0.3' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/9dd2da29-ca47-40fb-81a0-96fe26ea8ea2/e8f7e09a6d4848b8c4a13282d964b9e1/dotnet-runtime-7.0.3-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/c69813b7-2ece-4c2e-8c45-e33006985e18/61cc8fe4693a662b2da55ad932a46446/dotnet-runtime-7.0.3-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet70Asp;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/7.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App 7.0.3') then begin
|
||||||
|
Dependency_Add('dotnet70asp' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'ASP.NET Core Runtime 7.0.3' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/4bf0f350-f947-408b-9ee4-539313b85634/b17087052d6192b5d59735ae6f208c19/aspnetcore-runtime-7.0.3-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/d37efccc-2ba1-4fc9-a1ef-a8e1e77fb681/b9a20fc29ff05f18d81620ec88ade699/aspnetcore-runtime-7.0.3-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet70Desktop;
|
||||||
|
begin
|
||||||
|
// https://dotnet.microsoft.com/download/dotnet/7.0
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 7.0.3') then begin
|
||||||
|
Dependency_Add('dotnet70desktop' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Desktop Runtime 7.0.3' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/fb8bf100-9e1c-472c-8bc8-aa16fff44f53/8d36f5a56edff8620f9c63c1e73ba88c/windowsdesktop-runtime-7.0.3-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/3ebf014d-fcb9-4200-b3fe-76ba2000b027/840f2f95833ce400a9949e35f1581d28/windowsdesktop-runtime-7.0.3-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2005;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=26347
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{86C9D5AA-F00C-4921-B3F2-C60AF92E2844}', '{A8D19029-8E5C-4E22-8011-48070F9E796E}'), PackVersionComponents(8, 0, 61000, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2005' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/q',
|
||||||
|
'Visual C++ 2005 Service Pack 1 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.EXE', 'https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.EXE'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2008;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=26368
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{DE2C306F-A067-38EF-B86C-03DE4B0312F9}', '{FDA45DDF-8E17-336F-A3ED-356B7B7C688A}'), PackVersionComponents(9, 0, 30729, 6161)) then begin
|
||||||
|
Dependency_Add('vcredist2008' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/q',
|
||||||
|
'Visual C++ 2008 Service Pack 1 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe', 'https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2010;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=26999
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{1F4F1D2A-D9DA-32CF-9909-48485DA06DD5}', '{5B75F761-BAC8-33BC-A381-464DDDD813A3}'), PackVersionComponents(10, 0, 40219, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2010' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/passive /norestart',
|
||||||
|
'Visual C++ 2010 Service Pack 1 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe', 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2012;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=30679
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{4121ED58-4BD9-3E7B-A8B5-9F8BAAE045B7}', '{EFA6AFA1-738E-3E00-8101-FD03B86B29D1}'), PackVersionComponents(11, 0, 61030, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2012' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/passive /norestart',
|
||||||
|
'Visual C++ 2012 Update 4 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe', 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2013;
|
||||||
|
begin
|
||||||
|
// https://support.microsoft.com/en-us/help/4032938
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{B59F5BF1-67C8-3802-8E59-2CE551A39FC5}', '{20400CF0-DE7C-327E-9AE4-F0F38D9085F8}'), PackVersionComponents(12, 0, 40664, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2013' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/passive /norestart',
|
||||||
|
'Visual C++ 2013 Update 5 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/10912113/5da66ddebb0ad32ebd4b922fd82e8e25/vcredist_x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/10912041/cee5d6bca2ddbcd039da727bf4acb48a/vcredist_x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2015To2022;
|
||||||
|
begin
|
||||||
|
// https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{65E5BD06-6392-3027-8C26-853107D3CF1A}', '{36F68A90-239C-34DF-B58C-64B30153CE35}'), PackVersionComponents(14, 30, 30704, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2022' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/passive /norestart',
|
||||||
|
'Visual C++ 2015-2022 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://aka.ms/vs/17/release/vc_redist.x86.exe', 'https://aka.ms/vs/17/release/vc_redist.x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDirectX;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=35
|
||||||
|
Dependency_Add('dxwebsetup.exe',
|
||||||
|
'/q',
|
||||||
|
'DirectX Runtime',
|
||||||
|
'https://download.microsoft.com/download/1/7/1/1718CCC4-6315-4D8E-9543-8E28A4E18C4C/dxwebsetup.exe',
|
||||||
|
'', True, False);
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2008Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=30438
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(10, 50, 4000, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2008express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2008 R2 Service Pack 2 Express',
|
||||||
|
Dependency_String('https://download.microsoft.com/download/0/4/B/04BE03CD-EAF3-4797-9D8D-2E08E316C998/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/0/4/B/04BE03CD-EAF3-4797-9D8D-2E08E316C998/SQLEXPR_x64_ENU.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2012Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=56042
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(11, 0, 7001, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2012express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2012 Service Pack 4 Express',
|
||||||
|
Dependency_String('https://download.microsoft.com/download/B/D/E/BDE8FAD6-33E5-44F6-B714-348F73E602B6/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/B/D/E/BDE8FAD6-33E5-44F6-B714-348F73E602B6/SQLEXPR_x64_ENU.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2014Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=57473
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(12, 0, 6024, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2014express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2014 Service Pack 3 Express',
|
||||||
|
Dependency_String('https://download.microsoft.com/download/3/9/F/39F968FA-DEBB-4960-8F9E-0E7BB3035959/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/3/9/F/39F968FA-DEBB-4960-8F9E-0E7BB3035959/SQLEXPR_x64_ENU.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2016Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=56840
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(13, 0, 5026, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2016express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2016 Service Pack 2 Express',
|
||||||
|
'https://download.microsoft.com/download/3/7/6/3767D272-76A1-4F31-8849-260BD37924E4/SQLServer2016-SSEI-Expr.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2017Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=55994
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(14, 0, 0, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2017express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2017 Express',
|
||||||
|
'https://download.microsoft.com/download/5/E/9/5E9B18CC-8FD5-467E-B5BF-BADE39C51F73/SQLServer2017-SSEI-Expr.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2019Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
// https://www.microsoft.com/en-us/download/details.aspx?id=101064
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(15, 0, 0, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2019express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2019 Express',
|
||||||
|
'https://download.microsoft.com/download/7/f/8/7f8a9c43-8c8a-4f7c-9f92-83c18d96b681/SQL2019-SSEI-Expr.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddWebView2;
|
||||||
|
begin
|
||||||
|
if not RegValueExists(HKLM, Dependency_String('SOFTWARE', 'SOFTWARE\WOW6432Node') + '\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv') then begin
|
||||||
|
Dependency_Add('MicrosoftEdgeWebview2Setup.exe',
|
||||||
|
'/silent /install',
|
||||||
|
'WebView2 Runtime',
|
||||||
|
'https://go.microsoft.com/fwlink/p/?LinkId=2124703',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
[Setup]
|
||||||
|
; -------------
|
||||||
|
; EXAMPLE SETUP
|
||||||
|
; -------------
|
||||||
|
#ifndef Dependency_NoExampleSetup
|
||||||
|
|
||||||
|
; comment out dependency defines to disable installing them
|
||||||
|
#define UseDotNet35
|
||||||
|
#define UseDotNet40
|
||||||
|
#define UseDotNet45
|
||||||
|
#define UseDotNet46
|
||||||
|
#define UseDotNet47
|
||||||
|
#define UseDotNet48
|
||||||
|
|
||||||
|
; requires netcorecheck.exe and netcorecheck_x64.exe (see download link below)
|
||||||
|
#define UseNetCoreCheck
|
||||||
|
#ifdef UseNetCoreCheck
|
||||||
|
#define UseNetCore31
|
||||||
|
#define UseNetCore31Asp
|
||||||
|
#define UseNetCore31Desktop
|
||||||
|
#define UseDotNet50
|
||||||
|
#define UseDotNet50Asp
|
||||||
|
#define UseDotNet50Desktop
|
||||||
|
#define UseDotNet60
|
||||||
|
#define UseDotNet60Asp
|
||||||
|
#define UseDotNet60Desktop
|
||||||
|
#define UseDotNet70
|
||||||
|
#define UseDotNet70Asp
|
||||||
|
#define UseDotNet70Desktop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UseVC2005
|
||||||
|
#define UseVC2008
|
||||||
|
#define UseVC2010
|
||||||
|
#define UseVC2012
|
||||||
|
#define UseVC2013
|
||||||
|
#define UseVC2015To2022
|
||||||
|
|
||||||
|
; requires dxwebsetup.exe (see download link below)
|
||||||
|
;#define UseDirectX
|
||||||
|
|
||||||
|
#define UseSql2008Express
|
||||||
|
#define UseSql2012Express
|
||||||
|
#define UseSql2014Express
|
||||||
|
#define UseSql2016Express
|
||||||
|
#define UseSql2017Express
|
||||||
|
#define UseSql2019Express
|
||||||
|
|
||||||
|
#define UseWebView2
|
||||||
|
|
||||||
|
#define MyAppSetupName 'MyProgram'
|
||||||
|
#define MyAppVersion '1.0'
|
||||||
|
#define MyAppPublisher 'Inno Setup'
|
||||||
|
#define MyAppCopyright 'Copyright <20> Inno Setup'
|
||||||
|
#define MyAppURL 'https://jrsoftware.org/isinfo.php'
|
||||||
|
|
||||||
|
AppName={#MyAppSetupName}
|
||||||
|
AppVersion={#MyAppVersion}
|
||||||
|
AppVerName={#MyAppSetupName} {#MyAppVersion}
|
||||||
|
AppCopyright={#MyAppCopyright}
|
||||||
|
VersionInfoVersion={#MyAppVersion}
|
||||||
|
VersionInfoCompany={#MyAppPublisher}
|
||||||
|
AppPublisher={#MyAppPublisher}
|
||||||
|
AppPublisherURL={#MyAppURL}
|
||||||
|
AppSupportURL={#MyAppURL}
|
||||||
|
AppUpdatesURL={#MyAppURL}
|
||||||
|
OutputBaseFilename={#MyAppSetupName}-{#MyAppVersion}
|
||||||
|
DefaultGroupName={#MyAppSetupName}
|
||||||
|
DefaultDirName={autopf}\{#MyAppSetupName}
|
||||||
|
UninstallDisplayIcon={app}\MyProgram.exe
|
||||||
|
SourceDir=src
|
||||||
|
OutputDir={#SourcePath}\bin
|
||||||
|
AllowNoIcons=yes
|
||||||
|
PrivilegesRequired=admin
|
||||||
|
|
||||||
|
; remove next line if you only deploy 32-bit binaries and dependencies
|
||||||
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: en; MessagesFile: "compiler:Default.isl"
|
||||||
|
Name: nl; MessagesFile: "compiler:Languages\Dutch.isl"
|
||||||
|
Name: de; MessagesFile: "compiler:Languages\German.isl"
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
#ifdef UseNetCoreCheck
|
||||||
|
; download netcorecheck.exe: https://go.microsoft.com/fwlink/?linkid=2135256
|
||||||
|
; download netcorecheck_x64.exe: https://go.microsoft.com/fwlink/?linkid=2135504
|
||||||
|
Source: "netcorecheck.exe"; Flags: dontcopy noencryption
|
||||||
|
Source: "netcorecheck_x64.exe"; Flags: dontcopy noencryption
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UseDirectX
|
||||||
|
Source: "dxwebsetup.exe"; Flags: dontcopy noencryption
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Source: "MyProg-x64.exe"; DestDir: "{app}"; DestName: "MyProg.exe"; Check: Dependency_IsX64; Flags: ignoreversion
|
||||||
|
Source: "MyProg.exe"; DestDir: "{app}"; Check: not Dependency_IsX64; Flags: ignoreversion
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{group}\{#MyAppSetupName}"; Filename: "{app}\MyProg.exe"
|
||||||
|
Name: "{group}\{cm:UninstallProgram,{#MyAppSetupName}}"; Filename: "{uninstallexe}"
|
||||||
|
Name: "{commondesktop}\{#MyAppSetupName}"; Filename: "{app}\MyProg.exe"; Tasks: desktopicon
|
||||||
|
|
||||||
|
[Tasks]
|
||||||
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: "{app}\MyProg.exe"; Description: "{cm:LaunchProgram,{#MyAppSetupName}}"; Flags: nowait postinstall skipifsilent
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
function InitializeSetup: Boolean;
|
||||||
|
begin
|
||||||
|
#ifdef UseDotNet35
|
||||||
|
Dependency_AddDotNet35;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet40
|
||||||
|
Dependency_AddDotNet40;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet45
|
||||||
|
Dependency_AddDotNet45;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet46
|
||||||
|
Dependency_AddDotNet46;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet47
|
||||||
|
Dependency_AddDotNet47;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet48
|
||||||
|
Dependency_AddDotNet48;
|
||||||
|
#endif
|
||||||
|
#ifdef UseNetCore31
|
||||||
|
Dependency_AddNetCore31;
|
||||||
|
#endif
|
||||||
|
#ifdef UseNetCore31Asp
|
||||||
|
Dependency_AddNetCore31Asp;
|
||||||
|
#endif
|
||||||
|
#ifdef UseNetCore31Desktop
|
||||||
|
Dependency_AddNetCore31Desktop;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet50
|
||||||
|
Dependency_AddDotNet50;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet50Asp
|
||||||
|
Dependency_AddDotNet50Asp;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet50Desktop
|
||||||
|
Dependency_AddDotNet50Desktop;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet60
|
||||||
|
Dependency_AddDotNet60;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet60Asp
|
||||||
|
Dependency_AddDotNet60Asp;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet60Desktop
|
||||||
|
Dependency_AddDotNet60Desktop;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet70
|
||||||
|
Dependency_AddDotNet70;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet70Asp
|
||||||
|
Dependency_AddDotNet70Asp;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDotNet70Desktop
|
||||||
|
Dependency_AddDotNet70Desktop;
|
||||||
|
#endif
|
||||||
|
#ifdef UseVC2005
|
||||||
|
Dependency_AddVC2005;
|
||||||
|
#endif
|
||||||
|
#ifdef UseVC2008
|
||||||
|
Dependency_AddVC2008;
|
||||||
|
#endif
|
||||||
|
#ifdef UseVC2010
|
||||||
|
Dependency_AddVC2010;
|
||||||
|
#endif
|
||||||
|
#ifdef UseVC2012
|
||||||
|
Dependency_AddVC2012;
|
||||||
|
#endif
|
||||||
|
#ifdef UseVC2013
|
||||||
|
//Dependency_ForceX86 := True; // force 32-bit install of next dependencies
|
||||||
|
Dependency_AddVC2013;
|
||||||
|
//Dependency_ForceX86 := False; // disable forced 32-bit install again
|
||||||
|
#endif
|
||||||
|
#ifdef UseVC2015To2022
|
||||||
|
Dependency_AddVC2015To2022;
|
||||||
|
#endif
|
||||||
|
#ifdef UseDirectX
|
||||||
|
ExtractTemporaryFile('dxwebsetup.exe');
|
||||||
|
Dependency_AddDirectX;
|
||||||
|
#endif
|
||||||
|
#ifdef UseSql2008Express
|
||||||
|
Dependency_AddSql2008Express;
|
||||||
|
#endif
|
||||||
|
#ifdef UseSql2012Express
|
||||||
|
Dependency_AddSql2012Express;
|
||||||
|
#endif
|
||||||
|
#ifdef UseSql2014Express
|
||||||
|
Dependency_AddSql2014Express;
|
||||||
|
#endif
|
||||||
|
#ifdef UseSql2016Express
|
||||||
|
Dependency_AddSql2016Express;
|
||||||
|
#endif
|
||||||
|
#ifdef UseSql2017Express
|
||||||
|
Dependency_AddSql2017Express;
|
||||||
|
#endif
|
||||||
|
#ifdef UseSql2019Express
|
||||||
|
Dependency_AddSql2019Express;
|
||||||
|
#endif
|
||||||
|
#ifdef UseWebView2
|
||||||
|
Dependency_AddWebView2;
|
||||||
|
#endif
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
#endif
|
||||||
587
Preprocessed.iss
Normal file
587
Preprocessed.iss
Normal file
@@ -0,0 +1,587 @@
|
|||||||
|
; Script generated by the Inno Setup Script Wizard.
|
||||||
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||||
|
; -- CodeDependencies.iss --
|
||||||
|
;
|
||||||
|
; This script shows how to download and install any dependency such as .NET,
|
||||||
|
; Visual C++ or SQL Server during your application's installation process.
|
||||||
|
;
|
||||||
|
; contribute: https://github.com/DomGries/InnoDependencyInstaller
|
||||||
|
; -----------
|
||||||
|
; SHARED CODE
|
||||||
|
; -----------
|
||||||
|
[Code]
|
||||||
|
type
|
||||||
|
TDependency_Entry = record
|
||||||
|
Filename: String;
|
||||||
|
Parameters: String;
|
||||||
|
Title: String;
|
||||||
|
URL: String;
|
||||||
|
Checksum: String;
|
||||||
|
ForceSuccess: Boolean;
|
||||||
|
RestartAfter: Boolean;
|
||||||
|
end;
|
||||||
|
var
|
||||||
|
Dependency_Memo: String;
|
||||||
|
Dependency_List: array of TDependency_Entry;
|
||||||
|
Dependency_NeedRestart, Dependency_ForceX86: Boolean;
|
||||||
|
Dependency_DownloadPage: TDownloadWizardPage;
|
||||||
|
procedure Dependency_Add(const Filename, Parameters, Title, URL, Checksum: String; const ForceSuccess, RestartAfter: Boolean);
|
||||||
|
var
|
||||||
|
Dependency: TDependency_Entry;
|
||||||
|
DependencyCount: Integer;
|
||||||
|
begin
|
||||||
|
Dependency_Memo := Dependency_Memo + #13#10 + '%1' + Title;
|
||||||
|
Dependency.Filename := Filename;
|
||||||
|
Dependency.Parameters := Parameters;
|
||||||
|
Dependency.Title := Title;
|
||||||
|
if FileExists(ExpandConstant('{tmp}{\}') + Filename) then begin
|
||||||
|
Dependency.URL := '';
|
||||||
|
end else begin
|
||||||
|
Dependency.URL := URL;
|
||||||
|
end;
|
||||||
|
Dependency.Checksum := Checksum;
|
||||||
|
Dependency.ForceSuccess := ForceSuccess;
|
||||||
|
Dependency.RestartAfter := RestartAfter;
|
||||||
|
DependencyCount := GetArrayLength(Dependency_List);
|
||||||
|
SetArrayLength(Dependency_List, DependencyCount + 1);
|
||||||
|
Dependency_List[DependencyCount] := Dependency;
|
||||||
|
end;
|
||||||
|
<event('InitializeWizard')>
|
||||||
|
procedure Dependency_Internal1;
|
||||||
|
begin
|
||||||
|
Dependency_DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil);
|
||||||
|
end;
|
||||||
|
<event('PrepareToInstall')>
|
||||||
|
function Dependency_Internal2(var NeedsRestart: Boolean): String;
|
||||||
|
var
|
||||||
|
DependencyCount, DependencyIndex, ResultCode: Integer;
|
||||||
|
Retry: Boolean;
|
||||||
|
TempValue: String;
|
||||||
|
begin
|
||||||
|
DependencyCount := GetArrayLength(Dependency_List);
|
||||||
|
if DependencyCount > 0 then begin
|
||||||
|
Dependency_DownloadPage.Show;
|
||||||
|
for DependencyIndex := 0 to DependencyCount - 1 do begin
|
||||||
|
if Dependency_List[DependencyIndex].URL <> '' then begin
|
||||||
|
Dependency_DownloadPage.Clear;
|
||||||
|
Dependency_DownloadPage.Add(Dependency_List[DependencyIndex].URL, Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Checksum);
|
||||||
|
Retry := True;
|
||||||
|
while Retry do begin
|
||||||
|
Retry := False;
|
||||||
|
try
|
||||||
|
Dependency_DownloadPage.Download;
|
||||||
|
except
|
||||||
|
if Dependency_DownloadPage.AbortedByUser then begin
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
DependencyIndex := DependencyCount;
|
||||||
|
end else begin
|
||||||
|
case SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
|
||||||
|
IDABORT: begin
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
DependencyIndex := DependencyCount;
|
||||||
|
end;
|
||||||
|
IDRETRY: begin
|
||||||
|
Retry := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Result = '' then begin
|
||||||
|
for DependencyIndex := 0 to DependencyCount - 1 do begin
|
||||||
|
Dependency_DownloadPage.SetText(Dependency_List[DependencyIndex].Title, '');
|
||||||
|
Dependency_DownloadPage.SetProgress(DependencyIndex + 1, DependencyCount + 1);
|
||||||
|
while True do begin
|
||||||
|
ResultCode := 0;
|
||||||
|
if ShellExec('', ExpandConstant('{tmp}{\}') + Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then begin
|
||||||
|
if Dependency_List[DependencyIndex].RestartAfter then begin
|
||||||
|
if DependencyIndex = DependencyCount - 1 then begin
|
||||||
|
Dependency_NeedRestart := True;
|
||||||
|
end else begin
|
||||||
|
NeedsRestart := True;
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end else if (ResultCode = 0) or Dependency_List[DependencyIndex].ForceSuccess then begin // ERROR_SUCCESS (0)
|
||||||
|
break;
|
||||||
|
end else if ResultCode = 1641 then begin // ERROR_SUCCESS_REBOOT_INITIATED (1641)
|
||||||
|
NeedsRestart := True;
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
break;
|
||||||
|
end else if ResultCode = 3010 then begin // ERROR_SUCCESS_REBOOT_REQUIRED (3010)
|
||||||
|
Dependency_NeedRestart := True;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
case SuppressibleMsgBox(FmtMessage(SetupMessage(msgErrorFunctionFailed), [Dependency_List[DependencyIndex].Title, IntToStr(ResultCode)]), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
|
||||||
|
IDABORT: begin
|
||||||
|
Result := Dependency_List[DependencyIndex].Title;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
IDIGNORE: begin
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Result <> '' then begin
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if NeedsRestart then begin
|
||||||
|
TempValue := '"' + ExpandConstant('{srcexe}') + '" /restart=1 /LANG="' + ExpandConstant('{language}') + '" /DIR="' + WizardDirValue + '" /GROUP="' + WizardGroupValue + '" /TYPE="' + WizardSetupType(False) + '" /COMPONENTS="' + WizardSelectedComponents(False) + '" /TASKS="' + WizardSelectedTasks(False) + '"';
|
||||||
|
if WizardNoIcons then begin
|
||||||
|
TempValue := TempValue + ' /NOICONS';
|
||||||
|
end;
|
||||||
|
RegWriteStringValue(HKA, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', '', TempValue);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Dependency_DownloadPage.Hide;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
<event('UpdateReadyMemo')>
|
||||||
|
function Dependency_Internal3(const Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
if MemoUserInfoInfo <> '' then begin
|
||||||
|
Result := Result + MemoUserInfoInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoDirInfo <> '' then begin
|
||||||
|
Result := Result + MemoDirInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoTypeInfo <> '' then begin
|
||||||
|
Result := Result + MemoTypeInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoComponentsInfo <> '' then begin
|
||||||
|
Result := Result + MemoComponentsInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoGroupInfo <> '' then begin
|
||||||
|
Result := Result + MemoGroupInfo + Newline + NewLine;
|
||||||
|
end;
|
||||||
|
if MemoTasksInfo <> '' then begin
|
||||||
|
Result := Result + MemoTasksInfo;
|
||||||
|
end;
|
||||||
|
if Dependency_Memo <> '' then begin
|
||||||
|
if MemoTasksInfo = '' then begin
|
||||||
|
Result := Result + SetupMessage(msgReadyMemoTasks);
|
||||||
|
end;
|
||||||
|
Result := Result + FmtMessage(Dependency_Memo, [Space]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
<event('NeedRestart')>
|
||||||
|
function Dependency_Internal4: Boolean;
|
||||||
|
begin
|
||||||
|
Result := Dependency_NeedRestart;
|
||||||
|
end;
|
||||||
|
function Dependency_IsX64: Boolean;
|
||||||
|
begin
|
||||||
|
Result := not Dependency_ForceX86 and Is64BitInstallMode;
|
||||||
|
end;
|
||||||
|
function Dependency_String(const x86, x64: String): String;
|
||||||
|
begin
|
||||||
|
if Dependency_IsX64 then begin
|
||||||
|
Result := x64;
|
||||||
|
end else begin
|
||||||
|
Result := x86;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
function Dependency_ArchSuffix: String;
|
||||||
|
begin
|
||||||
|
Result := Dependency_String('', '_x64');
|
||||||
|
end;
|
||||||
|
function Dependency_ArchTitle: String;
|
||||||
|
begin
|
||||||
|
Result := Dependency_String(' (x86)', ' (x64)');
|
||||||
|
end;
|
||||||
|
function Dependency_IsNetCoreInstalled(const Version: String): Boolean;
|
||||||
|
var
|
||||||
|
ResultCode: Integer;
|
||||||
|
begin
|
||||||
|
if not FileExists(ExpandConstant('{tmp}{\}') + 'netcorecheck' + Dependency_ArchSuffix + '.exe') then begin
|
||||||
|
ExtractTemporaryFile('netcorecheck' + Dependency_ArchSuffix + '.exe');
|
||||||
|
end;
|
||||||
|
StringChangeEx(Version, ' ', ' -v ', True)
|
||||||
|
Result := ShellExec('', ExpandConstant('{tmp}{\}') + 'netcorecheck' + Dependency_ArchSuffix + '.exe', ' -n ' + Version, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0);
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet35;
|
||||||
|
begin
|
||||||
|
if not IsDotNetInstalled(net35, 1) then begin
|
||||||
|
Dependency_Add('dotnetfx35.exe',
|
||||||
|
'/lang:enu /passive /norestart',
|
||||||
|
'.NET Framework 3.5 Service Pack 1',
|
||||||
|
'https://download.microsoft.com/download/2/0/E/20E90413-712F-438C-988E-FDAA79A8AC3D/dotnetfx35.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet40;
|
||||||
|
begin
|
||||||
|
if not IsDotNetInstalled(net4full, 0) then begin
|
||||||
|
Dependency_Add('dotNetFx40_Full_setup.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.0',
|
||||||
|
'https://download.microsoft.com/download/1/B/E/1BE39E79-7E39-46A3-96FF-047F95396215/dotNetFx40_Full_setup.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet45;
|
||||||
|
begin
|
||||||
|
if not IsDotNetInstalled(net452, 0) then begin
|
||||||
|
Dependency_Add('dotnetfx45.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.5.2',
|
||||||
|
'https://go.microsoft.com/fwlink/?LinkId=397707',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet46;
|
||||||
|
begin
|
||||||
|
if not IsDotNetInstalled(net462, 0) then begin
|
||||||
|
Dependency_Add('dotnetfx46.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.6.2',
|
||||||
|
'https://go.microsoft.com/fwlink/?linkid=780596',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet47;
|
||||||
|
begin
|
||||||
|
if not IsDotNetInstalled(net472, 0) then begin
|
||||||
|
Dependency_Add('dotnetfx47.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.7.2',
|
||||||
|
'https://go.microsoft.com/fwlink/?LinkId=863262',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet48;
|
||||||
|
begin
|
||||||
|
if not IsDotNetInstalled(net48, 0) then begin
|
||||||
|
Dependency_Add('dotnetfx48.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Framework 4.8',
|
||||||
|
'https://go.microsoft.com/fwlink/?LinkId=2085155',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddNetCore31;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App 3.1.22') then begin
|
||||||
|
Dependency_Add('netcore31' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Core Runtime 3.1.22' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/c2437aed-8cc4-41d0-a239-d6c7cf7bddae/062c37e8b06df740301c0bca1b0b7b9a/dotnet-runtime-3.1.22-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/4e95705e-1bb6-4764-b899-1b97eb70ea1d/dd311e073bd3e25b2efe2dcf02727e81/dotnet-runtime-3.1.22-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddNetCore31Asp;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App 3.1.22') then begin
|
||||||
|
Dependency_Add('netcore31asp' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'ASP.NET Core Runtime 3.1.22' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/0a1a2ee5-b8ed-4f0d-a4af-a7bce9a9ac2b/d452039b49d79e8897f272c3ab34b875/aspnetcore-runtime-3.1.22-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/80e52143-31e8-450e-aa94-b3f8484aaba9/4b69e5c77d50e7b367960a0079c90a99/aspnetcore-runtime-3.1.22-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddNetCore31Desktop;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 3.1.22') then begin
|
||||||
|
Dependency_Add('netcore31desktop' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Desktop Runtime 3.1.22' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/e4fcd574-4487-4b4b-8ca8-c23177c6f59f/c6d67a04956169dc21895cdcb42bf344/windowsdesktop-runtime-3.1.22-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/1c14e24b-7f31-42dc-ba3c-83295a2d6f7e/41b93591162dfe556cc160ae44fbe75e/windowsdesktop-runtime-3.1.22-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet50;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App 5.0.13') then begin
|
||||||
|
Dependency_Add('dotnet50' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Runtime 5.0.13' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/4a79fcd5-d61b-4606-8496-68071c8099c6/2bf770ca40521e8c4563072592eadd06/dotnet-runtime-5.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/fccf43d2-3e62-4ede-b5a5-592a7ccded7b/6339f1fdfe3317df5b09adf65f0261ab/dotnet-runtime-5.0.13-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet50Asp;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App 5.0.13') then begin
|
||||||
|
Dependency_Add('dotnet50asp' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'ASP.NET Core Runtime 5.0.13' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/340f9482-fc43-4ef7-b434-e2ed57f55cb3/c641b805cef3823769409a6dbac5746b/aspnetcore-runtime-5.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/aac560f3-eac8-437e-aebd-9830119deb10/6a3880161cf527e4ec71f67efe4d91ad/aspnetcore-runtime-5.0.13-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet50Desktop;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 5.0.13') then begin
|
||||||
|
Dependency_Add('dotnet50desktop' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Desktop Runtime 5.0.13' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/c8125c6b-d399-4be3-b201-8f1394fc3b25/724758f754fc7b67daba74db8d6d91d9/windowsdesktop-runtime-5.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/2bfb80f2-b8f2-44b0-90c1-d3c8c1c8eac8/409dd3d3367feeeda048f4ff34b32e82/windowsdesktop-runtime-5.0.13-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet60;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App 6.0.11') then begin
|
||||||
|
Dependency_Add('dotnet60' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Runtime 6.0.11' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/719bfd7c-bce2-4e73-937c-cbd7a7ace3cb/d4f570d461711d22e277f1e3487ea9c2/dotnet-runtime-6.0.11-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/8cf88855-ed09-4002-95db-8bb0f0eff051/f9006645511830bd3b840be132423768/dotnet-runtime-6.0.11-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet60Asp;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App 6.0.11') then begin
|
||||||
|
Dependency_Add('dotnet60asp' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'ASP.NET Core Runtime 6.0.11' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/94504599-143a-4d53-b518-74aee0ebecca/dac4a7b1f7bdc7b4e8441d6befa4941a/aspnetcore-runtime-6.0.11-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/e874914f-d43d-4b61-8479-f6a5536e44b1/7043adfe896aa9f980ce23e884aae37d/aspnetcore-runtime-6.0.11-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet60Desktop;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 6.0.11') then begin
|
||||||
|
Dependency_Add('dotnet60desktop' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Desktop Runtime 6.0.11' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/2a392287-fd51-4ee8-9c15-a672ab9bc55d/03d4784b3a543a0fb9ce5677ed13a9a3/windowsdesktop-runtime-6.0.11-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/0192a249-3ec8-4374-a827-e186dd58d55d/cec046575f3eb2247a10ba3d50f5cf6c/windowsdesktop-runtime-6.0.11-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet70;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App 7.0.3') then begin
|
||||||
|
Dependency_Add('dotnet70' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Runtime 7.0.3' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/9dd2da29-ca47-40fb-81a0-96fe26ea8ea2/e8f7e09a6d4848b8c4a13282d964b9e1/dotnet-runtime-7.0.3-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/c69813b7-2ece-4c2e-8c45-e33006985e18/61cc8fe4693a662b2da55ad932a46446/dotnet-runtime-7.0.3-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet70Asp;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App 7.0.3') then begin
|
||||||
|
Dependency_Add('dotnet70asp' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'ASP.NET Core Runtime 7.0.3' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/4bf0f350-f947-408b-9ee4-539313b85634/b17087052d6192b5d59735ae6f208c19/aspnetcore-runtime-7.0.3-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/d37efccc-2ba1-4fc9-a1ef-a8e1e77fb681/b9a20fc29ff05f18d81620ec88ade699/aspnetcore-runtime-7.0.3-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDotNet70Desktop;
|
||||||
|
begin
|
||||||
|
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 7.0.3') then begin
|
||||||
|
Dependency_Add('dotnet70desktop' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
||||||
|
'.NET Desktop Runtime 7.0.3' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/fb8bf100-9e1c-472c-8bc8-aa16fff44f53/8d36f5a56edff8620f9c63c1e73ba88c/windowsdesktop-runtime-7.0.3-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/3ebf014d-fcb9-4200-b3fe-76ba2000b027/840f2f95833ce400a9949e35f1581d28/windowsdesktop-runtime-7.0.3-win-x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2005;
|
||||||
|
begin
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{86C9D5AA-F00C-4921-B3F2-C60AF92E2844}', '{A8D19029-8E5C-4E22-8011-48070F9E796E}'), PackVersionComponents(8, 0, 61000, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2005' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/q',
|
||||||
|
'Visual C++ 2005 Service Pack 1 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.EXE', 'https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.EXE'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2008;
|
||||||
|
begin
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{DE2C306F-A067-38EF-B86C-03DE4B0312F9}', '{FDA45DDF-8E17-336F-A3ED-356B7B7C688A}'), PackVersionComponents(9, 0, 30729, 6161)) then begin
|
||||||
|
Dependency_Add('vcredist2008' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/q',
|
||||||
|
'Visual C++ 2008 Service Pack 1 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe', 'https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2010;
|
||||||
|
begin
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{1F4F1D2A-D9DA-32CF-9909-48485DA06DD5}', '{5B75F761-BAC8-33BC-A381-464DDDD813A3}'), PackVersionComponents(10, 0, 40219, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2010' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/passive /norestart',
|
||||||
|
'Visual C++ 2010 Service Pack 1 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe', 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2012;
|
||||||
|
begin
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{4121ED58-4BD9-3E7B-A8B5-9F8BAAE045B7}', '{EFA6AFA1-738E-3E00-8101-FD03B86B29D1}'), PackVersionComponents(11, 0, 61030, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2012' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/passive /norestart',
|
||||||
|
'Visual C++ 2012 Update 4 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe', 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2013;
|
||||||
|
begin
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{B59F5BF1-67C8-3802-8E59-2CE551A39FC5}', '{20400CF0-DE7C-327E-9AE4-F0F38D9085F8}'), PackVersionComponents(12, 0, 40664, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2013' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/passive /norestart',
|
||||||
|
'Visual C++ 2013 Update 5 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://download.visualstudio.microsoft.com/download/pr/10912113/5da66ddebb0ad32ebd4b922fd82e8e25/vcredist_x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/10912041/cee5d6bca2ddbcd039da727bf4acb48a/vcredist_x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddVC2015To2022;
|
||||||
|
begin
|
||||||
|
if not IsMsiProductInstalled(Dependency_String('{65E5BD06-6392-3027-8C26-853107D3CF1A}', '{36F68A90-239C-34DF-B58C-64B30153CE35}'), PackVersionComponents(14, 30, 30704, 0)) then begin
|
||||||
|
Dependency_Add('vcredist2022' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/passive /norestart',
|
||||||
|
'Visual C++ 2015-2022 Redistributable' + Dependency_ArchTitle,
|
||||||
|
Dependency_String('https://aka.ms/vs/17/release/vc_redist.x86.exe', 'https://aka.ms/vs/17/release/vc_redist.x64.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddDirectX;
|
||||||
|
begin
|
||||||
|
Dependency_Add('dxwebsetup.exe',
|
||||||
|
'/q',
|
||||||
|
'DirectX Runtime',
|
||||||
|
'https://download.microsoft.com/download/1/7/1/1718CCC4-6315-4D8E-9543-8E28A4E18C4C/dxwebsetup.exe',
|
||||||
|
'', True, False);
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2008Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(10, 50, 4000, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2008express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2008 R2 Service Pack 2 Express',
|
||||||
|
Dependency_String('https://download.microsoft.com/download/0/4/B/04BE03CD-EAF3-4797-9D8D-2E08E316C998/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/0/4/B/04BE03CD-EAF3-4797-9D8D-2E08E316C998/SQLEXPR_x64_ENU.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2012Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(11, 0, 7001, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2012express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2012 Service Pack 4 Express',
|
||||||
|
Dependency_String('https://download.microsoft.com/download/B/D/E/BDE8FAD6-33E5-44F6-B714-348F73E602B6/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/B/D/E/BDE8FAD6-33E5-44F6-B714-348F73E602B6/SQLEXPR_x64_ENU.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2014Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(12, 0, 6024, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2014express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2014 Service Pack 3 Express',
|
||||||
|
Dependency_String('https://download.microsoft.com/download/3/9/F/39F968FA-DEBB-4960-8F9E-0E7BB3035959/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/3/9/F/39F968FA-DEBB-4960-8F9E-0E7BB3035959/SQLEXPR_x64_ENU.exe'),
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2016Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(13, 0, 5026, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2016express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2016 Service Pack 2 Express',
|
||||||
|
'https://download.microsoft.com/download/3/7/6/3767D272-76A1-4F31-8849-260BD37924E4/SQLServer2016-SSEI-Expr.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2017Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(14, 0, 0, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2017express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2017 Express',
|
||||||
|
'https://download.microsoft.com/download/5/E/9/5E9B18CC-8FD5-467E-B5BF-BADE39C51F73/SQLServer2017-SSEI-Expr.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddSql2019Express;
|
||||||
|
var
|
||||||
|
Version: String;
|
||||||
|
PackedVersion: Int64;
|
||||||
|
begin
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(15, 0, 0, 0)) < 0) then begin
|
||||||
|
Dependency_Add('sql2019express' + Dependency_ArchSuffix + '.exe',
|
||||||
|
'/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER',
|
||||||
|
'SQL Server 2019 Express',
|
||||||
|
'https://download.microsoft.com/download/7/f/8/7f8a9c43-8c8a-4f7c-9f92-83c18d96b681/SQL2019-SSEI-Expr.exe',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
procedure Dependency_AddWebView2;
|
||||||
|
begin
|
||||||
|
if not RegValueExists(HKLM, Dependency_String('SOFTWARE', 'SOFTWARE\WOW6432Node') + '\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv') then begin
|
||||||
|
Dependency_Add('MicrosoftEdgeWebview2Setup.exe',
|
||||||
|
'/silent /install',
|
||||||
|
'WebView2 Runtime',
|
||||||
|
'https://go.microsoft.com/fwlink/p/?LinkId=2124703',
|
||||||
|
'', False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
[Setup]
|
||||||
|
; -------------
|
||||||
|
; EXAMPLE SETUP
|
||||||
|
; -------------
|
||||||
|
[Setup]
|
||||||
|
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||||
|
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||||
|
AppId={{7774CEEE-6785-48B9-BA35-6B842F947A21}
|
||||||
|
AppName=Twitchy
|
||||||
|
AppVersion=0.5
|
||||||
|
DefaultDirName={autopf}\Twitchy
|
||||||
|
DisableProgramGroupPage=yes
|
||||||
|
LicenseFile=.\TwitchDesktopNotifications\Lisence.rtf
|
||||||
|
; Uncomment the following line to run in non administrative install mode (install for current user only.)
|
||||||
|
;PrivilegesRequired=lowest
|
||||||
|
OutputDir=.\SetupFiles
|
||||||
|
OutputBaseFilename=TwitchySetup
|
||||||
|
SetupIconFile=.\TwitchDesktopNotifications\Assets\icon.ico
|
||||||
|
UninstallDisplayIcon=.\TwitchDesktopNotifications\Assets\icon.ico
|
||||||
|
WizardSmallImageFile=.\TwitchDesktopNotifications\Assets\twitch.bmp
|
||||||
|
Compression=lzma
|
||||||
|
SolidCompression=yes
|
||||||
|
WizardStyle=modern
|
||||||
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
|
SignedUninstaller=yes
|
||||||
|
SignTool=signtool
|
||||||
|
SourceDir=.\
|
||||||
|
[Languages]
|
||||||
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
[Tasks]
|
||||||
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||||
|
Name: "autostarticon"; Description: "{cm:AutoStartProgram,Twitchy}"; GroupDescription: "{cm:AdditionalIcons}";
|
||||||
|
[Files]
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\Twitchy.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\Microsoft.Toolkit.Uwp.Notifications.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\Microsoft.Windows.SDK.NET.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\Twitchy.deps.json"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\Twitchy.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\Twitchy.runtimeconfig.json"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\WinRT.Runtime.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\Assets\icon.ico"; DestDir: "{app}\Assets"; Flags: ignoreversion
|
||||||
|
Source: "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\Assets\twitch.png"; DestDir: "{app}\Assets"; Flags: ignoreversion
|
||||||
|
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||||
|
Source: "netcorecheck.exe"; Flags: dontcopy noencryption
|
||||||
|
Source: "netcorecheck_x64.exe"; Flags: dontcopy noencryption
|
||||||
45
Readme.md
45
Readme.md
@@ -1,15 +1,46 @@
|
|||||||
# Twitch Notify
|
# Twitchy
|
||||||
|
The Twitch windows desktop notification system.
|
||||||
|
|
||||||
|
[](https://www.paypal.com/donate/?hosted_button_id=9YUH3GCJ83A4G)
|
||||||
|
|
||||||
## Not affiliated with Twitch or Amazon
|
## Not affiliated with Twitch or Amazon
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Twitch Notify Requires [.NET 6 Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.13-windows-x64-installer).
|
Twitch Notify Requires [.NET 6 Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.13-windows-x64-installer).
|
||||||
|
As of RC-1 There is now a Setup that will install into auto run aswell
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
**How to Manage Ignores:**
|
||||||
|
1. Click "Manage Ignores" from the right click notification area icon
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
2, the following form will open where you can manage streamers that should be ignored
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
_Something to note:_
|
||||||
|
Making changes inside the form is saved automatically
|
||||||
|
Streamers won't appear in the form until they have been seen
|
||||||
|
|
||||||
|
**How to Exit:**
|
||||||
|
To exit you will have a Notification Icon / Tray icon where you can quit the application.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
**What it looks like:**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Want to contribute? Great!
|
Want to contribute? Great!
|
||||||
|
|
||||||
Project is built using Visual Studios 2022,
|
Project is built using Visual Studios 2022, please make sure you have added support for .NET 6, You will also requrie the Windows SDK (10.0.17763.0)
|
||||||
|
|
||||||
|
If your unable to code sign you can build configuration to "Debug" or "Release" mode the signing script will only run if set to "ReleaseSign".
|
||||||
|
|
||||||
You need to create Application to obtain a ID and Secret on [Twitch Developer Console](https://dev.twitch.tv/console)
|
You need to create Application to obtain a ID and Secret on [Twitch Developer Console](https://dev.twitch.tv/console)
|
||||||
Add a new C# Class to the project named `TwitchDetails.cs` add the following code with your ID and Secret
|
Add a new C# Class to the project named `TwitchDetails.cs` add the following code with your ID and Secret
|
||||||
@@ -34,7 +65,15 @@ Project Requests `CommunityToolkit-MainLatest` NuGET Package Source
|
|||||||
6. Click Update
|
6. Click Update
|
||||||
7. Click Ok
|
7. Click Ok
|
||||||
|
|
||||||
|
### Thanks
|
||||||
|
A Huge Thanks to [CaspersGG](https://twitch.tv/CaspersGG) for coming up with this idea.
|
||||||
|
Thanks to the following streamers for testing and promoting this application:
|
||||||
|
1. [Uprisen](https://twitch.tv/uprisen)
|
||||||
|
2. [Anthogator](https://www.twitch.tv/anthogator)
|
||||||
|
3. [Strife98](https://www.twitch.tv/strife98)
|
||||||
|
4. [petfriendamy_](https://www.twitch.tv/petfriendamy_)
|
||||||
|
5. [Roxas997](https://www.twitch.tv/roxas997)
|
||||||
|
6. [Anthogator](https://www.twitch.tv/anthogator)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,30 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.4.33205.214
|
VisualStudioVersion = 17.4.33205.214
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwitchDesktopNotifications", "TwitchDesktopNotifications\TwitchDesktopNotifications.csproj", "{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TwitchDesktopNotifications", "TwitchDesktopNotifications\TwitchDesktopNotifications.csproj", "{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
ReleaseSign|Any CPU = ReleaseSign|Any CPU
|
||||||
|
ReleaseSign|x64 = ReleaseSign|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Debug|x64.Build.0 = Debug|x64
|
||||||
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Release|Any CPU.Build.0 = Release|Any CPU
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.Release|x64.Build.0 = Release|x64
|
||||||
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.ReleaseSign|Any CPU.ActiveCfg = ReleaseSign|Any CPU
|
||||||
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.ReleaseSign|Any CPU.Build.0 = ReleaseSign|Any CPU
|
||||||
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.ReleaseSign|x64.ActiveCfg = ReleaseSign|x64
|
||||||
|
{323F3EBC-C1B1-4DDE-9069-5A65EDA4EB16}.ReleaseSign|x64.Build.0 = ReleaseSign|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
BIN
TwitchDesktopNotifications/Assets/twitch.bmp
Normal file
BIN
TwitchDesktopNotifications/Assets/twitch.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
39
TwitchDesktopNotifications/Core/Logger.cs
Normal file
39
TwitchDesktopNotifications/Core/Logger.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TwitchDesktopNotifications.Core
|
||||||
|
{
|
||||||
|
public class Logger : SingletonFactory<Logger>, Singleton
|
||||||
|
{
|
||||||
|
private string _name;
|
||||||
|
private StreamWriter sw;
|
||||||
|
public Logger()
|
||||||
|
{
|
||||||
|
_name = DateTime.Now.ToString("dd_mm_yyyy HH_mm")+".log";
|
||||||
|
}
|
||||||
|
|
||||||
|
~Logger()
|
||||||
|
{
|
||||||
|
if (sw != null)
|
||||||
|
{
|
||||||
|
sw.Flush();
|
||||||
|
sw.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreamWriter Writer {
|
||||||
|
get {
|
||||||
|
if(sw == null)
|
||||||
|
{
|
||||||
|
String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
|
||||||
|
sw = new StreamWriter(FilePath+_name);
|
||||||
|
}
|
||||||
|
return sw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,12 +10,14 @@ using Windows.Foundation.Collections;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using Windows.UI.Notifications;
|
using Windows.UI.Notifications;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
namespace TwitchDesktopNotifications.Core
|
namespace TwitchDesktopNotifications.Core
|
||||||
{
|
{
|
||||||
internal class Notification
|
public class Notification : SingletonFactory<Notification>, Singleton
|
||||||
{
|
{
|
||||||
private Notification() {
|
private WebClient webClient = new WebClient();
|
||||||
|
public Notification() {
|
||||||
ToastNotificationManagerCompat.OnActivated += toastArgs =>
|
ToastNotificationManagerCompat.OnActivated += toastArgs =>
|
||||||
{
|
{
|
||||||
// Obtain the arguments from the notification
|
// Obtain the arguments from the notification
|
||||||
@@ -34,22 +36,16 @@ namespace TwitchDesktopNotifications.Core
|
|||||||
myProcess.StartInfo.UseShellExecute = true;
|
myProcess.StartInfo.UseShellExecute = true;
|
||||||
myProcess.StartInfo.FileName = args["streamerUrl"];
|
myProcess.StartInfo.FileName = args["streamerUrl"];
|
||||||
myProcess.Start();
|
myProcess.Start();
|
||||||
|
}else if( args.Contains("action") && args["action"] == "ignore")
|
||||||
|
{
|
||||||
|
NotifyManager.AddStreamerToIgnoreList(args["streamerName"]);
|
||||||
}
|
}
|
||||||
}catch(Exception ex) { }
|
}catch(Exception ex) {
|
||||||
|
Logger.GetInstance().Writer.WriteLine(ex.ToString());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Notification Instance;
|
|
||||||
|
|
||||||
public static Notification GetInstance()
|
|
||||||
{
|
|
||||||
if(Instance == null)
|
|
||||||
{
|
|
||||||
Instance = new Notification();
|
|
||||||
}
|
|
||||||
return Instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendNotification(String streamerName, String streamerUrl, String profilePic, String streamThumbnail, String title)
|
public void sendNotification(String streamerName, String streamerUrl, String profilePic, String streamThumbnail, String title)
|
||||||
{
|
{
|
||||||
String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
|
String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
|
||||||
@@ -60,52 +56,64 @@ namespace TwitchDesktopNotifications.Core
|
|||||||
string fileNameProfilePic = profilePic.Split("/").Last();
|
string fileNameProfilePic = profilePic.Split("/").Last();
|
||||||
if (!File.Exists(FilePath + "/" + fileNameProfilePic))
|
if (!File.Exists(FilePath + "/" + fileNameProfilePic))
|
||||||
{
|
{
|
||||||
(new WebClient()).DownloadFile(new Uri(profilePic), FilePath + "/" + fileNameProfilePic);
|
webClient.DownloadFile(new Uri(profilePic), FilePath + "/" + fileNameProfilePic);
|
||||||
}
|
}
|
||||||
|
|
||||||
// download there profile picture
|
// download there profile picture
|
||||||
string fileNameThumbnailPic = streamThumbnail.Split("/").Last();
|
string fileNameThumbnailPic = streamThumbnail.Split("/").Last();
|
||||||
(new WebClient()).DownloadFile(new Uri(streamThumbnail),
|
webClient.DownloadFile(new Uri(streamThumbnail),
|
||||||
FilePath + "/" + fileNameThumbnailPic
|
FilePath + "/" + fileNameThumbnailPic
|
||||||
);
|
);
|
||||||
|
|
||||||
var builder = new ToastContentBuilder()
|
if (NotifyManager.ShouldNotify(streamerName))
|
||||||
.AddArgument("streamerUrl", streamerUrl)
|
|
||||||
.AddArgument("thumbnail_path", FilePath + "/" + fileNameThumbnailPic)
|
|
||||||
.AddText(streamerName + " is now live on Twitch")
|
|
||||||
.AddHeroImage(new Uri("file://" + (FilePath + "/" + fileNameThumbnailPic).Replace("\\", "/")))
|
|
||||||
.AddAppLogoOverride(new Uri("file://" + (FilePath + "/" + fileNameProfilePic).Replace("\\", "/")), ToastGenericAppLogoCrop.Circle)
|
|
||||||
.AddButton(new ToastButton()
|
|
||||||
.SetContent("Watch " + streamerName)
|
|
||||||
.AddArgument("action", "watch")
|
|
||||||
.SetBackgroundActivation())
|
|
||||||
.AddButton(new ToastButton()
|
|
||||||
.SetContent("Dismiss")
|
|
||||||
.AddArgument("action", "nothing")
|
|
||||||
.SetBackgroundActivation());
|
|
||||||
|
|
||||||
if(title != "") {
|
|
||||||
builder.AddText(title);
|
|
||||||
}
|
|
||||||
builder.Show(toast =>
|
|
||||||
{
|
{
|
||||||
toast.ExpirationTime = DateTime.Now.AddSeconds(15);
|
var builder = new ToastContentBuilder()
|
||||||
toast.Dismissed += (ToastNotification sender, ToastDismissedEventArgs args) =>
|
.AddArgument("streamerUrl", streamerUrl)
|
||||||
|
.AddArgument("streamerName", streamerName)
|
||||||
|
.AddArgument("thumbnail_path", FilePath + "/" + fileNameThumbnailPic)
|
||||||
|
.AddText(streamerName + " is now live on Twitch")
|
||||||
|
.AddHeroImage(new Uri("file://" + (FilePath + "/" + fileNameThumbnailPic).Replace("\\", "/")))
|
||||||
|
.AddAppLogoOverride(new Uri("file://" + (FilePath + "/" + fileNameProfilePic).Replace("\\", "/")), ToastGenericAppLogoCrop.Circle)
|
||||||
|
.AddButton(new ToastButton()
|
||||||
|
.SetContent("Watch ")
|
||||||
|
.AddArgument("action", "watch")
|
||||||
|
.SetBackgroundActivation())
|
||||||
|
.AddButton(new ToastButton()
|
||||||
|
.SetContent("Dismiss")
|
||||||
|
.AddArgument("action", "nothing")
|
||||||
|
.SetBackgroundActivation())
|
||||||
|
.AddButton(new ToastButton()
|
||||||
|
.SetContent("Ignore")
|
||||||
|
.AddArgument("action", "ignore")
|
||||||
|
.SetBackgroundActivation());
|
||||||
|
|
||||||
|
if (title != "")
|
||||||
{
|
{
|
||||||
try
|
builder.AddText(title);
|
||||||
{
|
}
|
||||||
File.Delete(FilePath + "/" + fileNameThumbnailPic);
|
builder.Show(toast =>
|
||||||
}catch(Exception) { }
|
|
||||||
};
|
|
||||||
toast.Activated += (ToastNotification sender, object args) =>
|
|
||||||
{
|
{
|
||||||
try
|
toast.ExpirationTime = DateTime.Now.AddMinutes(10);
|
||||||
|
toast.Dismissed += (ToastNotification sender, ToastDismissedEventArgs args) =>
|
||||||
{
|
{
|
||||||
File.Delete(FilePath + "/" + fileNameThumbnailPic);
|
try
|
||||||
}
|
{
|
||||||
catch (Exception) { }
|
File.Delete(FilePath + "/" + fileNameThumbnailPic);
|
||||||
};
|
}
|
||||||
});
|
catch (Exception) { }
|
||||||
|
builder = null;
|
||||||
|
};
|
||||||
|
toast.Activated += (ToastNotification sender, object args) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(FilePath + "/" + fileNameThumbnailPic);
|
||||||
|
}
|
||||||
|
catch (Exception) { }
|
||||||
|
builder = null;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
TwitchDesktopNotifications/Core/NotifyManager.cs
Normal file
29
TwitchDesktopNotifications/Core/NotifyManager.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.Toolkit.Uwp.Notifications;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using TwitchDesktopNotifications.JsonStructure.Helix;
|
||||||
|
|
||||||
|
namespace TwitchDesktopNotifications.Core
|
||||||
|
{
|
||||||
|
internal class NotifyManager
|
||||||
|
{
|
||||||
|
|
||||||
|
public static Boolean ShouldNotify(String streamerName)
|
||||||
|
{
|
||||||
|
if(DataStore.GetInstance().Store.SteamersToIgnore == null || DataStore.GetInstance().Store.SteamersToIgnore.Streamers == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !UIStreamer.GetCreateStreamer(streamerName).IsIgnored;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddStreamerToIgnoreList(string streamerName)
|
||||||
|
{
|
||||||
|
UIStreamer.GetCreateStreamer(streamerName).IsIgnored = true;
|
||||||
|
DataStore.GetInstance().Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
TwitchDesktopNotifications/Core/SingletonFactory.cs
Normal file
26
TwitchDesktopNotifications/Core/SingletonFactory.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TwitchDesktopNotifications.Core
|
||||||
|
{
|
||||||
|
public interface Singleton
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public class SingletonFactory<T> where T : Singleton, new()
|
||||||
|
{
|
||||||
|
public static Dictionary<String, Singleton> store = new Dictionary<String, Singleton>();
|
||||||
|
|
||||||
|
public static T GetInstance(){
|
||||||
|
string name = typeof(T).FullName;
|
||||||
|
if (!store.ContainsKey(name))
|
||||||
|
{
|
||||||
|
store.Add(name, new T());
|
||||||
|
}
|
||||||
|
return (T)store[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,11 +9,30 @@ using TwitchDesktopNotifications.JsonStructure.Helix;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.Core
|
namespace TwitchDesktopNotifications.Core
|
||||||
{
|
{
|
||||||
|
internal class TwitcherRefreshException : Exception
|
||||||
|
{
|
||||||
|
public TwitcherRefreshException(string? message, Exception? innerException) : base(message, innerException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
internal class TwitchFetcher
|
internal class TwitchFetcher
|
||||||
{
|
{
|
||||||
private TwitchFetcher() {
|
private TwitchFetcher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReconnectionNeeded rnFrm;
|
||||||
|
|
||||||
|
public void OpenFailedNotification()
|
||||||
|
{
|
||||||
|
if (rnFrm == null)
|
||||||
|
{
|
||||||
|
rnFrm = new ReconnectionNeeded();
|
||||||
|
}
|
||||||
|
if (rnFrm.IsActive)
|
||||||
|
{
|
||||||
|
rnFrm.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static TwitchFetcher instance { get; private set; }
|
public static TwitchFetcher instance { get; private set; }
|
||||||
|
|
||||||
List <StreamsData> currentlyLive = null;
|
List <StreamsData> currentlyLive = null;
|
||||||
@@ -46,36 +65,55 @@ namespace TwitchDesktopNotifications.Core
|
|||||||
{
|
{
|
||||||
throw new Exception("Not Authenticated");
|
throw new Exception("Not Authenticated");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DataStore.GetInstance().Store.Authentication.ExpiresAsDate <= DateTime.UtcNow)
|
if (DataStore.GetInstance().Store.Authentication.ExpiresAsDate <= DateTime.UtcNow)
|
||||||
{
|
{
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRequest request = WebRequest.Create("https://api.twitch.tv/" + endpoint);
|
try
|
||||||
request.Method = "GET";
|
{
|
||||||
request.Headers[HttpRequestHeader.Authorization] = String.Format("Bearer {0}", DataStore.GetInstance().Store.Authentication.AccessToken);
|
WebRequest request = WebRequest.Create("https://api.twitch.tv/" + endpoint);
|
||||||
request.Headers["Client-ID"] = TwitchDetails.TwitchClientID;
|
request.Method = "GET";
|
||||||
WebResponse response = request.GetResponse();
|
request.Headers[HttpRequestHeader.Authorization] = String.Format("Bearer {0}", DataStore.GetInstance().Store.Authentication.AccessToken);
|
||||||
Stream dataStream = response.GetResponseStream();
|
request.Headers["Client-ID"] = TwitchDetails.TwitchClientID;
|
||||||
StreamReader reader = new StreamReader(dataStream);
|
WebResponse response = request.GetResponse();
|
||||||
string responseFromServer = reader.ReadToEnd();
|
Stream dataStream = response.GetResponseStream();
|
||||||
reader.Close();
|
StreamReader reader = new StreamReader(dataStream);
|
||||||
dataStream.Close();
|
string responseFromServer = reader.ReadToEnd();
|
||||||
response.Close();
|
reader.Close();
|
||||||
|
dataStream.Close();
|
||||||
|
response.Close();
|
||||||
|
|
||||||
return JsonSerializer.Deserialize<T>(responseFromServer);
|
return JsonSerializer.Deserialize<T>(responseFromServer);
|
||||||
|
}
|
||||||
|
catch (TwitcherRefreshException ex)
|
||||||
|
{
|
||||||
|
OpenFailedNotification();
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
Logger.GetInstance().Writer.WriteLineAsync(ex.ToString());
|
||||||
|
}
|
||||||
|
return default(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FetchCurrentUser()
|
public void FetchCurrentUser()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DataStore.GetInstance().Store.UserData = MakeRequest<User>("helix/users").Data[0];
|
var UserList = MakeRequest<User>("helix/users");
|
||||||
DataStore.GetInstance().Save();
|
if (UserList.Data.Count > 0) {
|
||||||
}catch(System.Exception ex)
|
DataStore.GetInstance().Store.UserData = UserList.Data[0];
|
||||||
|
DataStore.GetInstance().Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (TwitcherRefreshException ex)
|
||||||
{
|
{
|
||||||
MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify");
|
OpenFailedNotification();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.GetInstance().Writer.WriteLineAsync(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,10 +121,19 @@ namespace TwitchDesktopNotifications.Core
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return MakeRequest<User>("helix/users?id=" + user_id).Data[0];
|
var Response = MakeRequest<User>("helix/users?id=" + user_id);
|
||||||
}catch(System.Exception ex)
|
if (Response.Data.Count > 0)
|
||||||
|
{
|
||||||
|
return Response.Data[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (TwitcherRefreshException ex)
|
||||||
{
|
{
|
||||||
MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify");
|
OpenFailedNotification();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.GetInstance().Writer.WriteLineAsync(ex.ToString());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -104,7 +151,7 @@ namespace TwitchDesktopNotifications.Core
|
|||||||
string QueryUrl = "helix/streams/followed?first=100&user_id=" + DataStore.GetInstance().Store.UserData.UserId;
|
string QueryUrl = "helix/streams/followed?first=100&user_id=" + DataStore.GetInstance().Store.UserData.UserId;
|
||||||
Streams following = MakeRequest<Streams>(QueryUrl);
|
Streams following = MakeRequest<Streams>(QueryUrl);
|
||||||
|
|
||||||
if (currentlyLive != null)
|
if (following != null && currentlyLive != null)
|
||||||
{
|
{
|
||||||
following.Data.ForEach(x =>
|
following.Data.ForEach(x =>
|
||||||
{
|
{
|
||||||
@@ -118,48 +165,60 @@ namespace TwitchDesktopNotifications.Core
|
|||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
UserData streamer = FetchUserData(x.UserId);
|
UserData streamer = FetchUserData(x.UserId);
|
||||||
|
UIStreamer.GetCreateStreamer(x.DisplayName);
|
||||||
Notification.GetInstance().sendNotification(streamer.DisplayName, "https://twitch.tv/" + streamer.UserName, streamer.ProfileImage, x.ThumbnailImg, x.Title);
|
Notification.GetInstance().sendNotification(streamer.DisplayName, "https://twitch.tv/" + streamer.UserName, streamer.ProfileImage, x.ThumbnailImg, x.Title);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
currentlyLive = following.Data;
|
currentlyLive = following.Data;
|
||||||
}catch(System.Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify");
|
|
||||||
}
|
}
|
||||||
}
|
catch (TwitcherRefreshException ex)
|
||||||
|
{
|
||||||
|
OpenFailedNotification();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.GetInstance().Writer.WriteLineAsync(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Refresh()
|
public void Refresh()
|
||||||
{
|
{
|
||||||
Dictionary<string, string> postData = new Dictionary<string, string>();
|
try
|
||||||
|
{
|
||||||
|
Dictionary<string, string> postData = new Dictionary<string, string>();
|
||||||
|
|
||||||
postData["client_id"] = TwitchDetails.TwitchClientID;
|
postData["client_id"] = TwitchDetails.TwitchClientID;
|
||||||
postData["client_secret"] = TwitchDetails.TwitchClientSecret;
|
postData["client_secret"] = TwitchDetails.TwitchClientSecret;
|
||||||
postData["grant_type"] = "refresh_token";
|
postData["grant_type"] = "refresh_token";
|
||||||
postData["refresh_token"] = DataStore.GetInstance().Store.Authentication.RefreshToken;
|
postData["refresh_token"] = DataStore.GetInstance().Store.Authentication.RefreshToken;
|
||||||
|
|
||||||
byte[] byteArray = buildPostData(postData);
|
byte[] byteArray = buildPostData(postData);
|
||||||
|
|
||||||
WebRequest request = WebRequest.Create("https://id.twitch.tv/oauth2/token");
|
WebRequest request = WebRequest.Create("https://id.twitch.tv/oauth2/token");
|
||||||
request.Method = "POST";
|
request.Method = "POST";
|
||||||
request.ContentType = "application/x-www-form-urlencoded";
|
request.ContentType = "application/x-www-form-urlencoded";
|
||||||
request.ContentLength = byteArray.Length;
|
request.ContentLength = byteArray.Length;
|
||||||
Stream dataStream = request.GetRequestStream();
|
Stream dataStream = request.GetRequestStream();
|
||||||
dataStream.Write(byteArray, 0, byteArray.Length);
|
dataStream.Write(byteArray, 0, byteArray.Length);
|
||||||
dataStream.Close();
|
dataStream.Close();
|
||||||
WebResponse response = request.GetResponse();
|
WebResponse response = request.GetResponse();
|
||||||
dataStream = response.GetResponseStream();
|
dataStream = response.GetResponseStream();
|
||||||
StreamReader reader = new StreamReader(dataStream);
|
StreamReader reader = new StreamReader(dataStream);
|
||||||
string responseFromServer = reader.ReadToEnd();
|
string responseFromServer = reader.ReadToEnd();
|
||||||
reader.Close();
|
reader.Close();
|
||||||
dataStream.Close();
|
dataStream.Close();
|
||||||
response.Close();
|
response.Close();
|
||||||
|
|
||||||
DataStore.GetInstance().Store.Authentication = JsonSerializer.Deserialize<Authentication>(responseFromServer);
|
DataStore.GetInstance().Store.Authentication = JsonSerializer.Deserialize<Authentication>(responseFromServer);
|
||||||
DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc);
|
DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc);
|
||||||
DataStore.GetInstance().Store.Authentication.ExpiresAt = (long)Math.Floor((DateTime.Now.AddSeconds(DataStore.GetInstance().Store.Authentication.ExpiresSeconds) - unixStart).TotalMilliseconds);
|
DataStore.GetInstance().Store.Authentication.ExpiresAt = (long)Math.Floor((DateTime.Now.AddSeconds(DataStore.GetInstance().Store.Authentication.ExpiresSeconds) - unixStart).TotalMilliseconds);
|
||||||
DataStore.GetInstance().Save();
|
DataStore.GetInstance().Save();
|
||||||
|
}catch(Exception e)
|
||||||
|
{
|
||||||
|
throw new TwitcherRefreshException("Unable to refresh", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async public void BeginConnection()
|
async public void BeginConnection()
|
||||||
|
|||||||
69
TwitchDesktopNotifications/Core/UIStreamer.cs
Normal file
69
TwitchDesktopNotifications/Core/UIStreamer.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
|
||||||
|
namespace TwitchDesktopNotifications.Core
|
||||||
|
{
|
||||||
|
public class UIStreamer
|
||||||
|
{
|
||||||
|
public UIStreamer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UIStreamer GetCreateStreamer(string name)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (DataStore.GetInstance().Store.SteamersToIgnore == null)
|
||||||
|
{
|
||||||
|
DataStore.GetInstance().Store.SteamersToIgnore = new JsonStructure.SteamersToIgnore();
|
||||||
|
}
|
||||||
|
if (DataStore.GetInstance().Store.SteamersToIgnore.Streamers == null)
|
||||||
|
{
|
||||||
|
DataStore.GetInstance().Store.SteamersToIgnore.Streamers = new List<UIStreamer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
UIStreamer strmr = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
strmr = DataStore.GetInstance().Store.SteamersToIgnore.Streamers.Where((UIStreamer strmr) => strmr.Name == name).First();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
|
||||||
|
if (strmr == null)
|
||||||
|
{
|
||||||
|
strmr = new UIStreamer() { IsIgnored = false, Name = name };
|
||||||
|
DataStore.GetInstance().Store.SteamersToIgnore.Streamers.Add(strmr);
|
||||||
|
DataStore.GetInstance().Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strmr;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public List<UIStreamer> StreamersToIgnore
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return DataStore.GetInstance().Store.SteamersToIgnore.Streamers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[JsonPropertyName("IsIgnored")]
|
||||||
|
public bool IsIgnored { get; set; } = false;
|
||||||
|
[JsonPropertyName("StreamerName")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string Link {
|
||||||
|
get {
|
||||||
|
return String.Format("https://www.twitch.tv/{0}", Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,23 +5,12 @@ using System.IO;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.Core
|
namespace TwitchDesktopNotifications.Core
|
||||||
{
|
{
|
||||||
internal class WebServer
|
public class WebServer : SingletonFactory<WebServer>, Singleton
|
||||||
{
|
{
|
||||||
public int Port = 32584;
|
public int Port = 32584;
|
||||||
|
|
||||||
private HttpListener listener;
|
private HttpListener listener;
|
||||||
|
|
||||||
private static WebServer Instance;
|
|
||||||
|
|
||||||
public static WebServer GetInstance()
|
|
||||||
{
|
|
||||||
if(Instance == null)
|
|
||||||
{
|
|
||||||
Instance= new WebServer();
|
|
||||||
}
|
|
||||||
return Instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String TwitchCode { get; private set; }
|
public String TwitchCode { get; private set; }
|
||||||
public String TwitchState { get; set; }
|
public String TwitchState { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using TwitchDesktopNotifications.JsonStructure;
|
using TwitchDesktopNotifications.JsonStructure;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using TwitchDesktopNotifications.Core;
|
||||||
|
|
||||||
namespace TwitchDesktopNotifications
|
namespace TwitchDesktopNotifications
|
||||||
{
|
{
|
||||||
internal class DataStore
|
public class DataStore : SingletonFactory<DataStore>, Singleton
|
||||||
{
|
{
|
||||||
private DataStore() { }
|
|
||||||
|
|
||||||
public static DataStore Instance { get; private set; }
|
|
||||||
private Store _store;
|
private Store _store;
|
||||||
public JsonStructure.Store Store {
|
public JsonStructure.Store Store {
|
||||||
get {
|
get {
|
||||||
@@ -25,15 +23,6 @@ namespace TwitchDesktopNotifications
|
|||||||
|
|
||||||
public bool isLoaded { get; private set; }
|
public bool isLoaded { get; private set; }
|
||||||
|
|
||||||
public static DataStore GetInstance()
|
|
||||||
{
|
|
||||||
if(Instance == null)
|
|
||||||
{
|
|
||||||
Instance = new DataStore();
|
|
||||||
}
|
|
||||||
return Instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
|
String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
|
||||||
@@ -41,29 +30,30 @@ namespace TwitchDesktopNotifications
|
|||||||
|
|
||||||
string fileContent = JsonSerializer.Serialize<JsonStructure.Store>(Store);
|
string fileContent = JsonSerializer.Serialize<JsonStructure.Store>(Store);
|
||||||
|
|
||||||
Console.WriteLine("I'm trying to save:");
|
|
||||||
Console.WriteLine(fileContent);
|
|
||||||
Console.WriteLine("to {0}", FilePath + "/" + FileName);
|
|
||||||
Directory.CreateDirectory(FilePath);
|
Directory.CreateDirectory(FilePath);
|
||||||
File.WriteAllText(FilePath + "/" + FileName, fileContent);
|
File.WriteAllText(FilePath + "/" + FileName, fileContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Load() {
|
public void Load() {
|
||||||
String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
|
if (!isLoaded)
|
||||||
String FileName = "store.json";
|
|
||||||
|
|
||||||
Directory.CreateDirectory(FilePath);
|
|
||||||
|
|
||||||
if(File.Exists(FilePath+"/"+ FileName)) {
|
|
||||||
|
|
||||||
string fileContent = File.ReadAllText(FilePath+"/"+ FileName);
|
|
||||||
Store = JsonSerializer.Deserialize<JsonStructure.Store>(fileContent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Store = new JsonStructure.Store();
|
String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
|
||||||
|
String FileName = "store.json";
|
||||||
|
|
||||||
|
Directory.CreateDirectory(FilePath);
|
||||||
|
|
||||||
|
if (File.Exists(FilePath + "/" + FileName))
|
||||||
|
{
|
||||||
|
|
||||||
|
string fileContent = File.ReadAllText(FilePath + "/" + FileName);
|
||||||
|
Store = JsonSerializer.Deserialize<JsonStructure.Store>(fileContent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Store = new JsonStructure.Store();
|
||||||
|
}
|
||||||
|
isLoaded = true;
|
||||||
}
|
}
|
||||||
isLoaded= true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure
|
namespace TwitchDesktopNotifications.JsonStructure
|
||||||
{
|
{
|
||||||
internal class Authentication
|
public class Authentication
|
||||||
{
|
{
|
||||||
[JsonPropertyName("access_token")]
|
[JsonPropertyName("access_token")]
|
||||||
public string AccessToken { get; set; }
|
public string AccessToken { get; set; }
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
||||||
{
|
{
|
||||||
internal class Pagination
|
public class Pagination
|
||||||
{
|
{
|
||||||
public Pagination() { }
|
public Pagination() { }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
||||||
{
|
{
|
||||||
internal class Streams
|
public class Streams
|
||||||
{
|
{
|
||||||
public Streams() { }
|
public Streams() { }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
||||||
{
|
{
|
||||||
internal class StreamsData
|
public class StreamsData
|
||||||
{
|
{
|
||||||
public StreamsData() { }
|
public StreamsData() { }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
||||||
{
|
{
|
||||||
internal class User
|
public class User
|
||||||
{
|
{
|
||||||
public User() { }
|
public User() { }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
||||||
{
|
{
|
||||||
internal class UserData
|
public class UserData
|
||||||
{
|
{
|
||||||
public UserData() { }
|
public UserData() { }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
||||||
{
|
{
|
||||||
internal class UserFollows
|
public class UserFollows
|
||||||
{
|
{
|
||||||
public UserFollows() { }
|
public UserFollows() { }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
namespace TwitchDesktopNotifications.JsonStructure.Helix
|
||||||
{
|
{
|
||||||
internal class UsersFollowsData
|
public class UsersFollowsData
|
||||||
{
|
{
|
||||||
public UsersFollowsData() { }
|
public UsersFollowsData() { }
|
||||||
|
|
||||||
|
|||||||
11
TwitchDesktopNotifications/JsonStructure/SteamersToIgnore.cs
Normal file
11
TwitchDesktopNotifications/JsonStructure/SteamersToIgnore.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using TwitchDesktopNotifications.Core;
|
||||||
|
|
||||||
|
namespace TwitchDesktopNotifications.JsonStructure
|
||||||
|
{
|
||||||
|
public class SteamersToIgnore
|
||||||
|
{
|
||||||
|
[JsonPropertyName("IgnoredStreamers")]
|
||||||
|
public List<UIStreamer> Streamers { get; set; } = new List<UIStreamer>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,14 +8,28 @@ using TwitchDesktopNotifications.JsonStructure.Helix;
|
|||||||
|
|
||||||
namespace TwitchDesktopNotifications.JsonStructure
|
namespace TwitchDesktopNotifications.JsonStructure
|
||||||
{
|
{
|
||||||
internal class Store
|
public class Store
|
||||||
{
|
{
|
||||||
public Store() { }
|
public Store() { }
|
||||||
|
|
||||||
|
[JsonPropertyName("ignore")]
|
||||||
|
public SteamersToIgnore ignore { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("authentication")]
|
[JsonPropertyName("authentication")]
|
||||||
public Authentication Authentication { get; set; }
|
public Authentication Authentication { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("user_data")]
|
[JsonPropertyName("user_data")]
|
||||||
public UserData UserData { get; set; }
|
public UserData UserData { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public SteamersToIgnore SteamersToIgnore {
|
||||||
|
get {
|
||||||
|
if(ignore == null) { ignore = new SteamersToIgnore(); }
|
||||||
|
return ignore;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
ignore = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
224
TwitchDesktopNotifications/Lisence.rtf
Normal file
224
TwitchDesktopNotifications/Lisence.rtf
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang2057\deflangfe2057\themelang2057\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}
|
||||||
|
{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||||
|
{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
|
||||||
|
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||||
|
{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
|
||||||
|
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f43\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f44\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||||
|
{\f46\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f47\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f48\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f49\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||||
|
{\f50\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f51\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f413\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f414\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
|
||||||
|
{\f416\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f417\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f418\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f419\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}
|
||||||
|
{\f420\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f421\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
|
||||||
|
{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||||
|
{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||||
|
{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||||
|
{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||||
|
{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||||
|
{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}
|
||||||
|
{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}
|
||||||
|
{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
|
||||||
|
{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||||
|
{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||||
|
{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||||
|
{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||||
|
{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||||
|
{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
|
||||||
|
{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||||
|
{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}
|
||||||
|
{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
|
||||||
|
{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
|
||||||
|
{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||||
|
{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||||
|
{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}
|
||||||
|
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
|
||||||
|
\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap
|
||||||
|
\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1
|
||||||
|
\af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
|
||||||
|
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
|
||||||
|
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext11 \ssemihidden \sunhideused
|
||||||
|
Normal Table;}}{\*\rsidtbl \rsid5513512\rsid15873127}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator Martin Barker}{\creatim\yr2023\mo2\dy23\hr20\min51}
|
||||||
|
{\revtim\yr2023\mo2\dy23\hr20\min52}{\version2}{\edmins1}{\nofpages1}{\nofwords169}{\nofchars907}{\nofcharsws1058}{\vern65}}{\*\userprops {\propname GrammarlyDocumentId}\proptype30{\staticval 7fca5dcf58e26f86e2af1a1c8daec913dd8ead382b463301162ecfe97ee9703
|
||||||
|
3}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
|
||||||
|
\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701
|
||||||
|
\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot15873127 \nouicompat \fet0{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1
|
||||||
|
\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5
|
||||||
|
\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
|
||||||
|
{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
|
||||||
|
\fs22\lang2057\langfe2057\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 MIT License
|
||||||
|
\par \hich\af37\dbch\af31505\loch\f37 Copyright (c) 2023 Martin Barker (Keatran)
|
||||||
|
\par \hich\af37\dbch\af31505\loch\f37 Permission is hereby granted, free of charge, to any person obtaining a copy}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 of this software and associated documentation files (the "Software"), to deal}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid15873127
|
||||||
|
\hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 in the Software without restriction, including without limitation the rights}{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 copies of the Software, and\hich\af37\dbch\af31505\loch\f37 to permit persons to whom the Software is}{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 furnished to do so, subject to the following conditions:
|
||||||
|
\par \hich\af37\dbch\af31505\loch\f37 The above copyright notice and this permission notice shall be included in all}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 copies or substantial portions of the Software.
|
||||||
|
\par \hich\af37\dbch\af31505\loch\f37 THE SOFTWARE IS PROVIDED "A\hich\af37\dbch\af31505\loch\f37 S IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{
|
||||||
|
\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,}{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAG\hich\af37\dbch\af31505\loch\f37 ES OR OTHER}{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid15873127 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
|
||||||
|
\f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid15873127
|
||||||
|
\hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512 \hich\af37\dbch\af31505\loch\f37 SOFTWARE.}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe2057\langnp9\insrsid5513512
|
||||||
|
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
|
||||||
|
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
|
||||||
|
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
|
||||||
|
b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
|
||||||
|
0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
|
||||||
|
a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
|
||||||
|
c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
|
||||||
|
0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
|
||||||
|
a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
|
||||||
|
6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
|
||||||
|
4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
|
||||||
|
4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100b6f4679893070000c9200000160000007468656d652f7468656d652f
|
||||||
|
7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f2a24fcfda33b6b164873dd648a5eef2547789aad28cc56208de532e81c026e49085bd
|
||||||
|
ed21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c99e191c3061463074977eefd5afde7bf5de53d5ddcf5e26d4bbc05c1096f6fcfa9d9aefe174ce16248d
|
||||||
|
7afeb3d9a4d2f13d2151ba4094a5b8e76fb0f03fbbf7eb5fdd454732c609f6403e1547a8e7c752ae8eaa5531876124eeb0154ee1bb25e30992f0caa3ea82a34b
|
||||||
|
d09bd06aa3566b55134452df4b51026a1f2f97648ebd9952e9dfdb2a1f53784da5500373caa74a35b6243476715e5708b11143cabd0b447b3eccb3609733fc52
|
||||||
|
fa1e4542c2173dbfa6fffceabdbb5574940b517940d6909be8bf5c2e17589c37f49c3c3a2b260d823068f50bfd1a40e53e6edc1eb7c6ad429f06a0f91c569a71
|
||||||
|
b175b61bc320c71aa0ecd1a17bd41e35eb16ded0dfdce3dc0fd5c7c26b50a63fd8c34f2643b0a285d7a00c1feee1c3417730b2f56b50866fede1dbb5fe28685b
|
||||||
|
fa3528a6243ddf43d7c25673b85d6d0159327aec8477c360d26ee4ca4b144443115d6a8a254be5a1584bd00bc6270050408a24493db959e1259a43140f112567
|
||||||
|
9c7827248a21f056286502866b8ddaa4d684ffea13e827ed5174849121ad780113b137a4f87862cec94af6fc07a0d537206f7ffef9cdeb1fdfbcfee9cd575fbd
|
||||||
|
79fdf77c6eadca923b466964cafdf2dd1ffef3cd6fbd7ffff0ed2f5fff319b7a172f4cfcbbbffdeedd3ffef93ef5b0e2d2146ffff4fdbb1fbf7ffbe7dfffebaf
|
||||||
|
5f3bb4f7393a33e1339260e13dc297de5396c0021dfcf119bf9ec42c46c494e8a791402952b338f48f656ca11f6d10450edc00db767cce21d5b880f7d72f2cc2
|
||||||
|
d398af2571687c182716f094313a60dc6985876a2ec3ccb3751ab927e76b13f714a10bd7dc43945a5e1eaf579063894be530c616cd2714a5124538c5d253dfb1
|
||||||
|
738c1dabfb8210cbaea764ce99604be97d41bc01224e93ccc899154da5d03149c02f1b1741f0b7659bd3e7de8051d7aa47f8c246c2de40d4417e86a965c6fb68
|
||||||
|
2d51e252394309350d7e8264ec2239ddf0b9891b0b099e8e3065de78818570c93ce6b05ec3e90f21cdb8dd7e4a37898de4929cbb749e20c64ce4889d0f6394ac
|
||||||
|
5cd829496313fbb938871045de13265df05366ef10f50e7e40e941773f27d872f787b3c133c8b026a53240d4376beef0e57dccacf89d6ee8126157aae9f3c44a
|
||||||
|
b17d4e9cd131584756689f604cd1255a60ec3dfbdcc160c05696cd4bd20f62c82ac7d815580f901dabea3dc5027a25d5dcece7c91322ac909de2881de073bad9
|
||||||
|
493c1b9426881fd2fc08bc6eda7c0ca52e7105c0633a3f37818f08f480102f4ea33c16a0c308ee835a9fc4c82a60ea5db8e375c32dff5d658fc1be7c61d1b8c2
|
||||||
|
be04197c6d1948eca6cc7b6d3343d49aa00c9819822ec3956e41c4727f29a28aab165b3be596f6a62ddd00dd91d5f42424fd6007b4d3fb84ffbbde073a8cb77f
|
||||||
|
f9c6b10f3e4ebfe3566c25ab6b763a8792c9f14e7f7308b7dbd50c195f904fbfa919a175fa04431dd9cf58b73dcd6d4fe3ffdff73487f6f36d2773a8dfb8ed64
|
||||||
|
7ce8306e3b99fc70e5e3743265f3027d8d3af0c80e7af4b14f72f0d46749289dca0dc527421ffc08f83db398c0a092d3279eb838055cc5f0a8ca1c4c60e1228e
|
||||||
|
b48cc799fc0d91f134462b381daafb4a492472d591f0564cc0a1911e76ea5678ba4e4ed9223becacd7d5c16656590592e5782d2cc6e1a04a66e856bb3cc02bd4
|
||||||
|
6bb6913e68dd1250b2d721614c6693683a48b4b783ca48fa58178ce620a157f65158741d2c3a4afdd6557b2c805ae115f8c1edc1cff49e1f06200242701e07cd
|
||||||
|
f942f92973f5d6bbda991fd3d3878c69450034d8db08283ddd555c0f2e4fad2e0bb52b78da2261849b4d425b46377822869fc17974aad1abd0b8aeafbba54b2d
|
||||||
|
7aca147a3e08ad9246bbf33e1637f535c8ede6069a9a9982a6de65cf6f35430899395af5fc251c1ac363b282d811ea3717a211dcbccc25cf36fc4d32cb8a0b39
|
||||||
|
4222ce0cae934e960d122231f728497abe5a7ee1069aea1ca2b9d51b90103e59725d482b9f1a3970baed64bc5ce2b934dd6e8c284b67af90e1b35ce1fc568bdf
|
||||||
|
1cac24d91adc3d8d1797de195df3a708422c6cd795011744c0dd413db3e682c0655891c8caf8db294c79da356fa3740c65e388ae62945714339967709dca0b3a
|
||||||
|
faadb081f196af190c6a98242f8467912ab0a651ad6a5a548d8cc3c1aafb6121653923699635d3ca2aaa6abab39835c3b60cecd8f26645de60b53531e434b3c2
|
||||||
|
67a97b37e576b7b96ea74f28aa0418bcb09fa3ea5ea12018d4cac92c6a8af17e1a56393b1fb56bc776811fa07695226164fdd656ed8edd8a1ae19c0e066f54f9
|
||||||
|
416e376a6168b9ed2bb5a5f5adb979b1cdce5e40f2184197bba6526857c2c92e47d0104d754f92a50dd8222f65be35e0c95b73d2f3bfac85fd60d80887955a27
|
||||||
|
1c57826650ab74c27eb3d20fc3667d1cd66ba341e31514161927f530bbb19fc00506dde4f7f67a7cefee3ed9ded1dc99b3a4caf4dd7c5513d777f7f5c6e1bb7b
|
||||||
|
8f40d2f9b2d598749bdd41abd26df627956034e854bac3d6a0326a0ddba3c9681876ba9357be77a1c141bf390c5ae34ea5551f0e2b41aba6e877ba9576d068f4
|
||||||
|
8376bf330efaaff23606569ea58fdc16605ecdebde7f010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65
|
||||||
|
2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36
|
||||||
|
3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e
|
||||||
|
3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985
|
||||||
|
0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000000000
|
||||||
|
0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000
|
||||||
|
000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019020000
|
||||||
|
7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100b6f4679893070000c92000001600000000000000
|
||||||
|
000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000
|
||||||
|
000000000000000000009d0a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980b00000000}
|
||||||
|
{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
|
||||||
|
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
|
||||||
|
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
|
||||||
|
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
|
||||||
|
{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
|
||||||
|
\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Table;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text;
|
||||||
|
\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;
|
||||||
|
\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;
|
||||||
|
\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1;
|
||||||
|
\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision;
|
||||||
|
\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;
|
||||||
|
\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1;
|
||||||
|
\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;
|
||||||
|
\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;
|
||||||
|
\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;
|
||||||
|
\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;
|
||||||
|
\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;
|
||||||
|
\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;
|
||||||
|
\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;
|
||||||
|
\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;
|
||||||
|
\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;
|
||||||
|
\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
|
||||||
|
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
|
||||||
|
\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
|
||||||
|
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
|
||||||
|
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
|
||||||
|
\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
|
||||||
|
\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
|
||||||
|
\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
|
||||||
|
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
|
||||||
|
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
|
||||||
|
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
|
||||||
|
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
|
||||||
|
\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
|
||||||
|
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
|
||||||
|
\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
|
||||||
|
\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
|
||||||
|
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
|
||||||
|
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
|
||||||
|
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
|
||||||
|
\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
|
||||||
|
\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
|
||||||
|
\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
|
||||||
|
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
|
||||||
|
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
|
||||||
|
\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
|
||||||
|
\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
|
||||||
|
\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
|
||||||
|
\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
|
||||||
|
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
|
||||||
|
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
|
||||||
|
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
|
||||||
|
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000
|
||||||
|
02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
|
||||||
|
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e50000000000000000000000006030
|
||||||
|
20b4c847d901feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
|
||||||
|
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
|
||||||
|
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
|
||||||
|
0000000000000000000000000000000000000000000000000105000000000000}}
|
||||||
106
TwitchDesktopNotifications/ManageIgnores.xaml
Normal file
106
TwitchDesktopNotifications/ManageIgnores.xaml
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
<Window x:Class="TwitchDesktopNotifications.ManageIgnores"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:local="clr-namespace:TwitchDesktopNotifications"
|
||||||
|
xmlns:core="clr-namespace:TwitchDesktopNotifications.Core"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="Twitchy: Ignored Streamers" Height="435" Width="395" ResizeMode="CanResizeWithGrip" Background="#FF333333">
|
||||||
|
<Window.DataContext>
|
||||||
|
<core:UIStreamer />
|
||||||
|
</Window.DataContext>
|
||||||
|
<Window.Resources>
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="GotFocusColor" Color="#FF333333" />
|
||||||
|
<SolidColorBrush x:Key="LostFocusColor" Color="#FF333333" />
|
||||||
|
|
||||||
|
<Style TargetType="{x:Type DataGridColumnHeader}">
|
||||||
|
<Setter Property="Foreground" Value="#FFB3B3B3"/>
|
||||||
|
<Setter Property="Background" Value="#FF333333"/>
|
||||||
|
<Setter Property="Height" Value="25"/>
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="{x:Type DataGridRow}">
|
||||||
|
<Setter Property="Foreground" Value="#FFB3B3B3"/>
|
||||||
|
<Setter Property="Height" Value="25"/>
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsSelected" Value="True">
|
||||||
|
<Setter Property="Background" Value="#FF262626"/>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
|
||||||
|
<Setter Property="Background" Value="#FF383838"/>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
|
||||||
|
<Setter Property="Background" Value="#FF333333"/>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<EventTrigger RoutedEvent="DataGrid.GotFocus">
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource GotFocusColor}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</EventTrigger>
|
||||||
|
|
||||||
|
<EventTrigger RoutedEvent="DataGrid.LostFocus">
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource LostFocusColor}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</EventTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Window.Resources>
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="10" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="10" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="10" />
|
||||||
|
<RowDefinition Height="30" />
|
||||||
|
<RowDefinition Height="10" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="10" />
|
||||||
|
<RowDefinition Height="25" />
|
||||||
|
<RowDefinition Height="10" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<DataGrid
|
||||||
|
Grid.Column="1"
|
||||||
|
Grid.RowSpan="1" Grid.Row="3"
|
||||||
|
CanUserResizeColumns="False"
|
||||||
|
x:Name="dgrdIgnore" ItemsSource="{Binding StreamersToIgnore}" AutoGenerateColumns="False" CanUserAddRows="False" RowHeaderWidth="0" HeadersVisibility="Column" Background="#FF333333" BorderBrush="#FF333333">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridCheckBoxColumn Header="Ignore" Binding="{Binding IsIgnored}" IsReadOnly="False" Width="50">
|
||||||
|
</DataGridCheckBoxColumn>
|
||||||
|
<DataGridTextColumn Header="Streamer Name" Binding="{Binding Name}" IsReadOnly="True" />
|
||||||
|
<DataGridHyperlinkColumn Header="Streamer Link" Binding="{Binding Link}" Width="*">
|
||||||
|
<DataGridHyperlinkColumn.ElementStyle>
|
||||||
|
<Style TargetType="TextBlock">
|
||||||
|
<EventSetter Event="Hyperlink.Click" Handler="HyperLink_Click"/>
|
||||||
|
</Style>
|
||||||
|
</DataGridHyperlinkColumn.ElementStyle>
|
||||||
|
</DataGridHyperlinkColumn>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
<DataGrid.Resources>
|
||||||
|
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
|
||||||
|
Color="#FFF"/>
|
||||||
|
<SolidColorBrush Color="#000" x:Key="{x:Static SystemColors.HighlightTextBrushKey}" />
|
||||||
|
</DataGrid.Resources>
|
||||||
|
</DataGrid>
|
||||||
|
<Button Content="Close" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Width="100" Grid.Row="5" Click="CloseBtn_Click" Background="#FF878788" Foreground="#FF391265" />
|
||||||
|
<TextBlock Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" Text="Changes to the ignore list are automatically saved." VerticalAlignment="Top" Foreground="#FFF9F6F6"/>
|
||||||
|
<TextBlock Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" Text="If you can't see a streamer Twitch Notify has not seen them." VerticalAlignment="Bottom" Foreground="#FFF9F6F6"/>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
98
TwitchDesktopNotifications/ManageIgnores.xaml.cs
Normal file
98
TwitchDesktopNotifications/ManageIgnores.xaml.cs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Windows.Interop;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
using TwitchDesktopNotifications.Core;
|
||||||
|
|
||||||
|
namespace TwitchDesktopNotifications
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for ManageIgnores.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class ManageIgnores : Window
|
||||||
|
{
|
||||||
|
public enum DWMWINDOWATTRIBUTE
|
||||||
|
{
|
||||||
|
DWMWA_NCRENDERING_ENABLED,
|
||||||
|
DWMWA_NCRENDERING_POLICY,
|
||||||
|
DWMWA_TRANSITIONS_FORCEDISABLED,
|
||||||
|
DWMWA_ALLOW_NCPAINT,
|
||||||
|
DWMWA_CAPTION_BUTTON_BOUNDS,
|
||||||
|
DWMWA_NONCLIENT_RTL_LAYOUT,
|
||||||
|
DWMWA_FORCE_ICONIC_REPRESENTATION,
|
||||||
|
DWMWA_FLIP3D_POLICY,
|
||||||
|
DWMWA_EXTENDED_FRAME_BOUNDS,
|
||||||
|
DWMWA_HAS_ICONIC_BITMAP,
|
||||||
|
DWMWA_DISALLOW_PEEK,
|
||||||
|
DWMWA_EXCLUDED_FROM_PEEK,
|
||||||
|
DWMWA_CLOAK,
|
||||||
|
DWMWA_CLOAKED,
|
||||||
|
DWMWA_FREEZE_REPRESENTATION,
|
||||||
|
DWMWA_PASSIVE_UPDATE_MODE,
|
||||||
|
DWMWA_USE_HOSTBACKDROPBRUSH,
|
||||||
|
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
|
||||||
|
DWMWA_WINDOW_CORNER_PREFERENCE = 33,
|
||||||
|
DWMWA_BORDER_COLOR,
|
||||||
|
DWMWA_CAPTION_COLOR,
|
||||||
|
DWMWA_TEXT_COLOR,
|
||||||
|
DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
|
||||||
|
DWMWA_SYSTEMBACKDROP_TYPE,
|
||||||
|
DWMWA_LAST
|
||||||
|
}
|
||||||
|
|
||||||
|
// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
|
||||||
|
// what value of the enum to set.
|
||||||
|
public enum DWM_WINDOW_CORNER_PREFERENCE
|
||||||
|
{
|
||||||
|
DWMWCP_DEFAULT = 0,
|
||||||
|
DWMWCP_DONOTROUND = 1,
|
||||||
|
DWMWCP_ROUND = 2,
|
||||||
|
DWMWCP_ROUNDSMALL = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
|
||||||
|
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
private static extern long DwmSetWindowAttribute(IntPtr hwnd,
|
||||||
|
DWMWINDOWATTRIBUTE attribute,
|
||||||
|
ref uint pvAttribute,
|
||||||
|
uint cbAttribute);
|
||||||
|
|
||||||
|
public ManageIgnores()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
|
||||||
|
var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
|
||||||
|
uint preference = 2;
|
||||||
|
DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));
|
||||||
|
|
||||||
|
var attribute2 = DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE;
|
||||||
|
uint colour = 1;
|
||||||
|
DwmSetWindowAttribute(hWnd, attribute2, ref colour, sizeof(uint));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UIStreamer> StreamersToIgnore = DataStore.GetInstance().Store.SteamersToIgnore.Streamers;
|
||||||
|
|
||||||
|
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HyperLink_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
string link = ((Hyperlink)e.OriginalSource).NavigateUri.OriginalString;
|
||||||
|
|
||||||
|
var psi = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = link,
|
||||||
|
UseShellExecute = true
|
||||||
|
};
|
||||||
|
Process.Start(psi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
// See https://aka.ms/new-console-template for more information
|
// See https://aka.ms/new-console-template for more information
|
||||||
|
using Microsoft.Toolkit.Uwp.Notifications;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Forms;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using System.Threading;
|
||||||
using TwitchDesktopNotifications;
|
using TwitchDesktopNotifications;
|
||||||
using TwitchDesktopNotifications.Core;
|
using TwitchDesktopNotifications.Core;
|
||||||
using TwitchDesktopNotifications.JsonStructure;
|
using TwitchDesktopNotifications.JsonStructure;
|
||||||
|
using Windows.UI.Core.Preview;
|
||||||
|
|
||||||
internal class Program
|
internal class Program
|
||||||
{
|
{
|
||||||
@@ -18,6 +20,7 @@ internal class Program
|
|||||||
|
|
||||||
private static NotifyIcon notifyIcon;
|
private static NotifyIcon notifyIcon;
|
||||||
private static ContextMenuStrip cms;
|
private static ContextMenuStrip cms;
|
||||||
|
private static ManageIgnores? manageIgnores;
|
||||||
|
|
||||||
public static void Ws_CodeRecived(object? sender, EventArgs e)
|
public static void Ws_CodeRecived(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@@ -45,6 +48,21 @@ internal class Program
|
|||||||
TriggerAuthentication();
|
TriggerAuthentication();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void ManageIgnores_Click(object? sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
if (manageIgnores == null) {
|
||||||
|
manageIgnores = new ManageIgnores();
|
||||||
|
manageIgnores.Closed += ManageIgnores_Closed;
|
||||||
|
}
|
||||||
|
manageIgnores.Show();
|
||||||
|
manageIgnores.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ManageIgnores_Closed(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
manageIgnores = null;
|
||||||
|
}
|
||||||
|
|
||||||
protected static void Quit_Click(object? sender, System.EventArgs e)
|
protected static void Quit_Click(object? sender, System.EventArgs e)
|
||||||
{
|
{
|
||||||
notifyIcon.Visible = false;
|
notifyIcon.Visible = false;
|
||||||
@@ -62,24 +80,27 @@ internal class Program
|
|||||||
{
|
{
|
||||||
if (isConnecting)
|
if (isConnecting)
|
||||||
{
|
{
|
||||||
MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify");
|
TwitchFetcher.GetInstance().OpenFailedNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[STAThread]
|
||||||
private static async Task Main(string[] args)
|
private static void Main(string[] args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
|
|
||||||
|
|
||||||
notifyIcon = new NotifyIcon();
|
notifyIcon = new NotifyIcon();
|
||||||
notifyIcon.Icon = new Icon("Assets/icon.ico");
|
notifyIcon.Icon = new Icon("Assets/icon.ico");
|
||||||
notifyIcon.Text = "Twitch Notify";
|
notifyIcon.Text = "Twitch Notify";
|
||||||
|
|
||||||
cms = new ContextMenuStrip();
|
cms = new ContextMenuStrip();
|
||||||
|
cms.BackColor = System.Drawing.Color.FromArgb(51, 51, 51);
|
||||||
|
cms.ForeColor = System.Drawing.Color.FromArgb(145, 70, 255);
|
||||||
|
cms.ShowImageMargin= false;
|
||||||
|
cms.Items.Add(new ToolStripMenuItem("Manage Ignores", null, new EventHandler(ManageIgnores_Click)));
|
||||||
|
cms.Items.Add(new ToolStripSeparator());
|
||||||
cms.Items.Add(new ToolStripMenuItem("Reconnect", null, new EventHandler(Reconnect_Click)));
|
cms.Items.Add(new ToolStripMenuItem("Reconnect", null, new EventHandler(Reconnect_Click)));
|
||||||
|
//cms.Items.Add(new ToolStripMenuItem("About", null, new EventHandler(About_Click), "Quit"));
|
||||||
cms.Items.Add(new ToolStripSeparator());
|
cms.Items.Add(new ToolStripSeparator());
|
||||||
cms.Items.Add(new ToolStripMenuItem("Quit", null, new EventHandler(Quit_Click), "Quit"));
|
cms.Items.Add(new ToolStripMenuItem("Quit", null, new EventHandler(Quit_Click), "Quit"));
|
||||||
|
|
||||||
@@ -91,22 +112,23 @@ internal class Program
|
|||||||
TriggerAuthentication();
|
TriggerAuthentication();
|
||||||
}
|
}
|
||||||
|
|
||||||
new Thread(() =>
|
var autoEvent = new AutoResetEvent(false);
|
||||||
{
|
var timer = new System.Threading.Timer((Object? stateInfo) => {
|
||||||
while (true)
|
if (DataStore.GetInstance().Store != null)
|
||||||
{
|
{
|
||||||
Thread.Sleep(10000);
|
TwitchFetcher.GetInstance().GetLiveFollowingUsers();
|
||||||
if (DataStore.GetInstance().Store != null)
|
|
||||||
{
|
|
||||||
TwitchFetcher.GetInstance().GetLiveFollowingUsers();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).Start();
|
}, autoEvent, 1000, 500);
|
||||||
|
|
||||||
|
|
||||||
Application.Run();
|
Application.Run();
|
||||||
|
|
||||||
|
Application.ApplicationExit += (object? sender, EventArgs e) => {
|
||||||
|
ToastNotificationManagerCompat.Uninstall();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
Console.WriteLine(e.ToString());
|
Logger.GetInstance().Writer.WriteLineAsync(e.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
28
TwitchDesktopNotifications/ReconnectionNeeded.xaml
Normal file
28
TwitchDesktopNotifications/ReconnectionNeeded.xaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<Window x:Class="TwitchDesktopNotifications.ReconnectionNeeded"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:local="clr-namespace:TwitchDesktopNotifications"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="Twitchy Disconnected" Height="140" Width="335" x:Name="reconnectionNeededWin" Background="#FF333333">
|
||||||
|
<Grid>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="10" />
|
||||||
|
<ColumnDefinition Width="100" />
|
||||||
|
<ColumnDefinition Width="100" />
|
||||||
|
<ColumnDefinition Width="100" />
|
||||||
|
<ColumnDefinition Width="10" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="10" />
|
||||||
|
<RowDefinition Height="40" />
|
||||||
|
<RowDefinition Height="10" />
|
||||||
|
<RowDefinition Height="40" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock TextWrapping="Wrap" VerticalAlignment="Top" TextAlignment="Center" Text="We have been unable to refresh your twitch connection" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" Foreground="#FFF9F6F6"/>
|
||||||
|
<TextBlock TextWrapping="Wrap" VerticalAlignment="Center" TextAlignment="Center" Text="Don't worry you just need to reconnect" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" Foreground="#FFF9F6F6"/>
|
||||||
|
<Button Content="Thanks" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Column="2" Grid.Row="3" Padding="5" Click="Button_Click" Background="#FF878788" Foreground="#FF391265"/>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
88
TwitchDesktopNotifications/ReconnectionNeeded.xaml.cs
Normal file
88
TwitchDesktopNotifications/ReconnectionNeeded.xaml.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Interop;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace TwitchDesktopNotifications
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for ReconnectionNeeded.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class ReconnectionNeeded : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
public enum DWMWINDOWATTRIBUTE
|
||||||
|
{
|
||||||
|
DWMWA_NCRENDERING_ENABLED,
|
||||||
|
DWMWA_NCRENDERING_POLICY,
|
||||||
|
DWMWA_TRANSITIONS_FORCEDISABLED,
|
||||||
|
DWMWA_ALLOW_NCPAINT,
|
||||||
|
DWMWA_CAPTION_BUTTON_BOUNDS,
|
||||||
|
DWMWA_NONCLIENT_RTL_LAYOUT,
|
||||||
|
DWMWA_FORCE_ICONIC_REPRESENTATION,
|
||||||
|
DWMWA_FLIP3D_POLICY,
|
||||||
|
DWMWA_EXTENDED_FRAME_BOUNDS,
|
||||||
|
DWMWA_HAS_ICONIC_BITMAP,
|
||||||
|
DWMWA_DISALLOW_PEEK,
|
||||||
|
DWMWA_EXCLUDED_FROM_PEEK,
|
||||||
|
DWMWA_CLOAK,
|
||||||
|
DWMWA_CLOAKED,
|
||||||
|
DWMWA_FREEZE_REPRESENTATION,
|
||||||
|
DWMWA_PASSIVE_UPDATE_MODE,
|
||||||
|
DWMWA_USE_HOSTBACKDROPBRUSH,
|
||||||
|
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
|
||||||
|
DWMWA_WINDOW_CORNER_PREFERENCE = 33,
|
||||||
|
DWMWA_BORDER_COLOR,
|
||||||
|
DWMWA_CAPTION_COLOR,
|
||||||
|
DWMWA_TEXT_COLOR,
|
||||||
|
DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
|
||||||
|
DWMWA_SYSTEMBACKDROP_TYPE,
|
||||||
|
DWMWA_LAST
|
||||||
|
}
|
||||||
|
|
||||||
|
// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
|
||||||
|
// what value of the enum to set.
|
||||||
|
public enum DWM_WINDOW_CORNER_PREFERENCE
|
||||||
|
{
|
||||||
|
DWMWCP_DEFAULT = 0,
|
||||||
|
DWMWCP_DONOTROUND = 1,
|
||||||
|
DWMWCP_ROUND = 2,
|
||||||
|
DWMWCP_ROUNDSMALL = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
|
||||||
|
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
private static extern long DwmSetWindowAttribute(IntPtr hwnd,
|
||||||
|
DWMWINDOWATTRIBUTE attribute,
|
||||||
|
ref uint pvAttribute,
|
||||||
|
uint cbAttribute);
|
||||||
|
public ReconnectionNeeded()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
|
||||||
|
var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
|
||||||
|
uint preference = 2;
|
||||||
|
DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));
|
||||||
|
|
||||||
|
var attribute2 = DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE;
|
||||||
|
uint colour = 1;
|
||||||
|
DwmSetWindowAttribute(hWnd, attribute2, ref colour, sizeof(uint));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,12 +6,24 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||||
<PackageId>Twitch Notify</PackageId>
|
<PackageId>Twitchy</PackageId>
|
||||||
<Authors>KeareanGaming</Authors>
|
<Authors>Martin Barker (KeatranGaming)</Authors>
|
||||||
<AssemblyName>Twitch Notify</AssemblyName>
|
<AssemblyName>Twitchy</AssemblyName>
|
||||||
<UseWPF>True</UseWPF>
|
<UseWPF>True</UseWPF>
|
||||||
<UseWindowsForms>True</UseWindowsForms>
|
<UseWindowsForms>True</UseWindowsForms>
|
||||||
<UserSecretsId>2dfb7064-609b-41c3-a80d-a9e4d842a55d</UserSecretsId>
|
<UserSecretsId>2dfb7064-609b-41c3-a80d-a9e4d842a55d</UserSecretsId>
|
||||||
|
<SignAssembly>False</SignAssembly>
|
||||||
|
<Description>Show Windows notifications when your fav streamers go live.</Description>
|
||||||
|
<Copyright>2023 Martin Barker</Copyright>
|
||||||
|
<PackageProjectUrl>https://github.com/barkermn01/TwitchNotify/</PackageProjectUrl>
|
||||||
|
<PackageIcon>twitch.png</PackageIcon>
|
||||||
|
<RepositoryUrl>https://github.com/barkermn01/TwitchNotify/</RepositoryUrl>
|
||||||
|
<RepositoryType>git</RepositoryType>
|
||||||
|
<PackageTags>twitch, notifications</PackageTags>
|
||||||
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
|
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
|
||||||
|
<Configurations>Debug;Release;ReleaseSign</Configurations>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -28,7 +40,19 @@
|
|||||||
</None>
|
</None>
|
||||||
<None Update="Assets\twitch.png">
|
<None Update="Assets\twitch.png">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
<None Update="LICENSE.txt">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="sign.ps1">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
<Exec Command="powershell -command "if('$(ConfigurationName)' -eq 'ReleaseSign'){ cd $(TargetDir); ./sign.ps1}"" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="ManageIgnores.xaml.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="ReconnectionNeeded.xaml.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="ManageIgnores.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Update="ReconnectionNeeded.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
80
TwitchDesktopNotifications/sign.ps1
Normal file
80
TwitchDesktopNotifications/sign.ps1
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#clean up if existing Files
|
||||||
|
if(Test-Path -Path 'Twitchy.zip'){
|
||||||
|
Remove-Item 'Twitchy.zip';
|
||||||
|
}
|
||||||
|
|
||||||
|
# Files to be signed
|
||||||
|
$files = 'Twitchy.exe',
|
||||||
|
'Twitchy.dll';
|
||||||
|
|
||||||
|
#certificate Common Name
|
||||||
|
$cert = "Open Source Developer, MARTIN BARKER";
|
||||||
|
|
||||||
|
# get Operating system drive letter
|
||||||
|
$drive = (Get-WmiObject Win32_OperatingSystem).SystemDrive;
|
||||||
|
|
||||||
|
# setup defaults
|
||||||
|
$progFiles = $drive+"\Program Files";
|
||||||
|
$sdkArch = "x86";
|
||||||
|
|
||||||
|
# Check if this is a 64bit windows or 32 (only 64 bit will have (x86) varient of program files
|
||||||
|
$checkPath = $drive+"\Program Files (x86)\";
|
||||||
|
if(Test-Path -Path $checkPath){
|
||||||
|
"OS Architecture: Detected 64bit Windows"
|
||||||
|
$progFiles = $progFiles + " (x86)\";
|
||||||
|
$sdkArch = "x64";
|
||||||
|
} else {
|
||||||
|
"OS Architecture: Detected 32bit Windows"
|
||||||
|
$progFiles = $progFiles + "\";
|
||||||
|
}
|
||||||
|
|
||||||
|
#Check for the Windows SDK intall
|
||||||
|
$checkPath = $progFiles+"Windows Kits\10\";
|
||||||
|
"Checking for windows 10 SDK";
|
||||||
|
if(Test-Path -Path $checkPath){
|
||||||
|
$win10sdkPath = $progFiles+"Windows Kits\10\bin\";
|
||||||
|
"SDK Path: "+$win10sdkPath;
|
||||||
|
} else {
|
||||||
|
# not found end the script
|
||||||
|
"[Error] Unable to find Windows 10 SDK, is Visual Studios 2019 or newer installed?";
|
||||||
|
Break Script;
|
||||||
|
}
|
||||||
|
|
||||||
|
# get the latest SDK Version Path (ordered by name so latest will be last)
|
||||||
|
Get-ChildItem $win10sdkPath -Filter 10.* |
|
||||||
|
Foreach-Object{
|
||||||
|
# check that this SDK version has signtool
|
||||||
|
$checkPath = $_.FullName+"\"+$sdkArch+"\signtool.exe"
|
||||||
|
if(Test-Path -Path $checkPath){
|
||||||
|
#sign tool found add set this path as comptable
|
||||||
|
$SDKVersionPath = $_.FullName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$SDKVersionPath = $SDKVersionPath+"\"+$sdkArch;
|
||||||
|
# Windows 10 signing system (signtool.exe from Windows 10 SDK)
|
||||||
|
$signPath = $SDKVersionPath+"\signtool.exe";
|
||||||
|
"Signtool Path: "+$SDKVersionPath+"\signtool.exe";
|
||||||
|
|
||||||
|
# create alias to the discovered path so we can invoke with arguments
|
||||||
|
new-alias signtool $signPath;
|
||||||
|
|
||||||
|
# basic aguments for sign tool
|
||||||
|
$appArgs = 'sign',
|
||||||
|
'/fd',
|
||||||
|
'sha256',
|
||||||
|
'/t',
|
||||||
|
'http://timestamp.comodoca.com/authenticode',
|
||||||
|
'/n',
|
||||||
|
$cert;
|
||||||
|
|
||||||
|
# add the files to be signed to the end of the args array
|
||||||
|
$appArgs = $appArgs + $files;
|
||||||
|
|
||||||
|
#run the signtool
|
||||||
|
signtool $appArgs;
|
||||||
|
|
||||||
|
# once files are signed package into zip
|
||||||
|
Get-ChildItem './' | where { $_.Name -notin 'sign.ps1'} | Compress-Archive -DestinationPath 'Twitchy.zip' -Update
|
||||||
|
|
||||||
|
Exit $LASTEXITCODE
|
||||||
BIN
netcorecheck.exe
Normal file
BIN
netcorecheck.exe
Normal file
Binary file not shown.
BIN
netcorecheck_x64.exe
Normal file
BIN
netcorecheck_x64.exe
Normal file
Binary file not shown.
83
setup.iss
Normal file
83
setup.iss
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
; Script generated by the Inno Setup Script Wizard.
|
||||||
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||||
|
|
||||||
|
#define MyAppName "Twitchy"
|
||||||
|
#define MyAppVersion "0.5"
|
||||||
|
#define MyAppExeName "Twitchy.exe"
|
||||||
|
|
||||||
|
#ifndef MyAppTargetFramework
|
||||||
|
#define MyAppTargetFramework "net6.0-windows"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SourceDir
|
||||||
|
#define SourceDir "TwitchDesktopNotifications\bin\Release\net6.0-windows10.0.17763.0\"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define public Dependency_NoExampleSetup
|
||||||
|
#include "CodeDependencies.iss"
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||||
|
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||||
|
AppId={{7774CEEE-6785-48B9-BA35-6B842F947A21}
|
||||||
|
AppName={#MyAppName}
|
||||||
|
AppVersion={#MyAppVersion}
|
||||||
|
DefaultDirName={autopf}\{#MyAppName}
|
||||||
|
DisableProgramGroupPage=yes
|
||||||
|
LicenseFile=.\TwitchDesktopNotifications\Lisence.rtf
|
||||||
|
; Uncomment the following line to run in non administrative install mode (install for current user only.)
|
||||||
|
;PrivilegesRequired=lowest
|
||||||
|
OutputDir=.\SetupFiles
|
||||||
|
OutputBaseFilename=TwitchySetup
|
||||||
|
SetupIconFile=.\TwitchDesktopNotifications\Assets\icon.ico
|
||||||
|
UninstallDisplayIcon=.\TwitchDesktopNotifications\Assets\icon.ico
|
||||||
|
WizardSmallImageFile=.\TwitchDesktopNotifications\Assets\twitch.bmp
|
||||||
|
Compression=lzma
|
||||||
|
SolidCompression=yes
|
||||||
|
WizardStyle=modern
|
||||||
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
|
SignedUninstaller=yes
|
||||||
|
SignTool=signtool
|
||||||
|
SourceDir=.\
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
|
[Tasks]
|
||||||
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||||
|
Name: "autostarticon"; Description: "{cm:AutoStartProgram,{#MyAppName}}"; GroupDescription: "{cm:AdditionalIcons}";
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "{#SourceDir}{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#SourceDir}Microsoft.Toolkit.Uwp.Notifications.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#SourceDir}Microsoft.Windows.SDK.NET.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#SourceDir}Twitchy.deps.json"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#SourceDir}Twitchy.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#SourceDir}Twitchy.runtimeconfig.json"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#SourceDir}WinRT.Runtime.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#SourceDir}Assets\icon.ico"; DestDir: "{app}\Assets"; Flags: ignoreversion
|
||||||
|
Source: "{#SourceDir}Assets\twitch.png"; DestDir: "{app}\Assets"; Flags: ignoreversion
|
||||||
|
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||||
|
Source: "netcorecheck.exe"; Flags: dontcopy noencryption
|
||||||
|
Source: "netcorecheck_x64.exe"; Flags: dontcopy noencryption
|
||||||
|
|
||||||
|
#expr SaveToFile("Preprocessed.iss")
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||||
|
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||||
|
Name: "{commonstartup}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: autostarticon
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: {app}\{cm:AppName}.exe; Description: {cm:LaunchProgram,{cm:AppName}}; Flags: nowait postinstall skipifsilent
|
||||||
|
|
||||||
|
[CustomMessages]
|
||||||
|
AppName=Twitchy
|
||||||
|
LaunchProgram=Start Twitchy after finishing installation
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
function InitializeSetup: Boolean;
|
||||||
|
begin
|
||||||
|
Dependency_AddDotNet60Desktop;
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
Reference in New Issue
Block a user