HI,
我在 Windows 7 上有 C# WCF Windows 服务,以具有管理员权限的用户身份登录。
我正在尝试在服务启动后启动桌面应用程序。我发现的所有讨论都是关于 Windows 工作站和桌面...我创建了一个单独的线程,设置线程工作站和桌面,并尝试启动桌面应用程序。
当我使用 asp.net 开发服务器从 VS2010 启动代码时,代码可以工作,但如果从服务启动,则没有错误,但进程未启动。我尝试以不同的用户身份启动进程,并尝试调用 CreateProcessWithLogonW (将 startInfo.lpDesktop 设置为“winsta0\default”;之前)。在这两种情况下,我都返回了 processId,但看不到桌面应用程序。
有人可以帮我看看哪里有错误吗?
public class ExternalProcess
{
const int READ_CONTROL = 0x20000;
const int WRITE_DAC = 0x40000;
const int DESKTOP_WRITEOBJECTS = 0x80;
const int DESKTOP_READOBJECTS = 0x1;
private Process extProcess;
private string sFilePath = "";
[DllImport("user32.dll")]
private static extern bool SetThreadDesktop(IntPtr hDesktop);
[DllImport("user32.dll")]
static extern IntPtr OpenDesktop(string lpszDesktop, uint dwFlags,bool fInherit, uint dwDesiredAccess);
[DllImport("user32.dll")]
private static extern IntPtr GetProcessWindowStation();
[DllImport("user32.dll")]
private static extern IntPtr OpenWindowStation(string lpszWinSta, bool fInherit, ACCESS_MASK dwDesiredAccess);
[DllImport("user32.dll")]
private static extern IntPtr SetProcessWindowStation(IntPtr hWinsta);
public bool StartProcess(string filePath)
{
sFilePath = filePath;
Thread t = new Thread(new ThreadStart(Thread_StartProcess));
t.Start();
return true;
}
private void Thread_StartProcess()
{
IntPtr hwinstaSave;
IntPtr hwinsta, hwinsta2;
IntPtr hdesk;
hwinstaSave = GetProcessWindowStation();
System.Console.WriteLine("GetProcessWindowStation Lasterror= " + Marshal.GetLastWin32Error().ToString());
System.Console.WriteLine("GetProcessWindowStation hwinstaSave= " + hwinstaSave.ToString());
//hwinsta = OpenWindowStation("winsta0", false, ACCESS_MASK.GENERIC_EXECUTE | ACCESS_MASK.DESKTOP_CREATEWINDOW | ACCESS_MASK.DESKTOP_CREATEMENU | ACCESS_MASK.DESKTOP_SWITCHDESKTOP | ACCESS_MASK.DESKTOP_WRITEOBJECTS);
hwinsta = OpenWindowStation("winsta0", false, ACCESS_MASK.WINSTA_ALL_ACCESS); // when call from windows service OpenWindowStation returns 0
System.Console.WriteLine("OpenWindowStation lasterror = " + Marshal.GetLastWin32Error().ToString());
System.Console.WriteLine("OpenWindowStation hwinsta= " + hwinsta.ToString());
hwinsta2 = SetProcessWindowStation(hwinsta);
System.Console.WriteLine("SetProcessWindowStation lasterror = " + Marshal.GetLastWin32Error().ToString());
System.Console.WriteLine("SetProcessWindowStation hwinsta2= " + hwinsta2.ToString());
hdesk = OpenDesktop("default", 0, true, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS);
System.Console.WriteLine("OpenDesktop lasterror = " + Marshal.GetLastWin32Error().ToString());
System.Console.WriteLine("OpenDesktop hdesk= " + hdesk.ToString());
bool Success = SetThreadDesktop(hdesk);
System.Console.WriteLine("SetThreadDesktop lasterror = " + Marshal.GetLastWin32Error().ToString());
System.Console.WriteLine("SetThreadDesktop Success= " + Success.ToString());
try
{
extProcess = new Process();
extProcess.StartInfo.FileName = sFilePath;
extProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
if (extProcess.Start())
System.Console.WriteLine("Process started ");
else
System.Console.WriteLine("Not started!");
}
catch (Win32Exception e)
{
System.Console.WriteLine("Start {0} failed. Error: " + e.Message);
}
}
}
交互式Windows 服务在Windows Vista 中进行了以安全为中心的改造。服务现在在隔离的“会话 0”中运行,无法轻松地将窗口注入交互式用户会话中。上面的代码将在会话 0 中创建 GUI 元素,即使选中了“允许服务与桌面交互”,这些元素也不会显示在任何用户的桌面上。
有关 Windows 服务限制的更多详细信息,请参见这份来自微软的技术文档 http://www.microsoft.com/whdc/system/sysinternals/session0changes.mspx.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)