mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-26 11:17:57 +08:00
Issue #677: provide a new library combobox in MySQL mode, for selecting any of the libmysql/mariadb.dll files from the application directory
This commit is contained in:
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: HeidiSQL\n"
|
"Project-Id-Version: HeidiSQL\n"
|
||||||
"POT-Creation-Date: 2012-11-05 21:40\n"
|
"POT-Creation-Date: 2012-11-05 21:40\n"
|
||||||
"PO-Revision-Date: 2019-06-12 20:31+0200\n"
|
"PO-Revision-Date: 2019-07-05 06:42+0200\n"
|
||||||
"Last-Translator: Ansgar Becker <anse@heidisql.com>\n"
|
"Last-Translator: Ansgar Becker <anse@heidisql.com>\n"
|
||||||
"Language-Team: English (http://www.transifex.com/projects/p/heidisql/language/en/)\n"
|
"Language-Team: English (http://www.transifex.com/projects/p/heidisql/language/en/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -4025,6 +4025,10 @@ msgstr "Trying to load library with full path: %s"
|
|||||||
msgid "Library error in %s: Could not find procedure address for \"%s\""
|
msgid "Library error in %s: Could not find procedure address for \"%s\""
|
||||||
msgstr "Library error in %s: Could not find procedure address for \"%s\""
|
msgstr "Library error in %s: Could not find procedure address for \"%s\""
|
||||||
|
|
||||||
|
#. DLL loading failed entirely
|
||||||
|
msgid "Library %s seems unusable. Please select a different one."
|
||||||
|
msgstr "Library %s seems unusable. Please select a different one."
|
||||||
|
|
||||||
#: dbconnection.pas:1392
|
#: dbconnection.pas:1392
|
||||||
msgid "Cannot find a usable %s. Please launch %s from the directory where you have installed it."
|
msgid "Cannot find a usable %s. Please launch %s from the directory where you have installed it."
|
||||||
msgstr "Cannot find a usable %s. Please launch %s from the directory where you have installed it."
|
msgstr "Cannot find a usable %s. Please launch %s from the directory where you have installed it."
|
||||||
|
@ -141,7 +141,7 @@ type
|
|||||||
asWrapLongLines, asDisplayBLOBsAsText, asSingleQueries, asMemoEditorWidth, asMemoEditorHeight, asMemoEditorMaximized,
|
asWrapLongLines, asDisplayBLOBsAsText, asSingleQueries, asMemoEditorWidth, asMemoEditorHeight, asMemoEditorMaximized,
|
||||||
asMemoEditorWrap, asDelimiter, asSQLHelpWindowLeft, asSQLHelpWindowTop, asSQLHelpWindowWidth,
|
asMemoEditorWrap, asDelimiter, asSQLHelpWindowLeft, asSQLHelpWindowTop, asSQLHelpWindowWidth,
|
||||||
asSQLHelpWindowHeight, asSQLHelpPnlLeftWidth, asSQLHelpPnlRightTopHeight, asHost,
|
asSQLHelpWindowHeight, asSQLHelpPnlLeftWidth, asSQLHelpPnlRightTopHeight, asHost,
|
||||||
asUser, asPassword, asCleartextPluginEnabled, asWindowsAuth, asLoginPrompt, asPort,
|
asUser, asPassword, asCleartextPluginEnabled, asWindowsAuth, asLoginPrompt, asPort, asLibrary,
|
||||||
asPlinkExecutable, asSSHtunnelHost, asSSHtunnelHostPort, asSSHtunnelPort, asSSHtunnelUser,
|
asPlinkExecutable, asSSHtunnelHost, asSSHtunnelHostPort, asSSHtunnelPort, asSSHtunnelUser,
|
||||||
asSSHtunnelPassword, asSSHtunnelTimeout, asSSHtunnelPrivateKey, asSSLActive, asSSLKey,
|
asSSHtunnelPassword, asSSHtunnelTimeout, asSSHtunnelPrivateKey, asSSLActive, asSSLKey,
|
||||||
asSSLCert, asSSLCA, asSSLCipher, asNetType, asCompressed, asLocalTimeZone, asQueryTimeout, asKeepAlive,
|
asSSLCert, asSSLCA, asSSLCipher, asNetType, asCompressed, asLocalTimeZone, asQueryTimeout, asKeepAlive,
|
||||||
@ -3495,6 +3495,7 @@ begin
|
|||||||
InitSetting(asWindowsAuth, 'WindowsAuth', 0, False, '', True);
|
InitSetting(asWindowsAuth, 'WindowsAuth', 0, False, '', True);
|
||||||
InitSetting(asLoginPrompt, 'LoginPrompt', 0, False, '', True);
|
InitSetting(asLoginPrompt, 'LoginPrompt', 0, False, '', True);
|
||||||
InitSetting(asPort, 'Port', 0, False, '', True);
|
InitSetting(asPort, 'Port', 0, False, '', True);
|
||||||
|
InitSetting(asLibrary, 'Library', 0, False, 'libmariadb.dll', True);
|
||||||
InitSetting(asPlinkExecutable, 'PlinkExecutable', 0, False, '');
|
InitSetting(asPlinkExecutable, 'PlinkExecutable', 0, False, '');
|
||||||
InitSetting(asSSHtunnelHost, 'SSHtunnelHost', 0, False, '', True);
|
InitSetting(asSSHtunnelHost, 'SSHtunnelHost', 0, False, '', True);
|
||||||
InitSetting(asSSHtunnelHostPort, 'SSHtunnelHostPort', 22, False, '', True);
|
InitSetting(asSSHtunnelHostPort, 'SSHtunnelHostPort', 22, False, '', True);
|
||||||
|
@ -273,11 +273,18 @@ object connform: Tconnform
|
|||||||
end
|
end
|
||||||
object lblComment: TLabel
|
object lblComment: TLabel
|
||||||
Left = 3
|
Left = 3
|
||||||
Top = 241
|
Top = 270
|
||||||
Width = 49
|
Width = 49
|
||||||
Height = 13
|
Height = 13
|
||||||
Caption = 'Comment:'
|
Caption = 'Comment:'
|
||||||
end
|
end
|
||||||
|
object lblLibrary: TLabel
|
||||||
|
Left = 3
|
||||||
|
Top = 243
|
||||||
|
Width = 37
|
||||||
|
Height = 13
|
||||||
|
Caption = 'Library:'
|
||||||
|
end
|
||||||
object chkCompressed: TCheckBox
|
object chkCompressed: TCheckBox
|
||||||
Left = 120
|
Left = 120
|
||||||
Top = 190
|
Top = 190
|
||||||
@ -377,12 +384,12 @@ object connform: Tconnform
|
|||||||
end
|
end
|
||||||
object memoComment: TMemo
|
object memoComment: TMemo
|
||||||
Left = 120
|
Left = 120
|
||||||
Top = 238
|
Top = 267
|
||||||
Width = 294
|
Width = 294
|
||||||
Height = 119
|
Height = 90
|
||||||
Anchors = [akLeft, akTop, akRight, akBottom]
|
Anchors = [akLeft, akTop, akRight, akBottom]
|
||||||
ScrollBars = ssVertical
|
ScrollBars = ssVertical
|
||||||
TabOrder = 10
|
TabOrder = 11
|
||||||
OnChange = Modification
|
OnChange = Modification
|
||||||
end
|
end
|
||||||
object editDatabases: TButtonedEdit
|
object editDatabases: TButtonedEdit
|
||||||
@ -399,6 +406,16 @@ object connform: Tconnform
|
|||||||
OnChange = Modification
|
OnChange = Modification
|
||||||
OnRightButtonClick = editDatabasesRightButtonClick
|
OnRightButtonClick = editDatabasesRightButtonClick
|
||||||
end
|
end
|
||||||
|
object comboLibrary: TComboBox
|
||||||
|
Left = 120
|
||||||
|
Top = 240
|
||||||
|
Width = 294
|
||||||
|
Height = 21
|
||||||
|
Style = csDropDownList
|
||||||
|
Anchors = [akLeft, akTop, akRight]
|
||||||
|
TabOrder = 10
|
||||||
|
OnChange = Modification
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
object tabSSHtunnel: TTabSheet
|
object tabSSHtunnel: TTabSheet
|
||||||
|
@ -11,7 +11,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Windows, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
|
Windows, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
|
||||||
VirtualTrees, Menus, Graphics, Generics.Collections, ActiveX, extra_controls, Messages,
|
VirtualTrees, Menus, Graphics, Generics.Collections, ActiveX, extra_controls, Messages,
|
||||||
dbconnection, gnugettext;
|
dbconnection, gnugettext, SynRegExpr, System.Types, System.IOUtils;
|
||||||
|
|
||||||
type
|
type
|
||||||
Tconnform = class(TFormWithSizeGrip)
|
Tconnform = class(TFormWithSizeGrip)
|
||||||
@ -121,6 +121,8 @@ type
|
|||||||
TimerButtonAnimation: TTimer;
|
TimerButtonAnimation: TTimer;
|
||||||
lblBackgroundColor: TLabel;
|
lblBackgroundColor: TLabel;
|
||||||
ColorBoxBackgroundColor: TColorBox;
|
ColorBoxBackgroundColor: TColorBox;
|
||||||
|
comboLibrary: TComboBox;
|
||||||
|
lblLibrary: TLabel;
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
procedure btnOpenClick(Sender: TObject);
|
procedure btnOpenClick(Sender: TObject);
|
||||||
procedure FormShow(Sender: TObject);
|
procedure FormShow(Sender: TObject);
|
||||||
@ -230,6 +232,9 @@ var
|
|||||||
nt: TNetType;
|
nt: TNetType;
|
||||||
Node: PVirtualNode;
|
Node: PVirtualNode;
|
||||||
Params: TConnectionParameters;
|
Params: TConnectionParameters;
|
||||||
|
rx: TRegExpr;
|
||||||
|
Libs: TStringDynArray;
|
||||||
|
LibPath, LibFile: String;
|
||||||
begin
|
begin
|
||||||
// Fix GUI stuff
|
// Fix GUI stuff
|
||||||
TranslateComponent(Self);
|
TranslateComponent(Self);
|
||||||
@ -265,6 +270,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
Params.Free;
|
Params.Free;
|
||||||
|
|
||||||
|
// Detect existing MySQL libraries
|
||||||
|
rx := TRegExpr.Create;
|
||||||
|
rx.Expression := '^lib(mysql|mariadb).*\.dll$';
|
||||||
|
Libs := TDirectory.GetFiles(ExtractFilePath(ParamStr(0)), '*.dll');
|
||||||
|
for LibPath in Libs do begin
|
||||||
|
LibFile := ExtractFileName(LibPath);
|
||||||
|
if rx.Exec(LibFile) then begin
|
||||||
|
comboLibrary.Items.Add(LibFile);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
// Init sessions tree
|
// Init sessions tree
|
||||||
RefreshSessions(nil);
|
RefreshSessions(nil);
|
||||||
|
|
||||||
@ -388,6 +404,7 @@ begin
|
|||||||
Sess.LocalTimeZone := chkLocalTimeZone.Checked;
|
Sess.LocalTimeZone := chkLocalTimeZone.Checked;
|
||||||
Sess.FullTableStatus := chkFullTableStatus.Checked;
|
Sess.FullTableStatus := chkFullTableStatus.Checked;
|
||||||
Sess.SessionColor := ColorBoxBackgroundColor.Selected;
|
Sess.SessionColor := ColorBoxBackgroundColor.Selected;
|
||||||
|
Sess.LibraryFile := comboLibrary.Text;
|
||||||
Sess.AllDatabasesStr := editDatabases.Text;
|
Sess.AllDatabasesStr := editDatabases.Text;
|
||||||
Sess.Comment := memoComment.Text;
|
Sess.Comment := memoComment.Text;
|
||||||
Sess.StartupScriptFilename := editStartupScript.Text;
|
Sess.StartupScriptFilename := editStartupScript.Text;
|
||||||
@ -582,6 +599,7 @@ begin
|
|||||||
else
|
else
|
||||||
Result.Port := 0;
|
Result.Port := 0;
|
||||||
Result.AllDatabasesStr := editDatabases.Text;
|
Result.AllDatabasesStr := editDatabases.Text;
|
||||||
|
Result.LibraryFile := comboLibrary.Text;
|
||||||
Result.Comment := memoComment.Text;
|
Result.Comment := memoComment.Text;
|
||||||
Result.SSHHost := editSSHHost.Text;
|
Result.SSHHost := editSSHHost.Text;
|
||||||
Result.SSHPort := MakeInt(editSSHPort.Text);
|
Result.SSHPort := MakeInt(editSSHPort.Text);
|
||||||
@ -848,6 +866,7 @@ begin
|
|||||||
chkFullTableStatus.Checked := Sess.FullTableStatus;
|
chkFullTableStatus.Checked := Sess.FullTableStatus;
|
||||||
ColorBoxBackgroundColor.Selected := Sess.SessionColor;
|
ColorBoxBackgroundColor.Selected := Sess.SessionColor;
|
||||||
editDatabases.Text := Sess.AllDatabasesStr;
|
editDatabases.Text := Sess.AllDatabasesStr;
|
||||||
|
comboLibrary.ItemIndex := comboLibrary.Items.IndexOf(Sess.LibraryFile);
|
||||||
memoComment.Text := Sess.Comment;
|
memoComment.Text := Sess.Comment;
|
||||||
editStartupScript.Text := Sess.StartupScriptFilename;
|
editStartupScript.Text := Sess.StartupScriptFilename;
|
||||||
editSSHPlinkExe.Text := Sess.SSHPlinkExe;
|
editSSHPlinkExe.Text := Sess.SSHPlinkExe;
|
||||||
@ -1108,6 +1127,7 @@ begin
|
|||||||
or (Sess.SessionColor <> ColorBoxBackgroundColor.Selected)
|
or (Sess.SessionColor <> ColorBoxBackgroundColor.Selected)
|
||||||
or (Sess.NetType <> TNetType(comboNetType.ItemIndex))
|
or (Sess.NetType <> TNetType(comboNetType.ItemIndex))
|
||||||
or (Sess.StartupScriptFilename <> editStartupScript.Text)
|
or (Sess.StartupScriptFilename <> editStartupScript.Text)
|
||||||
|
or (Sess.LibraryFile <> comboLibrary.Text)
|
||||||
or (Sess.AllDatabasesStr <> editDatabases.Text)
|
or (Sess.AllDatabasesStr <> editDatabases.Text)
|
||||||
or (Sess.Comment <> memoComment.Text)
|
or (Sess.Comment <> memoComment.Text)
|
||||||
or (Sess.SSHHost <> editSSHHost.Text)
|
or (Sess.SSHHost <> editSSHHost.Text)
|
||||||
@ -1187,6 +1207,7 @@ begin
|
|||||||
lblPort.Enabled := False; // Named instance without port
|
lblPort.Enabled := False; // Named instance without port
|
||||||
editPort.Enabled := lblPort.Enabled;
|
editPort.Enabled := lblPort.Enabled;
|
||||||
updownPort.Enabled := lblPort.Enabled;
|
updownPort.Enabled := lblPort.Enabled;
|
||||||
|
comboLibrary.Enabled := Params.NetTypeGroup in [ngMySQL];
|
||||||
if Params.NetTypeGroup = ngPgSQL then
|
if Params.NetTypeGroup = ngPgSQL then
|
||||||
lblDatabase.Caption := _('Database')+':'
|
lblDatabase.Caption := _('Database')+':'
|
||||||
else
|
else
|
||||||
|
@ -213,7 +213,7 @@ type
|
|||||||
TConnectionParameters = class(TObject)
|
TConnectionParameters = class(TObject)
|
||||||
strict private
|
strict private
|
||||||
FNetType: TNetType;
|
FNetType: TNetType;
|
||||||
FHostname, FUsername, FPassword, FAllDatabases, FComment, FStartupScriptFilename,
|
FHostname, FUsername, FPassword, FAllDatabases, FLibraryFile, FComment, FStartupScriptFilename,
|
||||||
FSessionPath, FSSLPrivateKey, FSSLCertificate, FSSLCACertificate, FSSLCipher, FServerVersion,
|
FSessionPath, FSSLPrivateKey, FSSLCertificate, FSSLCACertificate, FSSLCipher, FServerVersion,
|
||||||
FSSHHost, FSSHUser, FSSHPassword, FSSHPlinkExe, FSSHPrivateKey: String;
|
FSSHHost, FSSHUser, FSSHPassword, FSSHPlinkExe, FSSHPrivateKey: String;
|
||||||
FPort, FSSHPort, FSSHLocalPort, FSSHTimeout, FCounter, FQueryTimeout, FKeepAlive: Integer;
|
FPort, FSSHPort, FSSHLocalPort, FSSHTimeout, FCounter, FQueryTimeout, FKeepAlive: Integer;
|
||||||
@ -263,6 +263,7 @@ type
|
|||||||
property WindowsAuth: Boolean read FWindowsAuth write FWindowsAuth;
|
property WindowsAuth: Boolean read FWindowsAuth write FWindowsAuth;
|
||||||
property CleartextPluginEnabled: Boolean read FCleartextPluginEnabled write FCleartextPluginEnabled;
|
property CleartextPluginEnabled: Boolean read FCleartextPluginEnabled write FCleartextPluginEnabled;
|
||||||
property AllDatabasesStr: String read FAllDatabases write FAllDatabases;
|
property AllDatabasesStr: String read FAllDatabases write FAllDatabases;
|
||||||
|
property LibraryFile: String read FLibraryFile write FLibraryFile;
|
||||||
property Comment: String read FComment write FComment;
|
property Comment: String read FComment write FComment;
|
||||||
property StartupScriptFilename: String read FStartupScriptFilename write FStartupScriptFilename;
|
property StartupScriptFilename: String read FStartupScriptFilename write FStartupScriptFilename;
|
||||||
property QueryTimeout: Integer read FQueryTimeout write FQueryTimeout;
|
property QueryTimeout: Integer read FQueryTimeout write FQueryTimeout;
|
||||||
@ -1088,6 +1089,7 @@ begin
|
|||||||
FPort := DefaultPort;
|
FPort := DefaultPort;
|
||||||
FCompressed := AppSettings.GetDefaultBool(asCompressed);
|
FCompressed := AppSettings.GetDefaultBool(asCompressed);
|
||||||
FAllDatabases := AppSettings.GetDefaultString(asDatabases);
|
FAllDatabases := AppSettings.GetDefaultString(asDatabases);
|
||||||
|
FLibraryFile := AppSettings.GetDefaultString(asLibrary);
|
||||||
FComment := AppSettings.GetDefaultString(asComment);
|
FComment := AppSettings.GetDefaultString(asComment);
|
||||||
|
|
||||||
FSSHHost := AppSettings.GetDefaultString(asSSHtunnelHost);
|
FSSHHost := AppSettings.GetDefaultString(asSSHtunnelHost);
|
||||||
@ -1154,6 +1156,7 @@ begin
|
|||||||
FPort := MakeInt(AppSettings.ReadString(asPort));
|
FPort := MakeInt(AppSettings.ReadString(asPort));
|
||||||
FCompressed := AppSettings.ReadBool(asCompressed);
|
FCompressed := AppSettings.ReadBool(asCompressed);
|
||||||
FAllDatabases := AppSettings.ReadString(asDatabases);
|
FAllDatabases := AppSettings.ReadString(asDatabases);
|
||||||
|
FLibraryFile := AppSettings.ReadString(asLibrary);
|
||||||
FComment := AppSettings.ReadString(asComment);
|
FComment := AppSettings.ReadString(asComment);
|
||||||
|
|
||||||
FSSHHost := AppSettings.ReadString(asSSHtunnelHost);
|
FSSHHost := AppSettings.ReadString(asSSHtunnelHost);
|
||||||
@ -1218,6 +1221,7 @@ begin
|
|||||||
AppSettings.WriteInt(asKeepAlive, FKeepAlive);
|
AppSettings.WriteInt(asKeepAlive, FKeepAlive);
|
||||||
AppSettings.WriteBool(asFullTableStatus, FFullTableStatus);
|
AppSettings.WriteBool(asFullTableStatus, FFullTableStatus);
|
||||||
AppSettings.WriteString(asDatabases, FAllDatabases);
|
AppSettings.WriteString(asDatabases, FAllDatabases);
|
||||||
|
AppSettings.WriteString(asLibrary, FLibraryFile);
|
||||||
AppSettings.WriteString(asComment, FComment);
|
AppSettings.WriteString(asComment, FComment);
|
||||||
AppSettings.WriteString(asStartupScriptFilename, FStartupScriptFilename);
|
AppSettings.WriteString(asStartupScriptFilename, FStartupScriptFilename);
|
||||||
AppSettings.WriteInt(asTreeBackground, FSessionColor);
|
AppSettings.WriteInt(asTreeBackground, FSessionColor);
|
||||||
@ -2214,35 +2218,22 @@ end;
|
|||||||
procedure TMySQLConnection.DoBeforeConnect;
|
procedure TMySQLConnection.DoBeforeConnect;
|
||||||
var
|
var
|
||||||
msg,
|
msg,
|
||||||
TryLibraryPath: String;
|
LibraryPath: String;
|
||||||
TryLibraryPaths: TStringList;
|
|
||||||
begin
|
begin
|
||||||
// Init libmysql before actually connecting.
|
// Init libmysql before actually connecting.
|
||||||
|
LibraryPath := ExtractFilePath(ParamStr(0)) + Parameters.LibraryFile;
|
||||||
|
Log(lcDebug, f_('Loading library file %s ...', [LibraryPath]));
|
||||||
// Try newer libmariadb version at first, and fall back to libmysql,
|
try
|
||||||
// then fall back to dlls somewhere else on the users harddisk
|
FLib := TMySQLLib.Create(LibraryPath);
|
||||||
// Win XP needs libmysql.dll
|
Log(lcDebug, FLib.DllFile + ' v' + DecodeApiString(FLib.mysql_get_client_info) + ' loaded.');
|
||||||
TryLibraryPaths := TStringList.Create;
|
except
|
||||||
TryLibraryPaths.Add(ExtractFilePath(Application.ExeName) + 'libmariadb.dll');
|
on E:Exception do
|
||||||
TryLibraryPaths.Add(ExtractFilePath(Application.ExeName) + 'libmysql.dll');
|
Log(lcDebug, E.Message);
|
||||||
TryLibraryPaths.Add('libmariadb.dll');
|
|
||||||
TryLibraryPaths.Add('libmysql.dll');
|
|
||||||
|
|
||||||
for TryLibraryPath in TryLibraryPaths do begin
|
|
||||||
Log(lcDebug, f_('Loading library file %s ...', [TryLibraryPath]));
|
|
||||||
try
|
|
||||||
FLib := TMySQLLib.Create(TryLibraryPath);
|
|
||||||
Log(lcDebug, FLib.DllFile + ' v' + DecodeApiString(FLib.mysql_get_client_info) + ' loaded.');
|
|
||||||
Break;
|
|
||||||
except
|
|
||||||
on E:Exception do
|
|
||||||
Log(lcDebug, E.Message);
|
|
||||||
end
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not Assigned(FLib) then begin
|
if not Assigned(FLib) then begin
|
||||||
msg := f_('Cannot find a usable %s. Please launch %s from the directory where you have installed it.',
|
msg := f_('Library %s seems unusable. Please select a different one.',
|
||||||
[ExtractFileName(TryLibraryPaths[0]), ExtractFileName(ParamStr(0))]
|
[ExtractFileName(LibraryPath)]
|
||||||
);
|
);
|
||||||
if Windows.GetLastError <> 0 then
|
if Windows.GetLastError <> 0 then
|
||||||
msg := msg + CRLF + CRLF + f_('Internal error %d:', [Windows.GetLastError]) + ' ' + SysErrorMessage(Windows.GetLastError);
|
msg := msg + CRLF + CRLF + f_('Internal error %d:', [Windows.GetLastError]) + ' ' + SysErrorMessage(Windows.GetLastError);
|
||||||
|
Reference in New Issue
Block a user