C#编写的服务程序,用来每分钟一次地检测个USB设备是否被拨下,如果被拨下,就调用一个窗体程序,显示警告信息,并使蜂鸣器发声。因为需要访问局域网内其它电脑的资源,所以用来启动服务的用户帐户不是System(默认的System是没有网络访问权限的),而是另建立了一个管理员帐户,专门用来启动并登录此服务。由此,那个“允许服务与桌面交互”的选项是灰的,不能选的。
----------------以上是前提介绍-------------------------------为了能在服务里启动并显示报警窗体,程序调用了如下代码。问题就是,这段代码在win2000环境下是很正常的,窗体能显示出来,但是在winXP下就不行了,界面看不到,但确实是运行了的,进程里面有,请问有什么办法解决?
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public class SECURITY_ATTRIBUTES
{
public int nLength;
public string lpSecurityDescriptor;
public bool bInheritHandle;
}[StructLayout(LayoutKind.Sequential)]
public struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public int lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public int wShowWindow;
public int cbReserved2;
public byte lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[DllImport("Kernel32.dll", CharSet = CharSet.Ansi)]
public static extern bool CreateProcess(
StringBuilder lpApplicationName, StringBuilder lpCommandLine,
SECURITY_ATTRIBUTES lpProcessAttributes,
SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
int dwCreationFlags,
StringBuilder lpEnvironment,
StringBuilder lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
ref PROCESS_INFORMATION lpProcessInformation
);[DllImport("Kernel32.dll")]
public static extern uint WaitForSingleObject(System.IntPtr hHandle, uint dwMilliseconds);[DllImport("Kernel32.dll")]
public static extern bool CloseHandle(System.IntPtr hObject);[DllImport("Kernel32.dll")]
static extern bool GetExitCodeProcess(System.IntPtr hProcess, ref uint lpExitCode);/////////////////////////////////////////////////////////////////////////////////////////////////string argm = "调用的exe程序路径";
STARTUPINFO sInfo = new STARTUPINFO();
sInfo.lpDesktop = "Winsta0\\Default";
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
if (!CreateProcess(null, new StringBuilder(argm), null, null, false, 0, null, null, ref sInfo, ref pInfo))
{
throw new Exception("调用失败");
}
uint i = 0;
WaitForSingleObject(pInfo.hProcess, int.MaxValue);
GetExitCodeProcess(pInfo.hProcess, ref i);
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
----------------以上是前提介绍-------------------------------为了能在服务里启动并显示报警窗体,程序调用了如下代码。问题就是,这段代码在win2000环境下是很正常的,窗体能显示出来,但是在winXP下就不行了,界面看不到,但确实是运行了的,进程里面有,请问有什么办法解决?
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public class SECURITY_ATTRIBUTES
{
public int nLength;
public string lpSecurityDescriptor;
public bool bInheritHandle;
}[StructLayout(LayoutKind.Sequential)]
public struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public int lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public int wShowWindow;
public int cbReserved2;
public byte lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[DllImport("Kernel32.dll", CharSet = CharSet.Ansi)]
public static extern bool CreateProcess(
StringBuilder lpApplicationName, StringBuilder lpCommandLine,
SECURITY_ATTRIBUTES lpProcessAttributes,
SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
int dwCreationFlags,
StringBuilder lpEnvironment,
StringBuilder lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
ref PROCESS_INFORMATION lpProcessInformation
);[DllImport("Kernel32.dll")]
public static extern uint WaitForSingleObject(System.IntPtr hHandle, uint dwMilliseconds);[DllImport("Kernel32.dll")]
public static extern bool CloseHandle(System.IntPtr hObject);[DllImport("Kernel32.dll")]
static extern bool GetExitCodeProcess(System.IntPtr hProcess, ref uint lpExitCode);/////////////////////////////////////////////////////////////////////////////////////////////////string argm = "调用的exe程序路径";
STARTUPINFO sInfo = new STARTUPINFO();
sInfo.lpDesktop = "Winsta0\\Default";
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
if (!CreateProcess(null, new StringBuilder(argm), null, null, false, 0, null, null, ref sInfo, ref pInfo))
{
throw new Exception("调用失败");
}
uint i = 0;
WaitForSingleObject(pInfo.hProcess, int.MaxValue);
GetExitCodeProcess(pInfo.hProcess, ref i);
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
解决方案 »
- 本人新手,急求一段串口通信高频采集代码
- 怎么将参数做方法名使用?
- 将图片以路径的方式存到数据库中,并在WINFORM中显示
- combobox控件的DropDownStyle属性为DropDown情况下,如何让combobox不能输入东西?
- ==========WebService初学问题===============
- 想给初学的朋友们一些建议
- 请问哪位有使用sockets(c#)进行TCP/UDP通信的源代码的例子?
- 请问如何只根据时间来选取数据库数据啊
- 怎样在C#中动态加载可视化组件?
- 急! 急!那位大侠知道在C#中类似TabControl控件分页但不显示页标头,类似VC中的东东
- c#中树的用法
- 求用C#做的绘图程序画笔怎么写
Process p = new Process();
...
p.Start();
p.WaitForExit();如果是.net 1.1就没有p.WaitForExit,但可以使用其它的方法来等待线程运行结束。参考Process的用法。
http://www.cnblogs.com/qkhh/archive/2009/03/18/1415390.html
2、如果机器需要用户登录,把检测程序放到用户启动项里,而不是做成服务。
3、如果服务偶尔要显示信息,用WTSSendString API,该对话框会自动超时退出,不会永远阻碍服务。
4、如果一定要创建用户桌面进程,则可以从服务里偷一个用户Token,然后CreateProcessAsUser。
任务栏?底部?你点击一下看能否打开。如果可以,你用api:SetForegroundWindow试试。