现象:
1.控件Tree有时可以接收拖放,有时不可以。
2.CHM文件有时可以打开,有时打不开。
3.程序中有打开文件对话框,当转到桌面时,显示:C:\Documents and Settings\LocalService\桌面 引用了一个不可用的位置 ...
有时就正常。
同时检查日志发现:
事件 ID ( 1903 )的描述(在资源( HHCTRL )中)无法找到。本地计算机可能没有必要的注册信息或消息 DLL 文件来从远端计算机显示消息。您可能可以使用 /AUXSOURCE= 标识来检索词描述;查看帮助和支持以了解详细信息。下列信息是事件的一部分: http://go.microsoft.com/fwlink?LinkID=45839.
百思不得其解,忽然注意到:LocalService不是任何登录用户,一般是Administrator。
恍然大悟,原来这个程序时发生的现象是因为: 程序正常是因为手动双击文件启动。而不正常,则是因为此程序使用服务(允许与桌面交互)启动。
测试,手动启动下,以上奇怪问题均消失。
以服务启动所需程序的方法:(服务默认以System帐户启动程序,故使用CreateProcessAsUser启动所需进程)
uses TLHelp32;
//取得Explorer.exe ProcessID
function GetExplorerProcessId:Hwnd;
var
Pn: TProcesseNtry32;
hProcess:THandle;
H: Hwnd;
Found: Boolean;
begin
H := 0;
Result := 0;
//取所有进程的列表快照
hProcess:= CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);
Found := Process32First(sHandle, Pn);
while Found do
begin
if UpperCase(Pn.szExeFile) = 'EXPLORER.EXE' then
begin
Result := Pn.th32ProcessID;
Exit;
end;
Found := Process32Next(sHandle, Pn);
end;
end;
function StartProcessAsUser(const ACommandLine : String;AParam:String=''): Byte;
var
hToken:thandle;
ph:THandle;
si:STARTUPINFO;
pi:PROCESS_INFORMATION;
ExplHwnd:Hwnd;
begin
ExplHwnd:=GetExplorerProcessId;
if ExplHwnd<=0 then Exit;
ph:=OpenProcess(PROCESS_ALL_ACCESS ,
false,
ExplHwnd);
if ph<=0 then exit;
OpenProcessToken( ph,TOKEN_ALL_ACCESS,hToken); //取Explorer进程Token===>取当前桌面帐户Token
try
ZeroMemory( @si, sizeof( STARTUPINFO ) );
si.cb := sizeof( STARTUPINFO );
Si.lpDesktop := PChar('Winsta0\Default');
si.wShowWindow:=SW_SHOWNORMAL;
CreateProcessAsUser(hToken,
pchar(ACommandLine) ,
pchar(AParam),
nil,
nil,
FALSE,
CREATE_DEFAULT_ERROR_MODE,
nil,
nil,
si,
pi );
finally
closehandle(ph);
end;
end;