我试图在Win 7上从Delphi XE2中停止mysql。我已经根据我在网上为Delphi 7找到的东西编写了一些代码,这应该是这样做的,但它不起作用:
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 马克帕特森
答案 0 :(得分:6)
从Vista开始,您需要提升访问权限才能开始/停止服务 一种简单的方法是使用带有Shellexecute(Ex)的RunAs。
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>
一个最小的解决方案,不需要“net”,看起来像这样,应该做更多,例如。测试服务是否正在运行,但这对您而言可以通过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;
可以通过
创建管理员资源1 24“administrator.manifest”
brcc32 administrator.rc
使用创建的administrator.res将需要:
Source and anything needed for the manifest can be downloaded here
答案 1 :(得分: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;