ASP.NET 3.5 如何通过IIS7 启动与服务器桌面交互的进程?
How to Start a process that interacts with the server's desktop in ASP.NET 3.5 through IIS7?
有很多答案,试试这个那个,但没有任何效果。拒绝访问。
我们在服务器上启动一个应用程序,并自动执行某些快速任务。我当然可以启动它...(但它不能 运行 隐藏,它必须 运行 在真实桌面模式下)。
我尝试了各种不同的 elevation/impersonation 技巧。是的,我选择了 IIS-Interact with desktop 框。在 web.config 我有模拟标志...
以下是相关代码,其中包含一些已注释掉的尝试:
private const int WM_CLOSE = 16;
private const int BN_CLICKED = 245;
private const int LB_GETTEXT = 0x0189;
private const int LB_GETTEXTLEN = 0x018A;
private const int WM_SETTEXT = 0X000C;
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
WindowsImpersonationContext impersonationContext;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
protected static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetProcessWindowStation();
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetThreadDesktop(int dwThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern int GetCurrentThreadId();
public void findOurProcess(string filePath)
{
IntPtr hwnd = IntPtr.Zero;
IntPtr hwnd_select = IntPtr.Zero;
IntPtr hwndChild = IntPtr.Zero;
DateTime timer;
TimeSpan diff;
int processid;
string username = "Programmer";
clsImpersonate cls = new clsImpersonate();
try
{
IntPtr token = cls.ImpersonateUser(username, Environment.MachineName, "RoboMan");
using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(token))
{
//Process process = new Process();
//ProcessStartInfo info = new ProcessStartInfo();
//info.FileName = fileName;
//info.Arguments = argument;
//process.StartInfo = info;
//process.Start();
//if (impersonateValidUser("Programmer", "", "Roboman"))
//if (impersonateValidUser(username, "DESKTOP", "Roboman"))
//{
ProcessStartInfo psi = new ProcessStartInfo("OUR PROCESS");
//psi.UserName = username;
//psi.Domain = Environment.MachineName;
//psi.Password = new System.Security.SecureString();
//psi.Password.AppendChar('R');
//psi.Password.AppendChar('o');
//psi.Password.AppendChar('b');
//psi.Password.AppendChar('o');
//psi.Password.AppendChar('m');
//psi.Password.AppendChar('a');
//psi.Password.AppendChar('n');
psi.Arguments = "-batch";
psi.WorkingDirectory = "OUR DIRECTORY";
psi.UseShellExecute = false;
//myProcess.StartInfo.CreateNoWindow = true; //Maybe?
//myProcess.Start();
//The following security adjustments are necessary to give the new
//process sufficient permission to run in the service's window station
//and desktop. This uses classes from the AsproLock library also from
//Asprosys.
//IntPtr hWinSta = GetProcessWindowStation();
//WindowStationSecurity ws = new WindowStationSecurity(hWinSta,
// System.Security.AccessControl.AccessControlSections.Access);
////ws.AddAccessRule(new WindowStationAccessRule(username,
// // WindowStationRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
//ws.AddAccessRule(new WindowStationAccessRule(username,
// WindowStationRights.CreateDesktop, System.Security.AccessControl.AccessControlType.Allow));
//ws.AcceptChanges();
//IntPtr hDesk = GetThreadDesktop(GetCurrentThreadId());
//DesktopSecurity ds = new DesktopSecurity(hDesk,
// System.Security.AccessControl.AccessControlSections.Access);
//ds.AddAccessRule(new DesktopAccessRule(username,
// DesktopRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
//ds.AcceptChanges();
using (Process process = Process.Start(psi))
{
processid = process.Id;
}
the cls.ImpersonateUser The above attempts to run an elevated section of code as another user. But fails. You can see I've attempted to use this version as well. ImpersonateValidUser Example
AsProSys 代码还会在 ws.AcceptChanges(); 上抛出拒绝访问的异常;
WebServers 运行 作为 Windows 服务。自 Windows Vista 起,Windows 服务默认禁止访问桌面。
除了一般的服务限制外,网络服务器还习惯于 运行 尽可能限制用户权限。对其程序和内容目录的读取访问是他们所能获得的最好的。它们始终处于打开状态,因此极易受到黑客攻击。
据我了解,目前您正尝试从 Web 服务器启动 Dekstop 应用程序。这几乎是不行的。如果 确实 有效,我首先想知道我能多快卸载它。然后我一开始就没有设法限制以防止这种情况发生。对于每个必须 运行 您的网页的管理员:停止尝试这样做!
相反,只需安装通常安装在 Windows 上的 Helper 应用程序。让它在用户登录时通过 TaskSheduler 自动启动。并让它和 WebServer 通过管道、Loopback 设备或 WebServer 可接受的类似 IPC 方式进行通信。
有很多答案,试试这个那个,但没有任何效果。拒绝访问。 我们在服务器上启动一个应用程序,并自动执行某些快速任务。我当然可以启动它...(但它不能 运行 隐藏,它必须 运行 在真实桌面模式下)。
我尝试了各种不同的 elevation/impersonation 技巧。是的,我选择了 IIS-Interact with desktop 框。在 web.config 我有模拟标志...
以下是相关代码,其中包含一些已注释掉的尝试:
private const int WM_CLOSE = 16;
private const int BN_CLICKED = 245;
private const int LB_GETTEXT = 0x0189;
private const int LB_GETTEXTLEN = 0x018A;
private const int WM_SETTEXT = 0X000C;
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
WindowsImpersonationContext impersonationContext;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
protected static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetProcessWindowStation();
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetThreadDesktop(int dwThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern int GetCurrentThreadId();
public void findOurProcess(string filePath)
{
IntPtr hwnd = IntPtr.Zero;
IntPtr hwnd_select = IntPtr.Zero;
IntPtr hwndChild = IntPtr.Zero;
DateTime timer;
TimeSpan diff;
int processid;
string username = "Programmer";
clsImpersonate cls = new clsImpersonate();
try
{
IntPtr token = cls.ImpersonateUser(username, Environment.MachineName, "RoboMan");
using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(token))
{
//Process process = new Process();
//ProcessStartInfo info = new ProcessStartInfo();
//info.FileName = fileName;
//info.Arguments = argument;
//process.StartInfo = info;
//process.Start();
//if (impersonateValidUser("Programmer", "", "Roboman"))
//if (impersonateValidUser(username, "DESKTOP", "Roboman"))
//{
ProcessStartInfo psi = new ProcessStartInfo("OUR PROCESS");
//psi.UserName = username;
//psi.Domain = Environment.MachineName;
//psi.Password = new System.Security.SecureString();
//psi.Password.AppendChar('R');
//psi.Password.AppendChar('o');
//psi.Password.AppendChar('b');
//psi.Password.AppendChar('o');
//psi.Password.AppendChar('m');
//psi.Password.AppendChar('a');
//psi.Password.AppendChar('n');
psi.Arguments = "-batch";
psi.WorkingDirectory = "OUR DIRECTORY";
psi.UseShellExecute = false;
//myProcess.StartInfo.CreateNoWindow = true; //Maybe?
//myProcess.Start();
//The following security adjustments are necessary to give the new
//process sufficient permission to run in the service's window station
//and desktop. This uses classes from the AsproLock library also from
//Asprosys.
//IntPtr hWinSta = GetProcessWindowStation();
//WindowStationSecurity ws = new WindowStationSecurity(hWinSta,
// System.Security.AccessControl.AccessControlSections.Access);
////ws.AddAccessRule(new WindowStationAccessRule(username,
// // WindowStationRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
//ws.AddAccessRule(new WindowStationAccessRule(username,
// WindowStationRights.CreateDesktop, System.Security.AccessControl.AccessControlType.Allow));
//ws.AcceptChanges();
//IntPtr hDesk = GetThreadDesktop(GetCurrentThreadId());
//DesktopSecurity ds = new DesktopSecurity(hDesk,
// System.Security.AccessControl.AccessControlSections.Access);
//ds.AddAccessRule(new DesktopAccessRule(username,
// DesktopRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
//ds.AcceptChanges();
using (Process process = Process.Start(psi))
{
processid = process.Id;
}
the cls.ImpersonateUser The above attempts to run an elevated section of code as another user. But fails. You can see I've attempted to use this version as well. ImpersonateValidUser Example AsProSys 代码还会在 ws.AcceptChanges(); 上抛出拒绝访问的异常;
WebServers 运行 作为 Windows 服务。自 Windows Vista 起,Windows 服务默认禁止访问桌面。
除了一般的服务限制外,网络服务器还习惯于 运行 尽可能限制用户权限。对其程序和内容目录的读取访问是他们所能获得的最好的。它们始终处于打开状态,因此极易受到黑客攻击。
据我了解,目前您正尝试从 Web 服务器启动 Dekstop 应用程序。这几乎是不行的。如果 确实 有效,我首先想知道我能多快卸载它。然后我一开始就没有设法限制以防止这种情况发生。对于每个必须 运行 您的网页的管理员:停止尝试这样做!
相反,只需安装通常安装在 Windows 上的 Helper 应用程序。让它在用户登录时通过 TaskSheduler 自动启动。并让它和 WebServer 通过管道、Loopback 设备或 WebServer 可接受的类似 IPC 方式进行通信。