我尝试在clac.exe
显示 windows(7 和 xp)登录屏幕之前(或恰好在何时)运行进程。
我尝试了该gpedit.msc
方法(将 calc.exe 添加到Startup
),onLogin/onLogout
仅适用。
然后我创建了一个新的windows服务,
代码(我的大部分代码来自:Running a Form in Windows Logon Screen C#):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Runtime.InteropServices;
namespace WindowsService2
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
[DllImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.U4)]
public static extern int WTSGetActiveConsoleSessionId();
[DllImport("wtsapi32.dll", SetLastError = true)]
static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr Token);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private extern static bool DuplicateTokenEx(
IntPtr hExistingToken,
uint dwDesiredAccess,
ref SECURITY_ATTRIBUTES lpTokenAttributes,
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
TOKEN_TYPE TokenType,
out IntPtr phNewToken);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CreateProcessAsUser(
IntPtr hToken,
string lpApplicationName,
string lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool AdjustTokenPrivileges(IntPtr tokenhandle,
[MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges,
[MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES newstate,
uint bufferlength, IntPtr previousState, IntPtr returnlength);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(IntPtr ProcessHandle,
UInt32 DesiredAccess, out IntPtr TokenHandle);
public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
public const UInt32 TOKEN_DUPLICATE = 0x0002;
public const UInt32 TOKEN_IMPERSONATE = 0x0004;
public const UInt32 TOKEN_QUERY = 0x0008;
public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID);
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
enum SECURITY_IMPERSONATION_LEVEL
{
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
}
public enum TOKEN_TYPE
{
TokenPrimary = 1,
TokenImpersonation
}
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
public UInt32 PrivilegeCount;
public LUID Luid;
public UInt32 Attributes;
public LUID_AND_ATTRIBUTES[] Privileges;
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public uint LowPart;
public int HighPart;
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
out LUID lpLuid);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[Flags]
enum CreateProcessFlags : uint
{
DEBUG_PROCESS = 0x00000001,
DEBUG_ONLY_THIS_PROCESS = 0x00000002,
CREATE_SUSPENDED = 0x00000004,
DETACHED_PROCESS = 0x00000008,
CREATE_NEW_CONSOLE = 0x00000010,
NORMAL_PRIORITY_CLASS = 0x00000020,
IDLE_PRIORITY_CLASS = 0x00000040,
HIGH_PRIORITY_CLASS = 0x00000080,
REALTIME_PRIORITY_CLASS = 0x00000100,
CREATE_NEW_PROCESS_GROUP = 0x00000200,
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
CREATE_SEPARATE_WOW_VDM = 0x00000800,
CREATE_SHARED_WOW_VDM = 0x00001000,
CREATE_FORCEDOS = 0x00002000,
BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,
ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,
INHERIT_PARENT_AFFINITY = 0x00010000,
INHERIT_CALLER_PRIORITY = 0x00020000,
CREATE_PROTECTED_PROCESS = 0x00040000,
EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000,
PROCESS_MODE_BACKGROUND_END = 0x00200000,
CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
CREATE_NO_WINDOW = 0x08000000,
PROFILE_USER = 0x10000000,
PROFILE_KERNEL = 0x20000000,
PROFILE_SERVER = 0x40000000,
CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000,
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public UInt32 Attributes;
}
public class RunProcess
{
public void log(string error)
{
throw new Exception(error);
}
public void StartProcess(string pathOrName)
{
Process winLogon = null;
foreach (Process p in Process.GetProcesses())
{
if (p.ProcessName.Contains("winlogon"))
{
winLogon = p;
break;
}
}
// grab the winlogon's token
IntPtr userToken = IntPtr.Zero;
if (!OpenProcessToken(winLogon.Handle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, out userToken))
{
log("ERROR: OpenProcessToken returned false - " + Marshal.GetLastWin32Error());
}
WTSQueryUserToken((uint)WTSGetActiveConsoleSessionId(), out userToken);
// create a new token
IntPtr newToken = IntPtr.Zero;
SECURITY_ATTRIBUTES tokenAttributes = new SECURITY_ATTRIBUTES();
tokenAttributes.nLength = Marshal.SizeOf(tokenAttributes);
SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES();
threadAttributes.nLength = Marshal.SizeOf(threadAttributes);
// duplicate the winlogon token to the new token
if (!DuplicateTokenEx(userToken, 0x10000000, ref tokenAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
TOKEN_TYPE.TokenImpersonation, out newToken))
{
log("ERROR: DuplicateTokenEx returned false - " + Marshal.GetLastWin32Error());
}
TOKEN_PRIVILEGES tokPrivs = new TOKEN_PRIVILEGES();
tokPrivs.PrivilegeCount = 1;
LUID seDebugNameValue = new LUID();
if (!LookupPrivilegeValue(null, "SeDebugPrivilege", out seDebugNameValue))
{
log("ERROR: LookupPrivilegeValue returned false - " + Marshal.GetLastWin32Error());
}
tokPrivs.Privileges = new LUID_AND_ATTRIBUTES[1];
tokPrivs.Privileges[0].Luid = seDebugNameValue;
tokPrivs.Privileges[0].Attributes = 0x00000002;
if (!AdjustTokenPrivileges(newToken, false, ref tokPrivs, 0, IntPtr.Zero, IntPtr.Zero))
{
log("ERROR: AdjustTokenPrivileges returned false - " + Marshal.GetLastWin32Error());
}
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
STARTUPINFO si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = "Winsta0\\Winlogon";
// start the process using the new token
if (!CreateProcessAsUser(newToken, "calc.exe", null, ref tokenAttributes, ref threadAttributes,true, (uint)CreateProcessFlags.CREATE_NEW_CONSOLE | (uint)CreateProcessFlags.INHERIT_CALLER_PRIORITY, IntPtr.Zero,"C:\\Windows\\System32", ref si, out pi))
{
log("ERROR: CreateProcessAsUser returned false - " + Marshal.GetLastWin32Error());
}
Process _p = Process.GetProcessById(pi.dwProcessId);
if (_p != null)
{
log("Process " + _p.Id + " Name " + _p.ProcessName);
}
else
{
log("Not Found");
}
}
}
RunProcess r = new RunProcess();
protected override void OnStart(string[] args)
{
r.StartProcess("calc.exe");
}
protected override void OnStop()
{
r.log("Stoped");
}
}
}
我通过这一行安装了服务:
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe" "c:\myservice.exe"
现在我确实重新启动了。
然后我检查了显示登录屏幕时是否正在运行进程,然后我发现没有计算器窗口,也没有名为calc
运行的进程。
然后我看到“ WindowsService2
”没有运行(在 上taskmgr
)。
所以我觉得是可以修好的(我不会这么快就放弃的,今天一定要完成),问题是:
为什么它不起作用,我现在需要做什么来检查它为什么不起作用?
我更喜欢:
在登录屏幕(XP 和 Windows 7)之前还有其他方法(或方法)运行进程吗?
(好的答案是很好的例子加上很好的解释):)
编辑:
解决方案在安装中,
安装日志:
Installing assembly 'c:\WindowsService2.exe'.
Affected parameters are:
logtoconsole =
logfile = c:\WindowsService2.InstallLog
assemblypath = c:\WindowsService2.exe
No public installers with the RunInstallerAttribute.Yes attribute could be found in the c:\WindowsService2.exe assembly.
Committing assembly 'c:\WindowsService2.exe'.
Affected parameters are:
logtoconsole =
logfile = c:\WindowsService2.InstallLog
assemblypath = c:\WindowsService2.exe
No public installers with the RunInstallerAttribute.Yes attribute could be found in the c:\WindowsService2.exe assembly.
Remove InstallState file because there are no installers.
无法安装,因为:
No public installers with the RunInstallerAttribute.Yes attribute could be found in the c:\WindowsService2.exe assembly.
我现在该怎么办?:S
(我试过public static readonly RunInstallerAttribute Yes;
了,我什至试图以cmd.exe
管理员身份运行)