我正在尝试部署一个作为后台服务运行的控制台应用程序,该控制台应用程序会截取用户当前屏幕的屏幕截图并将其保存在 blob 容器中,当我手动单击 exe 文件时,代码可以在本地计算机和虚拟机上完美运行并运行它,但是当我通过创建服务来自动化相同的操作时,存储在 blob 中的所有 ss 都是空白的,有人可以帮助我知道发生了什么吗?
我正在尝试将 ss 保存在 blob 文件中,以便 c# 控制台应用程序应该在我的 azure vm 中作为后台服务工作,但是该服务正在运行,存储在 blob 中的 ss 是空白的,但是当我通过单击它手动运行 exe 文件时,它是很好
你有两个选择。你可以:
假设您的代码是 C#.NET(不太难反应为 C# 或 C++)...
枚举会话
using System;
using System.Runtime.InteropServices;
public class SessionHelper
{
[DllImport("wtsapi32.dll")]
private static extern bool WTSEnumerateSessions(IntPtr hServer, int Reserved, int Version, ref IntPtr ppSessionInfo, ref int pCount);
[DllImport("wtsapi32.dll")]
private static extern void WTSFreeMemory(IntPtr pMemory);
[DllImport("wtsapi32.dll")]
private static extern bool WTSQueryUserToken(uint sessionId, out IntPtr phToken);
public static uint GetActiveSessionId()
{
IntPtr ppSessionInfo = IntPtr.Zero;
int count = 0;
if (WTSEnumerateSessions(IntPtr.Zero, 0, 1, ref ppSessionInfo, ref count))
{
int dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
long current = (long)ppSessionInfo;
for (int i = 0; i < count; i++)
{
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO));
current += dataSize;
if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive)
{
WTSFreeMemory(ppSessionInfo);
return si.SessionId;
}
}
WTSFreeMemory(ppSessionInfo);
}
throw new Exception("No active sessions found");
}
public static IntPtr GetUserToken(uint sessionId)
{
if (!WTSQueryUserToken(sessionId, out IntPtr token))
throw new Exception("Could not get user token");
return token;
}
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public uint SessionId;
[MarshalAs(UnmanagedType.LPStr)]
public string pWinStationName;
public WTS_CONNECTSTATE_CLASS State;
}
private enum WTS_CONNECTSTATE_CLASS
{
WTSActive
}
}
在用户会话中创建进程using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
public class ProcessHelper
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
public static void StartCaptureProcess(IntPtr userToken)
{
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
si.cb = Marshal.SizeOf(si);
string captureApp = @"C:\Path\To\YourCaptureApp.exe"; // Path to your screen capture application
if (!CreateProcessAsUser(userToken, captureApp, null, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref si, out pi))
throw new Exception("Could not start process in user session");
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
[StructLayout(LayoutKind.Sequential)]
private struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
private struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}
}
确保您遵守法律。用户应该意识到,出于隐私原因和数据保护,他们的会话被捕获。