Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Delphi服务中装载网络磁盘?_Delphi_Windows Services - Fatal编程技术网

如何在Delphi服务中装载网络磁盘?

如何在Delphi服务中装载网络磁盘?,delphi,windows-services,Delphi,Windows Services,我是Delphi的新手,但我需要修复Delphi代码,以便在执行“服务启动”时安装网络磁盘。默认情况下,通过Windows服务启动应用程序时,应用程序无法访问网络磁盘,因此解决方案是在我的服务中插入UNC映射脚本。你能帮我解决这个问题吗 非常感谢 unit ALFTSASvcUnit; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, ShellAPI, T

我是Delphi的新手,但我需要修复Delphi代码,以便在执行“服务启动”时安装网络磁盘。默认情况下,通过Windows服务启动应用程序时,应用程序无法访问网络磁盘,因此解决方案是在我的服务中插入UNC映射脚本。你能帮我解决这个问题吗

非常感谢

unit ALFTSASvcUnit;


interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, ShellAPI, TLHelp32, StrUtils;

type
  TALFTSAService = class(TService)
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServiceExecute(Sender: TService);
  private
    { Private declarations }
    function CountSAAProcs(ProcName : string) : integer;
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

var
  ALFTSAService: TALFTSAService;
  ALLIANCE : string;
  ARCH : string;

implementation

{$R *.DFM}

function TALFTSAService.CountSAAProcs(ProcName : string) : integer;
var
  MyHandle : THandle;
  Struct: TProcessEntry32;
begin
  Result := 0;
  MyHandle:=CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  Struct.dwSize:=Sizeof(TProcessEntry32);
  if Process32First(MyHandle, Struct) then
  begin
    if AnsiStartsText(ProcName, Struct.szExeFile) then
      inc(Result);
    while Process32Next(MyHandle, Struct) do
      if AnsiStartsText(ProcName, Struct.szExeFile) then
        inc(Result);
  end;
  CloseHandle(MyHandle);
//  LogMessage('Number of BS_ processes = ' + IntToStr(Result), EVENTLOG_INFORMATION_TYPE);
end;

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  ALFTSAService.Controller(CtrlCode);
end;

function TALFTSAService.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TALFTSAService.ServiceStart(Sender: TService;
  var Started: Boolean);
begin
  ALLIANCE := 'C:\Alliance\Access';
  ARCH := 'win32';

  if (ALLIANCE <> '') and (ARCH <> '') then
  begin
    ShellExecute(0, 'open', PChar(ALLIANCE + '\BSS\BIN\' + ARCH + '\alestart.exe'), '', nil, SW_SHOWNORMAL) ;
    while (CountSAAProcs('bs_') < 5) do
      Sleep(10000);
    while (CountSAAProcs('mxs_') < 8) do
      Sleep(10000);
  end
  else
  begin
    LogMessage('Unable to find SWIFTAlliance environment variables %ALLIANCE%, %ARCH%');
    Status:=csStopped;
  end;
end;

procedure TALFTSAService.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  ShellExecute(0, 'open', PChar(ALLIANCE + '\BSS\BIN\' + ARCH + '\alestop.exe'), '', nil, SW_SHOWNORMAL) ;
  while (CountSAAProcs('bs_') > 0) do
    Sleep(10000);
  Sleep (10000);
  while (CountSAAProcs('aleempty') > 0) do
    Sleep(5000);
  Sleep(5000);
end;

procedure TALFTSAService.ServiceExecute(Sender: TService);
const
  SecBetweenRuns = 60;
var
  Count: Integer;
begin
  Count := 0;
  while not Terminated do
  begin
    Inc(Count);
    if Count >= SecBetweenRuns then
    begin
      Count := 0;
      if (CountSAAProcs('bs_') < 4) then
      begin
        Status:=csStopped;
        Break;
      end;
    end;
    Sleep(1000);
    ServiceThread.ProcessRequests(False);
  end;
end;

end.
unit-alftsavcUnit;
接口
使用
窗口、消息、系统工具、类、图形、控件、SvcMgr、对话框、ShellAPI、TLHelp32、StrUtils;
类型
TALFTSAService=类别(T服务)
过程ServiceStart(发送方:TService;var start:Boolean);
过程ServiceStop(发送方:TService;停止变量:Boolean);
过程ServiceExecute(发送方:TService);
私有的
{私有声明}
函数CountSAAProcs(ProcName:string):整数;
公众的
函数GetServiceController:TServiceController;推翻
{公开声明}
结束;
变量
ALFTSAService:TalfsaService;
联盟:字符串;
拱:弦;
实施
{$R*.DFM}
函数TALFTSAService.CountSAAProcs(ProcName:string):整数;
变量
我的把手:坦德尔;
结构:tprocesentry32;
开始
结果:=0;
MyHandle:=CreateToolHelp32SnapShot(TH32CS\u SNAPPROCESS,0);
结构dwSize:=Sizeof(tprocesentry32);
如果先处理32(MyHandle,Struct),然后
开始
如果是AnsiStartsText(ProcName,Struct.szExeFile),那么
公司(结果);
而Process32Next(MyHandle,Struct)执行
如果是AnsiStartsText(ProcName,Struct.szExeFile),那么
公司(结果);
结束;
关闭手柄(MyHandle);
//LogMessage('BS_u进程数='+IntToStr(结果),事件日志信息类型);
结束;
程序服务控制员(CtrlCode:DWord);stdcall;
开始
ALFTSAService.控制器(CtrlCode);
结束;
函数TALFTSAService.GetServiceController:TServiceController;
开始
结果:=服务控制器;
结束;
程序TALFTSAService.ServiceStart(发送方:TService;
变量:布尔值);
开始
联盟:=“C:\ALLIANCE\Access”;
ARCH:=“win32”;
如果(联盟“”)和(拱门“”),则
开始
ShellExecute(0,'open',PChar(ALLIANCE+'\BSS\BIN\'+ARCH+'\alestart.exe'),'',nil,SW_SHOWNORMAL);
而(CountSAAProcs('bs_')<5)做
睡眠(10000);
而(CountSAAProcs('mxs_')<8
睡眠(10000);
结束
其他的
开始
日志消息('无法找到SWIFTAlliance环境变量%ALLIANCE%,%ARCH%');
状态:=csStopped;
结束;
结束;
过程TALFTSAService.ServiceStop(发送方:TService;停止变量:Boolean);
开始
ShellExecute(0,'open',PChar(ALLIANCE+'\BSS\BIN\'+ARCH+'\alestop.exe'),'',nil,SW_SHOWNORMAL);
而(CountSAAProcs('bs')>0)则
睡眠(10000);
睡眠(10000);
而(CountSAAProcs('alempty')>0)do
睡眠(5000);
睡眠(5000);
结束;
过程Talftaservice.ServiceExecute(发送方:TService);
常数
SecBetweenRuns=60;
变量
计数:整数;
开始
计数:=0;
虽然没有终止
开始
公司(计数);
如果计数>=SecBetweenRuns,则
开始
计数:=0;
如果(CountSAAProcs('bs_')<4),则
开始
状态:=csStopped;
打破
结束;
结束;
睡眠(1000);
ServiceThread.ProcessRequests(False);
结束;
结束;
结束。

看起来这不是一个Delphi问题,假设ShellExecute不好用(我不清楚)

在这种情况下,可能是[网络]文件权限问题,我建议您在两种不同的解决方案中进行选择:

  • 将服务登录设置为具有所需文件的正确(且经过测试)网络读/写/执行权限的帐户。请记住,默认情况下,服务使用“系统”帐户运行,这对于访问本地资源是可以的,但对于网络资源则没有那么好
  • 为允许在不同用户的上下文中启动“alestart.exe”的用户更改ShellExecute方法(该服务作为系统运行,在其配置中存储用户启动“alestart.exe”进程的凭据。若要在其他用户的上下文中启动进程,可以使用CreateProcessWithLogonNW API调用。要使其正常工作,您的进程必须启用SeImpersonatePrivilege

注意。

您有什么“问题”吗?什么不起作用?另外,您应该尝试将代码缩减到相关部分。哦,既然这是您的第一个问题:欢迎使用SO!:)亲爱的Smasher,谢谢你;除了访问由上述服务启动的应用程序中的共享磁盘外,其他一切都正常。我是初学者,我无法确定在何处以及插入什么函数以安装网络驱动器(如cmd中的“net use”)是否每次都可以通过UNC路径访问资源,而不是映射驱动器?感谢jachguate,我将尝试插入CreateProcessWithLogonW而不是ShellExecute