C#代码转成delphi的 本帖最后由 mfpg01 于 2010-07-21 16:48:57 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 从windows服务中打开窗口进程2008-07-02 14:19从windows服务中打开窗口进程AVR地方业务中有一个DBA_BJLDNW工具要在服务器上运行着.一旦断开业务即中止.需要写一个守护程序监视它,一旦发现关闭了即重新启动.为了防止守护程序本身被用户关闭,所以我打算做一个windows服务在后台运行.每5分钟列举一个当前系统进程,如果没有发现DBA_BJLDNW.exe则重新启动.问题是windows服务不是窗口进程,在这个进程中调用ShellExecute打开的应用程序也是在后台运行,不能显示在当前窗口中.后来搜索到可以在Windows服务中打开窗口程序的方法.就是打开用户WinSta0和desktop,取得和用户交互的权限后再打开窗口进程,果然可以在windows服务中打开窗口进程了: HINSTANCE hProcessSnap = NULL;PROCESSENTRY32 pe32 = {0};//获取进程的内存镜照hProcessSnap = (HINSTANCE) ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);if(hProcessSnap == (HANDLE) -1) return ;pe32.dwSize = sizeof(PROCESSENTRY32);DWORD flag = 0;CString theProcssName = "DBA_BJLDNW.exe";//列举进程if(::Process32First(hProcessSnap,&pe32)){ do{ if(!theProcssName.CompareNoCase(pe32.szExeFile)){ flag = 1; break; } } while(Process32Next(hProcessSnap,&pe32));}::CloseHandle(hProcessSnap);if(!flag){ //如果没有找到 HDESK hdeskCurrent; HDESK hdesk; HWINSTA hwinstaCurrent; HWINSTA hwinsta; hwinstaCurrent = GetProcessWindowStation(); if (hwinstaCurrent == NULL){ LogEvent(_T("get window station err")); return ; } hdeskCurrent = GetThreadDesktop(GetCurrentThreadId()); if (hdeskCurrent == NULL){ LogEvent(_T("get window desktop err")); return ; }//打开用户的winsta0 hwinsta = OpenWindowStation("winsta0", FALSE, WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES); if (hwinsta == NULL){ LogEvent(_T("open window station err")); return ; } if (!SetProcessWindowStation(hwinsta)){ LogEvent(_T("Set window station err")); return ; } //打开desktop hdesk = OpenDesktop("default", 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); if (hdesk == NULL){ LogEvent(_T("Open desktop err")); return; } SetThreadDesktop(hdesk); ::ShellExecute(0,NULL,"f:\\ivrtj\\DBA\\DBA_BJLDNW.exe",NULL,NULL,SW_MAXIMIZE); CString msg = "DBA_BJLDNW.exe 被重启动"; LogEvent(msg); SetProcessWindowStation(hwinstaCurrent); SetThreadDesktop(hdeskCurrent); CloseWindowStation(hwinsta); CloseDesktop(hdesk);}服务安装后一定要注意,右键->属性->登录,选择 本地系统帐户下面的允许服务与桌面交互打勾.用代码注册一个程序为系统服务时,会在注册表中建立一个类似HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\服务名 下面有一个REG_DWORD类型的叫Type,当这个值是10的时候,表示这个是不允许桌面交互的,此时这个服务启动时即使有界面也不显示,当把它改成110的时候,就会显示界面了,注意10和110都是指的十六进制。 这个是标准的VC++程序,不是C#程序。就是调用了一堆WindowsAPI,不是什么难的东西。楼主自己一个函数一个函数的对应查找,应该不会有什么问题的。 这些函数在Delphi中都已经引用了,自己找找吧。 谁给个Delphi下载地址 菜鸟提问 大家帮帮忙,如何让DBgrid在添加删除数据后后即时刷新? 如何在DELPHI中直接操作ODBC数据源 关于dll的编写?用delphi我不太清楚,高手请指点,谢谢! 关于cxtreelist的显示问题 我有一段代码,但运行时好象总不对!请各位兄弟帮帮忙 如何引入flash动画???? 送分小问题 下面这段代码里 哪些属于post提交的数据包? 帮忙看看这个过程里加函数的写法,不懂 如何解决服务端程序经常出错
2008-07-02 14:19
从windows服务中打开窗口进程AVR地方业务中有一个DBA_BJLDNW工具要在服务器上运行着.一旦断开业务即中止.需要写一个守护程序监视它,一旦发现关闭了即重新启动.为了防止守护程序本身被用户关闭,所以我打算做一个windows服务在后台运行.每5分钟列举一个当前系统进程,如果没有发现DBA_BJLDNW.exe则重新启动.问题是windows服务不是窗口进程,在这个进程中调用ShellExecute打开的应用程序也是在后台运行,不能显示在当前窗口中.后来搜索到可以在Windows服务中打开窗口程序的方法.就是打开用户WinSta0和desktop,取得和用户交互的权限后再打开窗口进程,果然可以在windows服务中打开窗口进程了: HINSTANCE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};//获取进程的内存镜照
hProcessSnap = (HINSTANCE) ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hProcessSnap == (HANDLE) -1) return ;
pe32.dwSize = sizeof(PROCESSENTRY32);DWORD flag = 0;
CString theProcssName = "DBA_BJLDNW.exe";//列举进程if(::Process32First(hProcessSnap,&pe32)){
do{
if(!theProcssName.CompareNoCase(pe32.szExeFile)){
flag = 1;
break;
}
}
while(Process32Next(hProcessSnap,&pe32));
}
::CloseHandle(hProcessSnap);if(!flag){ //如果没有找到 HDESK hdeskCurrent;
HDESK hdesk;
HWINSTA hwinstaCurrent;
HWINSTA hwinsta; hwinstaCurrent = GetProcessWindowStation(); if (hwinstaCurrent == NULL){
LogEvent(_T("get window station err"));
return ;
} hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
if (hdeskCurrent == NULL){
LogEvent(_T("get window desktop err"));
return ;
}//打开用户的winsta0
hwinsta = OpenWindowStation("winsta0", FALSE,
WINSTA_ACCESSCLIPBOARD |
WINSTA_ACCESSGLOBALATOMS |
WINSTA_CREATEDESKTOP |
WINSTA_ENUMDESKTOPS |
WINSTA_ENUMERATE |
WINSTA_EXITWINDOWS |
WINSTA_READATTRIBUTES |
WINSTA_READSCREEN |
WINSTA_WRITEATTRIBUTES);
if (hwinsta == NULL){
LogEvent(_T("open window station err"));
return ;
} if (!SetProcessWindowStation(hwinsta)){
LogEvent(_T("Set window station err"));
return ;
} //打开desktop
hdesk = OpenDesktop("default", 0, FALSE,
DESKTOP_CREATEMENU |
DESKTOP_CREATEWINDOW |
DESKTOP_ENUMERATE |
DESKTOP_HOOKCONTROL |
DESKTOP_JOURNALPLAYBACK |
DESKTOP_JOURNALRECORD |
DESKTOP_READOBJECTS |
DESKTOP_SWITCHDESKTOP |
DESKTOP_WRITEOBJECTS);
if (hdesk == NULL){
LogEvent(_T("Open desktop err"));
return;
} SetThreadDesktop(hdesk); ::ShellExecute(0,NULL,"f:\\ivrtj\\DBA\\DBA_BJLDNW.exe",NULL,NULL,SW_MAXIMIZE);
CString msg = "DBA_BJLDNW.exe 被重启动";
LogEvent(msg); SetProcessWindowStation(hwinstaCurrent);
SetThreadDesktop(hdeskCurrent);
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
}服务安装后一定要注意,右键->属性->登录,选择 本地系统帐户下面的允许服务与桌面交互打勾.用代码注册一个程序为系统服务时,会在注册表中建立一个类似HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\服务名
下面有一个REG_DWORD类型的叫Type,当这个值是10的时候,表示这个是不允许桌面交互的,此时这个服务启动时即使有界面也不显示,当把它改成110的时候,就会显示界面了,注意10和110都是指的十六进制。
就是调用了一堆WindowsAPI,不是什么难的东西。
楼主自己一个函数一个函数的对应查找,应该不会有什么问题的。