1

Win7でDelphiXE2からmysqlを停止しようとしています。これを行うはずのDelphi7のWebで見つけたものに基づいてコードを記述しましたが、機能しません。

function StopMySQL: boolean;
const
  UserName = 'Mark';
  Domain = 'PC-Mark';
  Command = 'net stop mysql';
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_HIDE;
  result := CreateProcessWithLogonW(Username, Domain, Password, 0, nil, Command, 0,     nil, nil, StartupInfo, ProcessInfo);
  if result then
    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
end;

誰かがこれを行う方法を知っていますか?

TIAマークパターソン

4

2 に答える 2

6

Vista以降、サービスを開始/停止するには、昇格されたアクセスが必要になります。
簡単な方法の 1 つは、RunAs を Shellexecute(Ex) と共に使用することです。

ShellExecute(handle,'RunAs','net','stop mysql',nil,sw_Show);

より良い方法は、次のようなマニフェストを使用することです。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
       <requestedExecutionLevel level="requireAdministrator" />
      </requestedPrivileges> 
    </security>
  </trustInfo>
</assembly>

「ネット」を必要としない最小の解決策は、次のようになります。サービスが実行されているかどうかをテストしますが、それはあなた次第であり、WinSvc で次のことを行うことができます。

implementation
uses WinSvc;
{$R *.dfm}
{$R administrator.res}

function ServiceStop(Machine, ServiceName: string): Boolean;

var
  ServiceControlManager, ServiceHandle: SC_Handle;
  ServiceStatus: TServiceStatus;
  dwCheckPoint: DWORD;
begin
  ServiceControlManager := OpenSCManager(PChar(Machine), nil, SC_MANAGER_CONNECT);
  if ServiceControlManager > 0 then
  begin
    ServiceHandle := OpenService(ServiceControlManager, PChar(ServiceName),
      SERVICE_STOP or SERVICE_QUERY_STATUS);
    if ServiceHandle > 0 then
    begin
      if (ControlService(ServiceHandle, SERVICE_CONTROL_STOP, ServiceStatus)) then
      begin
        if (QueryServiceStatus(ServiceHandle, ServiceStatus)) then
        begin
          while (SERVICE_STOPPED <> ServiceStatus.dwCurrentState) do
          begin
            dwCheckPoint := ServiceStatus.dwCheckPoint;
            Sleep(ServiceStatus.dwWaitHint);
            if (not QueryServiceStatus(ServiceHandle, ServiceStatus)) then
              break;
            if (ServiceStatus.dwCheckPoint < dwCheckPoint) then
              break;
          end;
        end;
      end;
      CloseServiceHandle(ServiceHandle);
    end;
    CloseServiceHandle(ServiceControlManager);
  end;

  Result := (SERVICE_STOPPED = ServiceStatus.dwCurrentState);
end;

procedure TForm2.Button1Click(Sender: TObject);

begin
   If ServiceStop('','mysql') then Showmessage('Service Stopped')
   else Showmessage('Nope');
end;

管理者リソースは次の方法で作成できます

  • 上記の show XML-Code を administrator.manifest として保存します。
  • コンテンツを含むファイル administrator.rc として作成

1 24 "administrator.manifest"

  • ランニング

brcc32 管理者.rc

作成した administrator.res を使用するには、次のものが必要です。

  1. マニフェストに含まれている、新しい Delphi バージョンでのランタイム テーマの無効化
  2. XPMan を既存のプロジェクト (マニフェストに含まれるコンポーネントとコード) から削除する
  3. アプリケーションをデバッグする必要がある場合は、delphi も管理者として開始する必要があります。

ソースとマニフェストに必要なものはすべてここからダウンロードできます

于 2013-03-19T06:46:29.843 に答える
1

私がやったことはこれです:

uses WinApi, ShellApi;

function StartStopDatabase(start: boolean): integer;
var
  Info: TShellExecuteInfo;
  verb: string;
  ExitCode: DWORD;
begin
  Result := -1;
  if start
    then verb := 'start'
    else verb := 'stop';
  FillChar(Info, SizeOf(Info), 0);
  Info.cbSize := SizeOf(TShellExecuteInfo);
  Info.fMask := SEE_MASK_NOCLOSEPROCESS;
  Info.Wnd := Application.Handle;
  Info.lpVerb := 'RunAs';
  Info.lpFile := 'net';
  Info.lpParameters := PWideChar(verb + ' mysql');
  Info.nShow := SW_SHOW;
  if ShellExecuteEx(@Info) then begin
    repeat
      Sleep(100);
      Application.ProcessMessages;
      GetExitCodeProcess(Info.hProcess, ExitCode);
    until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
    Result := ExitCode;
  end;
end;
于 2013-03-25T05:57:34.890 に答える