В настоящее время я создаю приложение в Delphi, которое позволит компьютеру полностью выключиться после закрытия открытых приложений. В настоящее время я сталкиваюсь с проблемами, когда код не работает должным образом в Win10 enterprise, и он выводит пользователя из системы, но не полностью выключает P C. мозги кода приведены ниже, и мне неясно, почему это просто вывело бы меня из системы и не полностью выключило компьютер.
Пользователь определит параметры для запуска через CMD, чтобы выключить компьютер ссылка на приложение. Приложение закроет процессы, которые открыты, и пройдет процесс выключения через CMD.
procedure TfrmCleanShutdown.ProcessCommandLine;
const
CMD_CAPTION = 'w'; // window capShuttion
CMD_CLASSNAME = 'c'; // window class name
CMD_ACTION = 'a';
CMD_TIMEOUT = 't';
S_SHUTDOWN = 'shutdown';
S_LOGOFF = 'logoff';
S_RESTART = 'restart';
var
cmdl: TCommandLineParameterList;
cmd: TCommandLineParameter;
begin
cmdl := TCommandLineParameterList.Create;
cmdl.Initialize;
cmd := cmdl.FindByParam(CMD_CAPTION);
if Assigned(cmd) then
FWaitForWindowCaption := cmd.Param
else
FWaitForWindowCaption := '';
cmd := cmdl.FindByParam(CMD_CLASSNAME);
if Assigned(cmd) then
FWaitForWindowClassName := cmd.Param
else
FWaitForWindowClassName := '';
cmd := cmdl.FindByParam(CMD_TIMEOUT);
if Assigned(cmd) then
FTimeout := StrToIntDef(cmd.Param, DEF_TIMEOUT)
else
FTimeout := DEF_TIMEOUT;
FAction := EWX_LOGOFF or EWX_FORCEIFHUNG; // default action
cmd := cmdl.FindByParam(CMD_ACTION);
if Assigned(cmd) then begin
if cmd.Param = S_SHUTDOWN then
FAction := EWX_POWEROFF or EWX_FORCEIFHUNG
else if cmd.Param = S_RESTART then
FAction := EWX_REBOOT or EWX_FORCEIFHUNG
end;
end;
procedure TfrmCleanShutDown.ThreadTerminate(Sender: TObject);
begin
if (Sender as TWaitForWindowCloseThread).Success then
ExitWindowsEx(FAction, 0)
else
Label1.Caption := 'Timeout';
end;
Любая помощь будет принята. Мне неясно, почему win10 будет вести себя так, чтобы просто выйти из системы, а не завершать работу, поскольку приложение запускается через CMD, и у пользователя есть права на завершение работы. Это очень запутанно.
добавление кода командной строки из комментария ниже.
unit uCommandLine;
interface
uses
SysUtils, Classes, Contnrs;
const
S_SWITCHES = '+-*';
type
//======================================
// TCommandLineParameter
//======================================
TCommandLineParameter = class
private
FParam: String;
FSwitch: String;
FOptions: String;
public
property Param: String read FParam write FParam;
property Switch: String read FSwitch write FSwitch;
property Options: String read FOptions write FOptions;
end; // TCommandLineParameter
//======================================
// TCommandLineParameterList
//======================================
TCommandLineParameterList = class(TObjectList)
private
function GetParameter(idx: Integer): TCommandLineParameter;
public
function Initialize: Boolean;
function FindByParam(const ParamString: String): TCommandLineParameter;
property Parameters[idx: Integer]: TCommandLineParameter read GetParameter;
end;
implementation
const
C_CMD_DELIM: Char = '-';
//======================================
// TCommandLineParameter
//======================================
//======================================
// TCommandLineParameterList
//======================================
//------------------------------------------------------------------------------
function TCommandLineParameterList.GetParameter(idx: Integer): TCommandLineParameter;
begin
Result := TCommandLineParameter(Items[idx]);
end;
//------------------------------------------------------------------------------
function TCommandLineParameterList.Initialize: Boolean;
var
n, idx: Integer;
p: TCommandLineParameter;
s: String;
begin
Result := True;
p := nil;
n := ParamCount;
for idx := 1 to n do begin
s := Trim(ParamStr(idx));
if s[1] = C_CMD_DELIM then begin
System.Delete(s, 1, 1);
p := FindByParam(s);
if p = nil then begin
p := TCommandLineParameter.Create;
p.Param := s;
Add(p);
end
else begin
Result := False;
break;
end;
end
else begin
if p <> nil then begin
p.Options := s;
p := nil;
end
else begin
Result := False;
break;
end;
end;
end;
end;
//------------------------------------------------------------------------------
function TCommandLineParameterList.FindByParam(const ParamString: String): TCommandLineParameter;
var
idx: Integer;
begin
Result := nil;
for idx := 0 to Count-1 do
if CompareStr(Parameters[idx].Param, ParamString) = 0 then begin
Result := Parameters[idx];
break;
end;
end;
end.