c# - 在新桌面中启动进程
问题描述
我正在尝试在新桌面上启动一个进程。
这是我到目前为止的代码,但它会在后台打开进程。
新桌面完美创建。所以这一切都很好。
但是,新进程不会在新桌面中打开。
我需要把外部进程放到前面或者在新桌面打开
关于在新桌面中启动该过程,我在哪里做错了?
你能帮忙吗?
感谢您的任何意见
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
namespace AntiKeylogger
{
// public partial class Program : NetkioskVDesktop.Form1
// public partial class Program :
static class Program
{
[DllImport("user32.dll")]
public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags, uint dwDesiredAccess, IntPtr lpsa);
[DllImport("user32.dll")]
private static extern bool SwitchDesktop(IntPtr hDesktop);
[DllImport("user32.dll")]
public static extern bool CloseDesktop(IntPtr handle);
[DllImport("user32.dll")]
public static extern bool SetThreadDesktop(IntPtr hDesktop);
[DllImport("user32.dll")]
public static extern IntPtr GetThreadDesktop(int dwThreadId);
[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();
enum DESKTOP_ACCESS : uint
{
DESKTOP_NONE = 0,
DESKTOP_READOBJECTS = 0x0001,
DESKTOP_CREATEWINDOW = 0x0002,
DESKTOP_CREATEMENU = 0x0004,
DESKTOP_HOOKCONTROL = 0x0008,
DESKTOP_JOURNALRECORD = 0x0010,
DESKTOP_JOURNALPLAYBACK = 0x0020,
DESKTOP_ENUMERATE = 0x0040,
DESKTOP_WRITEOBJECTS = 0x0080,
DESKTOP_SWITCHDESKTOP = 0x0100,
GENERIC_ALL = (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU |
DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK |
DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP),
}
[DllImport("kernel32.dll")]
private static extern bool CreateProcess(
string lpApplicationName,
string lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
int dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory);
static void Main(string[] args)
{
IntPtr hOldDesktop = GetThreadDesktop(GetCurrentThreadId());
IntPtr hNewDesktop = CreateDesktop("RandomDesktopName", IntPtr.Zero, IntPtr.Zero, 0, (uint)DESKTOP_ACCESS.GENERIC_ALL, IntPtr.Zero);
SwitchDesktop(hNewDesktop);
Task.Factory.StartNew(() =>
{
SetThreadDesktop(hNewDesktop);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new NetkioskVDesktop.Form1());
Process.Start("C:\\Windows\\System32\\Notepad.exe");
}).Wait();
SwitchDesktop(hOldDesktop);
CloseDesktop(hNewDesktop);
}
}
}
解决方案
[DllImport("user32.dll")]
public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags, uint dwDesiredAccess, IntPtr lpsa);
[DllImport("user32.dll")]
private static extern bool SwitchDesktop(IntPtr hDesktop);
[DllImport("user32.dll")]
public static extern bool CloseDesktop(IntPtr handle);
[DllImport("user32.dll")]
public static extern bool SetThreadDesktop(IntPtr hDesktop);
[DllImport("user32.dll")]
public static extern IntPtr GetThreadDesktop(int dwThreadId);
[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();
enum DesktopAccess : uint
{
DesktopReadobjects = 0x0001,
DesktopCreatewindow = 0x0002,
DesktopCreatemenu = 0x0004,
DesktopHookcontrol = 0x0008,
DesktopJournalrecord = 0x0010,
DesktopJournalplayback = 0x0020,
DesktopEnumerate = 0x0040,
DesktopWriteobjects = 0x0080,
DesktopSwitchdesktop = 0x0100,
GenericAll = DesktopReadobjects | DesktopCreatewindow | DesktopCreatemenu |
DesktopHookcontrol | DesktopJournalrecord | DesktopJournalplayback |
DesktopEnumerate | DesktopWriteobjects | DesktopSwitchdesktop
}
public Form1()
{
InitializeComponent();
}
//You must press this button to start
private void btnInit_Click(object sender, EventArgs e)
{
Init();
}
private static void Init()
{
// old desktop's handle, obtained by getting the current desktop assigned for this thread
var hOldDesktop = GetThreadDesktop(GetCurrentThreadId());
// new desktop's handle, assigned automatically by CreateDesktop
var hNewDesktop = CreateDesktop(GetRandomName(), IntPtr.Zero, IntPtr.Zero, 0, (uint)DesktopAccess.GenericAll, IntPtr.Zero);
// switching to the new desktop
SwitchDesktop(hNewDesktop);
// Random login form: used for testing / not required
var passwd = "";
// running on a different thread, this way SetThreadDesktop won't fail
Task.Factory.StartNew(() =>
{
// assigning the new desktop to this thread - so the Form will be shown in the new desktop)
SetThreadDesktop(hNewDesktop);
var inbox = new CustomInbox();
inbox.FormClosing += (sender, e) => { passwd = inbox.Value; };
Application.Run(inbox);
}).Wait(); // waits for the task to finish
// end of login form
// if got here, the form is closed => switch back to the old desktop
SwitchDesktop(hOldDesktop);
// disposing the secure desktop since it's no longer needed
CloseDesktop(hNewDesktop);
MessageBox.Show(@"Password, typed inside secure desktop: " + passwd, @"Notice", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
//This get a random name for the new desktop
private static string GetRandomName()
{
var value = DateTime.Now.ToLongTimeString();
value = value.GetHashCode().ToString().Replace("-", "").ToLowerInvariant();
return value;
}
推荐阅读
- javascript - 如何等待 forEach 方法
- angular - 剑道网格列模板中的调用函数
- python - CSV 输出的 Web 抓取文件路径
- json - 用 groovy 更新 json 文件后,文件数据包含额外的大括号和“内容”对象
- python - Keras LSTM 准确率停留在 50%
- python - 每天生成日期和向前填充列
- javascript - 是否
- android - Google Ad Manager AdListener#onAdClicked() 回调未触发
- php - 在 handle() 之后在自定义工匠命令上运行代码
- javascript - Firebase - 获取最新文档