mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-11 10:07:42 +00:00
feat(windows): kmconfig console app
This app uses the new `TKeymanSettings` class to present a standardised interface for all Keyman settings -- debug, development and compatibility. This is a console app, intended for use in a variety of scenarios, including development tools, in the future. Settings can be set, exported/imported to/from json, reset, shown. Important in this PR is establishing the command line parameter consistency and usage into the future.
This commit is contained in:
parent
1418a0ebc0
commit
aa8fecf385
12 changed files with 1491 additions and 4 deletions
|
|
@ -2,7 +2,7 @@
|
|||
# Keyman Desktop Makefile
|
||||
#
|
||||
|
||||
TARGETS=kmshell kmbrowserhost setup insthelp
|
||||
TARGETS=kmshell kmconfig kmbrowserhost setup insthelp
|
||||
RELEASE_TARGETS=help
|
||||
CLEANS=inst clean-desktop
|
||||
MANIFESTS=kmshell setup insthelp
|
||||
|
|
@ -15,6 +15,10 @@ kmshell:
|
|||
cd $(ROOT)\src\desktop\kmshell
|
||||
$(MAKE) $(TARGET)
|
||||
|
||||
kmconfig:
|
||||
cd $(ROOT)\src\desktop\kmconfig
|
||||
$(MAKE) $(TARGET)
|
||||
|
||||
kmbrowserhost:
|
||||
cd $(ROOT)\src\desktop\kmbrowserhost
|
||||
$(MAKE) $(TARGET)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
<Projects Include="setup\setup.dproj">
|
||||
<Dependencies/>
|
||||
</Projects>
|
||||
<Projects Include="kmconfig\kmconfig.dproj">
|
||||
<Dependencies/>
|
||||
</Projects>
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<Borland.Personality>Default.Personality.12</Borland.Personality>
|
||||
|
|
@ -47,14 +50,23 @@
|
|||
<Target Name="setup:Make">
|
||||
<MSBuild Projects="setup\setup.dproj" Targets="Make"/>
|
||||
</Target>
|
||||
<Target Name="kmconfig">
|
||||
<MSBuild Projects="kmconfig\kmconfig.dproj"/>
|
||||
</Target>
|
||||
<Target Name="kmconfig:Clean">
|
||||
<MSBuild Projects="kmconfig\kmconfig.dproj" Targets="Clean"/>
|
||||
</Target>
|
||||
<Target Name="kmconfig:Make">
|
||||
<MSBuild Projects="kmconfig\kmconfig.dproj" Targets="Make"/>
|
||||
</Target>
|
||||
<Target Name="Build">
|
||||
<CallTarget Targets="kmshell;kmbrowserhost;setup"/>
|
||||
<CallTarget Targets="kmshell;kmbrowserhost;setup;kmconfig"/>
|
||||
</Target>
|
||||
<Target Name="Clean">
|
||||
<CallTarget Targets="kmshell:Clean;kmbrowserhost:Clean;setup:Clean"/>
|
||||
<CallTarget Targets="kmshell:Clean;kmbrowserhost:Clean;setup:Clean;kmconfig:Clean"/>
|
||||
</Target>
|
||||
<Target Name="Make">
|
||||
<CallTarget Targets="kmshell:Make;kmbrowserhost:Make;setup:Make"/>
|
||||
<CallTarget Targets="kmshell:Make;kmbrowserhost:Make;setup:Make;kmconfig:Make"/>
|
||||
</Target>
|
||||
<Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -145,6 +145,10 @@
|
|||
<File Id="kmbrowserhost.exe" Name="kmbrowserhost.exe" KeyPath="yes" />
|
||||
</Component>
|
||||
|
||||
<Component>
|
||||
<File Id="kmconfig.exe" Name="kmconfig.exe" KeyPath="yes" />
|
||||
</Component>
|
||||
|
||||
<Component Id="Reg_RootPath" Guid="*">
|
||||
<RegistryValue KeyPath="yes" Root="HKLM" Key="SOFTWARE\Keyman\Keyman Desktop" Name="root path" Type="string" Value="[INSTALLDIR]" />
|
||||
<RegistryValue Root="HKLM" Key="SOFTWARE\Keyman\Keyman Desktop" Name="version" Type="string" Value="$(var.VERSION)" />
|
||||
|
|
|
|||
333
windows/src/desktop/kmconfig/Keyman.System.KMConfigMain.pas
Normal file
333
windows/src/desktop/kmconfig/Keyman.System.KMConfigMain.pas
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
unit Keyman.System.KMConfigMain;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Keyman.System.Settings;
|
||||
|
||||
type
|
||||
TKMConfig = class
|
||||
private
|
||||
class var IsAdmin: Boolean;
|
||||
class var Settings: TKeymanSettings;
|
||||
class function Import(const Filename: string): Boolean; static;
|
||||
class function Export(const Filename: string): Boolean; static;
|
||||
class function Reset(const ID: string): Boolean; static;
|
||||
class function SetValue(const ID, Value: string): Boolean; static;
|
||||
class function Show(const P2: string): Boolean; static;
|
||||
class procedure Log(const message: string);
|
||||
class procedure LogError(const message: string);
|
||||
class procedure LogWarning(const message: string);
|
||||
public
|
||||
class constructor ClassCreate;
|
||||
class destructor ClassDestroy;
|
||||
class procedure Run; static;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Win.Registry,
|
||||
Winapi.Windows,
|
||||
|
||||
Keyman.System.SettingsManager,
|
||||
Keyman.System.SettingsManagerFile,
|
||||
RegistryKeys;
|
||||
|
||||
type
|
||||
TANSIColor = record
|
||||
Green, Grey, Default, Yellow, Red, White: string;
|
||||
end;
|
||||
|
||||
var
|
||||
ANSIColor: TANSIColor;
|
||||
|
||||
class constructor TKMConfig.ClassCreate;
|
||||
var
|
||||
r: TRegistry;
|
||||
begin
|
||||
inherited;
|
||||
r := TRegistry.Create;
|
||||
try
|
||||
r.RootKey := HKEY_LOCAL_MACHINE;
|
||||
IsAdmin := r.OpenKey(SRegKey_KeymanEngine_LM, True);
|
||||
finally
|
||||
r.Free;
|
||||
end;
|
||||
|
||||
Settings := TKeymanSettings.Create;
|
||||
end;
|
||||
|
||||
class destructor TKMConfig.ClassDestroy;
|
||||
begin
|
||||
Settings.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
class procedure TKMConfig.Run;
|
||||
var
|
||||
Command: string;
|
||||
Result: Boolean;
|
||||
begin
|
||||
Settings := TKeymanSettings.Create;
|
||||
Command := ParamStr(1).ToLower;
|
||||
if Command = 'import' then Result := Import(ParamStr(2))
|
||||
else if Command = 'export' then Result := Export(ParamStr(2))
|
||||
else if Command = 'reset' then Result := Reset(ParamStr(2))
|
||||
else if Command = 'set' then Result := SetValue(ParamStr(2), ParamStr(3))
|
||||
else if Command = 'show' then Result := Show(ParamStr(2))
|
||||
else
|
||||
begin
|
||||
Result := False;
|
||||
writeln('Usage: kmconfig command [options]');
|
||||
writeln('Commands:');
|
||||
writeln(' import <settings.json> Imports settings into local machine registry');
|
||||
writeln(' export <settings.json> Exports settings from local machine registry to file');
|
||||
writeln(' reset [id] Resets one or all settings to default');
|
||||
writeln(' set id value Sets setting identified by id to value');
|
||||
writeln(' show [-a] [id] Lists one or all settings; -a to show all, even empty settings');
|
||||
writeln('Note: registry changes may require elevation to succeed.');
|
||||
end;
|
||||
|
||||
if Result
|
||||
then ExitCode := 0
|
||||
else ExitCode := 1;
|
||||
end;
|
||||
|
||||
class procedure TKMConfig.Log(const message: string);
|
||||
begin
|
||||
writeln(message);
|
||||
end;
|
||||
|
||||
class procedure TKMConfig.LogError(const message: string);
|
||||
begin
|
||||
Log(AnsiColor.Red+'ERROR: '+message+AnsiColor.Default);
|
||||
end;
|
||||
|
||||
class procedure TKMConfig.LogWarning(const message: string);
|
||||
begin
|
||||
Log(AnsiColor.Yellow+'WARNING: '+message+AnsiColor.Default);
|
||||
end;
|
||||
|
||||
class function TKMConfig.Export(const Filename: string): Boolean;
|
||||
begin
|
||||
TKeymanSettingsManager.Load(Settings);
|
||||
TKeymanSettingsManagerFile.Export(Settings, Filename);
|
||||
Log('All Keyman settings have been exported to '+Filename);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
class function TKMConfig.Import(const Filename: string): Boolean;
|
||||
begin
|
||||
TKeymanSettingsManager.Load(Settings);
|
||||
TKeymanSettingsManagerFile.Import(Settings, Filename);
|
||||
TKeymanSettingsManager.Save(Settings, IsAdmin);
|
||||
Log('Keyman settings in '+Filename+' have been imported');
|
||||
if not IsAdmin then
|
||||
LogWarning('Some settings that require Administrator permissions may not have been updated');
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
class function TKMConfig.Reset(const ID: string): Boolean;
|
||||
var
|
||||
Setting: TKeymanSetting;
|
||||
begin
|
||||
if ID = '' then
|
||||
begin
|
||||
Settings.Reset;
|
||||
TKeymanSettingsManager.Load(Settings);
|
||||
if Settings.Modified then
|
||||
begin
|
||||
TKeymanSettingsManager.Save(Settings, IsAdmin);
|
||||
Log('Keyman settings have been reset to default');
|
||||
if not IsAdmin then
|
||||
LogWarning('Some settings that require Administrator permissions may not have been updated');
|
||||
end
|
||||
else
|
||||
begin
|
||||
Log('All Keyman settings were already default');
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
TKeymanSettingsManager.Load(Settings);
|
||||
Setting := Settings.Find(ID);
|
||||
if not Assigned(Setting) then
|
||||
begin
|
||||
// Custom value, do we support it?
|
||||
if ID.StartsWith(CustomKeymanSetting_TSFApp.ID, True) then
|
||||
begin
|
||||
LogWarning('Setting '+ID+' does not exist; not updating.');
|
||||
Exit(True);
|
||||
end
|
||||
else
|
||||
begin
|
||||
LogError('Setting '+ID+' is not a valid Keyman setting.');
|
||||
Exit(False);
|
||||
end;
|
||||
end;
|
||||
if Setting.IsEmpty then
|
||||
begin
|
||||
LogWarning('Setting '+ID+' is already default; not updating.');
|
||||
Exit(True);
|
||||
end;
|
||||
if (Setting.Base.RootKey = HKEY_LOCAL_MACHINE) and not IsAdmin then
|
||||
begin
|
||||
LogError('Setting '+ID+' requires Administrator permissions to update.');
|
||||
Exit(False);
|
||||
end;
|
||||
|
||||
Setting.Reset;
|
||||
if Setting.Modified then
|
||||
begin
|
||||
TKeymanSettingsManager.Save(Settings, IsAdmin);
|
||||
Log('Keyman setting '+ID+' has been reset to default');
|
||||
end
|
||||
else
|
||||
begin
|
||||
LogWarning('Keyman setting '+ID+' was already default; not updating');
|
||||
end;
|
||||
end;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
class function TKMConfig.SetValue(const ID, Value: string): Boolean;
|
||||
var
|
||||
Setting: TKeymanSetting;
|
||||
begin
|
||||
Setting := Settings.Find(ID);
|
||||
|
||||
if not Assigned(Setting) then
|
||||
begin
|
||||
// Custom value, do we support it?
|
||||
if ID.StartsWith(CustomKeymanSetting_TSFApp.ID, True) then
|
||||
begin
|
||||
Setting := TKeymanSetting.CreateCustom_TSFApp(ID);
|
||||
Settings.Add(Setting);
|
||||
end
|
||||
else
|
||||
begin
|
||||
LogError(ID+' is not a valid Keyman setting.');
|
||||
Exit(False);
|
||||
end;
|
||||
end;
|
||||
|
||||
if (Setting.Base.RootKey = HKEY_LOCAL_MACHINE) and not IsAdmin then
|
||||
begin
|
||||
LogError('Setting '+ID+' requires Administrator permissions to update.');
|
||||
Exit(False);
|
||||
end;
|
||||
|
||||
case Setting.Base.ValueType of
|
||||
kstString: Setting.ValueStr := Value;
|
||||
kstInteger: Setting.ValueInt := StrToInt(Value);
|
||||
end;
|
||||
|
||||
TKeymanSettingsManager.Save(Settings, IsAdmin);
|
||||
Log('Keyman setting '+ID+' has been updated to '+Value);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
class function TKMConfig.Show(const P2: string): Boolean;
|
||||
|
||||
function ShowOneSetting(const ID: string): Boolean;
|
||||
var
|
||||
Setting: TKeymanSetting;
|
||||
v: string;
|
||||
begin
|
||||
Setting := Settings.Find(ID);
|
||||
if not Assigned(Setting) then
|
||||
begin
|
||||
LogError('Setting '+ID+' is not a valid Keyman setting.');
|
||||
Exit(False);
|
||||
end;
|
||||
case Setting.Base.ValueType of
|
||||
kstString: v := Setting.ValueStr;
|
||||
kstInteger: v := Setting.ValueInt.ToString;
|
||||
end;
|
||||
if Setting.IsEmpty
|
||||
then Log(AnsiColor.Green+Setting.Base.ID+AnsiColor.Grey+'='+AnsiColor.Grey+v+AnsiColor.Default)
|
||||
else Log(AnsiColor.Green+Setting.Base.ID+AnsiColor.Grey+'='+AnsiColor.White+v+AnsiColor.Default);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure ShowAllSettings(ShowAll: Boolean);
|
||||
var
|
||||
Setting: TKeymanSetting;
|
||||
begin
|
||||
for Setting in Settings do
|
||||
begin
|
||||
if ShowAll or not Setting.IsEmpty then
|
||||
ShowOneSetting(Setting.Base.ID);
|
||||
end;
|
||||
end;
|
||||
begin
|
||||
Result := True;
|
||||
TKeymanSettingsManager.Load(Settings);
|
||||
if SameText(P2, '-a') then
|
||||
ShowAllSettings(True)
|
||||
else if P2 = '' then
|
||||
ShowAllSettings(False)
|
||||
else
|
||||
Result := ShowOneSetting(P2);
|
||||
end;
|
||||
|
||||
function DetectColorMode: Boolean;
|
||||
var
|
||||
mode: DWORD;
|
||||
hConsole: THandle;
|
||||
const
|
||||
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4;
|
||||
begin
|
||||
Result := False;
|
||||
mode := 0;
|
||||
hConsole := GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if hConsole = INVALID_HANDLE_VALUE then
|
||||
begin
|
||||
//writeln(Format('GetStdHandle failed with %d %s', [GetLastError, SysErrorMessage(GetLastError)]));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if GetEnvironmentVariable('MSYSTEM') = 'MINGW64' then
|
||||
begin
|
||||
// MinGW64 test
|
||||
// Use colour mode only with a non-redirected console. This test fails with pipes.
|
||||
// For pipe use, explicitly use -no-color parameter
|
||||
Result := GetFileType(hConsole) = 3;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Win32 console color mode test
|
||||
if not GetConsoleMode(hConsole, mode) then
|
||||
Exit;
|
||||
|
||||
mode := mode or ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
if not SetConsoleMode(hConsole, mode) then
|
||||
Exit;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
const
|
||||
ESC=#$1b;
|
||||
ESC_BRIGHT_YELLOW=ESC+'[38;2;255;255;0m';
|
||||
ESC_RED=ESC+'[38;2;255;0;0m';
|
||||
ESC_GREEN=ESC+'[38;2;0;255;0m';
|
||||
ESC_GREY=ESC+'[38;2;128;132;128m';
|
||||
ESC_WHITE=ESC+'[38;2;255;255;255m';
|
||||
ESC_DEFAULT=ESC+'[0m';
|
||||
|
||||
initialization
|
||||
if DetectColorMode then
|
||||
begin
|
||||
ANSIColor.Green := ESC_GREEN;
|
||||
ANSIColor.Default := ESC_DEFAULT;
|
||||
ANSIColor.Red := ESC_RED;
|
||||
ANSIColor.Yellow := ESC_BRIGHT_YELLOW;
|
||||
ANSIColor.Grey := ESC_GREY;
|
||||
ANSIColor.White := ESC_WHITE;
|
||||
end;
|
||||
end.
|
||||
32
windows/src/desktop/kmconfig/Makefile
Normal file
32
windows/src/desktop/kmconfig/Makefile
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# KMConfig Makefile
|
||||
#
|
||||
|
||||
!include ..\..\Defines.mak
|
||||
|
||||
build: version.res manifest.res #icons
|
||||
$(DELPHI_MSBUILD) kmconfig.dproj /p:Platform=Win32
|
||||
$(TDS2DBG) $(WIN32_TARGET_PATH)\kmconfig.exe
|
||||
$(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\kmconfig.exe -dpr kmconfig.exe
|
||||
$(COPY) $(WIN32_TARGET_PATH)\kmconfig.exe $(PROGRAM)\desktop
|
||||
if exist $(WIN32_TARGET_PATH)\kmconfig.exe $(COPY) $(WIN32_TARGET_PATH)\kmconfig.exe $(DEBUGPATH)\desktop
|
||||
|
||||
#icons:
|
||||
#rc icons.rc
|
||||
|
||||
clean: def-clean
|
||||
|
||||
signcode:
|
||||
$(SIGNCODE) /d "Keyman for Windows" $(PROGRAM)\desktop\kmconfig.exe
|
||||
|
||||
backup:
|
||||
$(WZZIP) $(BUILD)\desktop\kmconfig.zip $(BACKUPDEFAULTS) kmconfig.exe
|
||||
|
||||
test-manifest:
|
||||
# test that (a) linked manifest exists and correct, and (b) has uiAccess=true
|
||||
$(MT) -nologo -inputresource:$(PROGRAM)\desktop\kmconfig.exe -validate_manifest
|
||||
|
||||
install:
|
||||
copy $(ROOT)\bin\desktop\kmconfig.exe "$(INSTALLPATH_KEYMANDESKTOP)"
|
||||
|
||||
!include ..\..\Target.mak
|
||||
BIN
windows/src/desktop/kmconfig/elevation.png
Normal file
BIN
windows/src/desktop/kmconfig/elevation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 774 B |
43
windows/src/desktop/kmconfig/kmconfig.dpr
Normal file
43
windows/src/desktop/kmconfig/kmconfig.dpr
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
program kmconfig;
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
Keyman.System.SettingsManager in '..\..\global\delphi\general\Keyman.System.SettingsManager.pas',
|
||||
RegistryKeys in '..\..\global\delphi\general\RegistryKeys.pas',
|
||||
KeymanVersion in '..\..\global\delphi\general\KeymanVersion.pas',
|
||||
Keyman.System.Settings in '..\..\global\delphi\general\Keyman.System.Settings.pas',
|
||||
Keyman.System.KeymanSentryClient in '..\..\global\delphi\general\Keyman.System.KeymanSentryClient.pas',
|
||||
Sentry.Client.Console in '..\..\ext\sentry\Sentry.Client.Console.pas',
|
||||
Sentry.Client in '..\..\ext\sentry\Sentry.Client.pas',
|
||||
sentry in '..\..\ext\sentry\sentry.pas',
|
||||
KeymanPaths in '..\..\global\delphi\general\KeymanPaths.pas',
|
||||
DebugPaths in '..\..\global\delphi\general\DebugPaths.pas',
|
||||
utilexecute in '..\..\global\delphi\general\utilexecute.pas',
|
||||
unicode in '..\..\global\delphi\general\unicode.pas',
|
||||
ErrorControlledRegistry in '..\..\global\delphi\vcl\ErrorControlledRegistry.pas',
|
||||
Keyman.System.KMConfigMain in 'Keyman.System.KMConfigMain.pas',
|
||||
Keyman.System.SettingsManagerFile in '..\..\global\delphi\general\Keyman.System.SettingsManagerFile.pas';
|
||||
|
||||
{$R manifest.res}
|
||||
{$R version.res}
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
const
|
||||
LOGGER_DESKTOP_KMCONFIG = TKeymanSentryClient.LOGGER_DESKTOP + '.kmconfig';
|
||||
begin
|
||||
TKeymanSentryClient.Start(TSentryClientConsole, kscpDesktop, LOGGER_DESKTOP_KMCONFIG);
|
||||
try
|
||||
try
|
||||
TKeymanSentryClient.Validate;
|
||||
TKMConfig.Run;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
SentryHandleException(E);
|
||||
ExitCode := 1;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
TKeymanSentryClient.Stop;
|
||||
end;
|
||||
end.
|
||||
1000
windows/src/desktop/kmconfig/kmconfig.dproj
Normal file
1000
windows/src/desktop/kmconfig/kmconfig.dproj
Normal file
File diff suppressed because it is too large
Load diff
BIN
windows/src/desktop/kmconfig/kmconfig.res
Normal file
BIN
windows/src/desktop/kmconfig/kmconfig.res
Normal file
Binary file not shown.
28
windows/src/desktop/kmconfig/manifest.in
Normal file
28
windows/src/desktop/kmconfig/manifest.in
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity type="win32" name="com.keyman.windows.kmconfig" version="$VersionWin" processorArchitecture="x86"/>
|
||||
<description>Keyman for Windows Config</description>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<!-- Switch on various compatibility values -->
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/><!-- Windows Vista and Windows Server 2008 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/><!-- Windows 7 and Windows Server 2008 R2 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/><!-- Windows 8 and Windows Server 2012 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/><!-- Windows 8.1 and Windows Server 2012 R2 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/><!-- Windows 10 -->
|
||||
</application>
|
||||
</compatibility>
|
||||
<!-- Runtime themes v6.0 common controls -->
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
||||
1
windows/src/desktop/kmconfig/manifest.rc
Normal file
1
windows/src/desktop/kmconfig/manifest.rc
Normal file
|
|
@ -0,0 +1 @@
|
|||
1 24 manifest.xml
|
||||
30
windows/src/desktop/kmconfig/version.in
Normal file
30
windows/src/desktop/kmconfig/version.in
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
1 VERSIONINFO
|
||||
FILEVERSION $VERSIONNUM
|
||||
PRODUCTVERSION $VERSIONNUM
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "0C0904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "SIL International\0"
|
||||
VALUE "FileDescription", "Keyman Config\0"
|
||||
VALUE "FileVersion", "$VERSION\0"
|
||||
VALUE "InternalName", "KMCONFIG\0"
|
||||
VALUE "LegalCopyright", "© SIL International\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "KMCONFIG.EXE\0"
|
||||
VALUE "ProductName", "Keyman for Windows\0"
|
||||
VALUE "ProductVersion", "$VERSION\0"
|
||||
VALUE "Comments", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0xc09, 1252
|
||||
END
|
||||
END
|
||||
Loading…
Add table
Reference in a new issue