参考的文章https://blog.csdn.net/Struggle_Cxg/article/details/83302251
https://www.cnblogs.com/gnielee/archive/2010/04/07/session0-isolation-part1.html
https://www.cnblogs.com/masonlu/p/9726541.html
这个功能当时简单试过,没有长时间使用,短期内没有问题。很多代码看不太明白,莫名奇妙的可以用
1、在解决方案下新建个窗体包含如下内容
2具体内容
2.1installservice内容:(bat文件如何生成自己去找)
@echo off
@title 安装windows服务
path %SystemRoot%\Microsoft.NET\Framework\v4.0.30319
echo==============================================================
echo=
echo= windows服务程序安装
echo=
echo==============================================================
@echo off
InstallUtil D:\工作\大屏\收集指标\WindowsFormsApp1\WindowsService2\bin\Debug\WindowsService2.exe
net start WindowsService2
pause
2.2类interop内容,这个还查到一个方法,但是会报错
class Interop
{
public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
/// <summary>
/// 服务程序执行消息提示,前台MessageBox.Show
/// </summary>
/// <param name="message">消息内容</param>
/// <param name="title">标题</param>
public static void ShowServiceMessage(string message, string title)
{
int resp = 0;
WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, WTSGetActiveConsoleSessionId(), title, title.Length, message, message.Length, 0, 0, out resp, false);
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int WTSGetActiveConsoleSessionId();
[DllImport("wtsapi32.dll", SetLastError = true)]
public static extern bool WTSSendMessage(IntPtr hServer, int SessionId, String pTitle, int TitleLength, String pMessage, int MessageLength, int Style, int Timeout, out int pResponse, bool bWait);
#region P/Invoke WTS APIs
private enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct WTS_SESSION_INFO
{
public UInt32 SessionID;
public string pWinStationName;
public WTS_CONNECTSTATE_CLASS State;
}
[DllImport("WTSAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool WTSEnumerateSessions(
IntPtr hServer,
[MarshalAs(UnmanagedType.U4)] UInt32 Reserved,
[MarshalAs(UnmanagedType.U4)] UInt32 Version,
ref IntPtr ppSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref UInt32 pSessionInfoCount
);
[DllImport("WTSAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
static extern void WTSFreeMemory(IntPtr pMemory);
[DllImport("WTSAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr Token);
#endregion
#region P/Invoke CreateProcessAsUser
/// <summary>
/// Struct, Enum and P/Invoke Declarations for CreateProcessAsUser.
/// </summary>
///
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
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, CharSet = CharSet.Auto)]
struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
/// <summary>
/// 以当前登录的windows用户(角色权限)运行指定程序进程
/// </summary>
/// <param name="hToken"></param>
/// <param name="lpApplicationName">指定程序(全路径)</param>
/// <param name="lpCommandLine">参数</param>
/// <param name="lpProcessAttributes">进程属性</param>
/// <param name="lpThreadAttributes">线程属性</param>
/// <param name="bInheritHandles"></param>
/// <param name="dwCreationFlags"></param>
/// <param name="lpEnvironment"></param>
/// <param name="lpCurrentDirectory"></param>
/// <param name="lpStartupInfo">程序启动属性</param>
/// <param name="lpProcessInformation">最后返回的进程信息</param>
/// <returns>是否调用成功</returns>
[DllImport("ADVAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes,
bool bInheritHandles, uint dwCreationFlags, string lpEnvironment, string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("KERNEL32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CloseHandle(IntPtr hHandle);
#endregion
/// <summary>
/// 以当前登录系统的用户角色权限启动指定的进程
/// </summary>
/// <param name="ChildProcName">指定的进程(全路径)</param>
public static void CreateProcess(string ChildProcName)
{
IntPtr ppSessionInfo = IntPtr.Zero;
UInt32 SessionCount = 0;
if (WTSEnumerateSessions(
(IntPtr)WTS_CURRENT_SERVER_HANDLE, // Current RD Session Host Server handle would be zero.
0, // This reserved parameter must be zero.
1, // The version of the enumeration request must be 1.
ref ppSessionInfo, // This would point to an array of session info.
ref SessionCount // This would indicate the length of the above array.
))
{
for (int nCount = 0; nCount < SessionCount; nCount++)
{
WTS_SESSION_INFO tSessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure(ppSessionInfo + nCount * Marshal.SizeOf(typeof(WTS_SESSION_INFO)), typeof(WTS_SESSION_INFO));
if (WTS_CONNECTSTATE_CLASS.WTSActive == tSessionInfo.State)
{
IntPtr hToken = IntPtr.Zero;
if (WTSQueryUserToken(tSessionInfo.SessionID, out hToken))
{
PROCESS_INFORMATION tProcessInfo;
STARTUPINFO tStartUpInfo = new STARTUPINFO();
tStartUpInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));
bool ChildProcStarted = CreateProcessAsUser(
hToken, // Token of the logged-on user.
ChildProcName, // Name of the process to be started.
null, // Any command line arguments to be passed.
IntPtr.Zero, // Default Process' attributes.
IntPtr.Zero, // Default Thread's attributes.
false, // Does NOT inherit parent's handles.
0, // No any specific creation flag.
null, // Default environment path.
null, // Default current directory.
ref tStartUpInfo, // Process Startup Info.
out tProcessInfo // Process information to be returned.
);
if (ChildProcStarted)
{
CloseHandle(tProcessInfo.hThread);
CloseHandle(tProcessInfo.hProcess);
}
else
{
ShowServiceMessage("CreateProcessAsUser失败", "CreateProcess");
}
CloseHandle(hToken);
break;
}
}
}
WTSFreeMemory(ppSessionInfo);
}
}
}
}
2.3主程序program
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
2.4ProjectInstaller
2.5service1
加一个timer控件,添加timer elapsed事件,复制到输出目录选始终复制
public partial class Service1 : ServiceBase
{
public static int AutoInterval { get { return 10000; } }
private bool _IsRunning = false;
public bool IsRunning
{
get { return _IsRunning; }
set { _IsRunning = value; }
}
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
this.timer1.Enabled = true;
this.timer1.Interval = AutoInterval;
}
protected override void OnStop()
{
this.timer1.Enabled = false;
}
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Process[] localByName = Process.GetProcessesByName("WindowsFormsApp1.exe");
if (DateTime.Now.Day.ToString() == "23" & DateTime.Now.ToLongTimeString().ToString() == "19:02:00" )
{
using (StreamWriter sw = new StreamWriter(@"D:\1.txt", true, Encoding.UTF8))//测试用,软件是否运行
{
sw.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
}
Interop.CreateProcess( @"C:\Program Files (x86)\collect\WindowsFormsApp1.exe");
}
else
{
}
}
public bool StartProcess(string filename, string args)
{
try
{
string output;
string parameters = "";
string PathOfBin = args; /*获取路径名*/
parameters = PathOfBin.Trim();
Process myprocess = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo(filename, parameters);
myprocess.StartInfo = startInfo;
myprocess.StartInfo.UseShellExecute = false; /*要重定向IO流,Process对象必须将UseShellExecute属性设置为false*/
myprocess.StartInfo.RedirectStandardInput = true; /*标准输入流的重定向,重定向至Process*/
myprocess.StartInfo.RedirectStandardOutput = true; /*标准输出流的重定向,*/
myprocess.StartInfo.RedirectStandardError = true; myprocess.Start();
myprocess.WaitForExit(); output = myprocess.StandardOutput.ReadToEnd();
if (output.Contains("SUCCESS")) /*判断exe的调用是否成功("SUCCESS"是被调用的exe的标准流输出(如"printf()中的内容"))*/
{
/*弹出提示选择框;若用户选择是的话,进行路径跳转*/
DialogResult result = MessageBox.Show("转换完成,是否跳转到文件生成路径", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
if (result == DialogResult.OK)
{
Process.Start(PathOfBin);
}
else
{
}
}
else
{
MessageBox.Show("转换未完成\n" + "请检查OdrWidth与OdrHeigth的参数", "错误提示");
}
return true;
}
catch (Exception ex)
{
MessageBox.Show("启动应用程序时出错!原因:" + ex.Message);
}
return false;
}
}
2.6UnInstallService
@echo off
@title 卸载windows服务
path %SystemRoot%\Microsoft.NET\Framework\v4.0.30319
echo==============================================================
echo=
echo= windows服务程序卸载
echo=
echo==============================================================
@echo off
InstallUtil D:\工作\大屏\收集指标\WindowsFormsApp1\WindowsService2\bin\Debug\WindowsService2.exe
net stop WindowsService2
pause