以下是映射主驱动器和W驱动器的Windows服务。如果我在用户下执行代码,一切都很好。由于这是在本地系统下运行的服务,因此我使用模拟类来调用它。在为桌面上的驱动器创建快捷方式时,模拟可以很好地工作,但是它不会使用net use命令映射驱动器。我希望驱动器映射为非持久性。我在下面附上了我的完整代码以及模拟课程。有没有办法使用模拟在当前用户下映射这些非持久的驱动器?
namespace HdriveMapService2
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
using (ImpersonationUtils.ImpersonateCurrentUser())
//check if Hdrive exists
if (!Directory.Exists(@"H:\"))
{
//ping Hdrive server
try
{ //find current domain controller
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
string controller = context.ConnectedServer;
//ping current domain controller
Ping ping = new Ping();
PingReply pingReply = ping.Send(controller);
if (pingReply.Status == IPStatus.Success)
{
try
{
//get current username
string username = Environment.UserName;
Console.WriteLine(username);
Console.ReadLine();
//Lookup current username in AD
DirectoryEntry myLdapConnection = createDirectoryEntry();
DirectorySearcher search = new DirectorySearcher(myLdapConnection);
search.Filter = "(cn=" + username + ")";
//Search for User's Home Directory
string[] requiredProperties = new string[] { "homeDirectory" };
foreach (String property in requiredProperties)
search.PropertiesToLoad.Add(property);
SearchResult result = search.FindOne();
// If home directory info is not blank
if (result != null)
{
//pass the homedirectory path into a variable
string path = "";
foreach (String property in requiredProperties)
foreach (Object myCollection in result.Properties[property])
path = (myCollection.ToString());
//map Hdrive (non persistent map)
//create a desktop shortcut to Hdrive
var wsh = new IWshShell_Class();
IWshRuntimeLibrary.IWshShortcut shortcut = wsh.CreateShortcut(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\H Drive.lnk") as IWshRuntimeLibrary.IWshShortcut;
shortcut.TargetPath = path;
shortcut.Save();
//map Wdrive (non persistent map)
//create a desktop shortcut to Wdrive
var wsh2 = new IWshShell_Class();
IWshRuntimeLibrary.IWshShortcut shortcut2 = wsh2.CreateShortcut(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\W Drive.lnk") as IWshRuntimeLibrary.IWshShortcut;
shortcut2.TargetPath = @"\\path\path-groups";
shortcut2.Save();
System.Diagnostics.Process.Start("net.exe", "use /persistent:NO H: " + path);
System.Diagnostics.Process.Start("net.exe", @"use /persistent:NO W: \\path\path-groups");
}
}
catch (Exception)
{
//do nothing
}
}
}
}
catch (Exception)
{
//do nothing
}
}
}
//Impersonation Class
public static class ImpersonationUtils
{
private const int SW_SHOW = 5;
private const int TOKEN_QUERY = 0x0008;
private const int TOKEN_DUPLICATE = 0x0002;
private const int TOKEN_ASSIGN_PRIMARY = 0x0001;
private const int STARTF_USESHOWWINDOW = 0x00000001;
private const int STARTF_FORCEONFEEDBACK = 0x00000040;
private const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
private const int TOKEN_IMPERSONATE = 0x0004;
private const int TOKEN_QUERY_SOURCE = 0x0010;
private const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
private const int TOKEN_ADJUST_GROUPS = 0x0040;
private const int TOKEN_ADJUST_DEFAULT = 0x0080;
private const int TOKEN_ADJUST_SESSIONID = 0x0100;
private const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
private const int 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)]
private struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential)]
private struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
[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;
}
private enum SECURITY_IMPERSONATION_LEVEL
{
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
}
private enum TOKEN_TYPE
{
TokenPrimary = 1,
TokenImpersonation
}
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CreateProcessAsUser(
IntPtr hToken,
string lpApplicationName,
string lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
int dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool DuplicateTokenEx(
IntPtr hExistingToken,
int dwDesiredAccess,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
int ImpersonationLevel,
int dwTokenType,
ref IntPtr phNewToken);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(
IntPtr ProcessHandle,
int DesiredAccess,
ref IntPtr TokenHandle);
[DllImport("userenv.dll", SetLastError = true)]
private static extern bool CreateEnvironmentBlock(
ref IntPtr lpEnvironment,
IntPtr hToken,
bool bInherit);
[DllImport("userenv.dll", SetLastError = true)]
private static extern bool DestroyEnvironmentBlock(
IntPtr lpEnvironment);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(
IntPtr hObject);
private static void LaunchProcessAsUser(string cmdLine, IntPtr token, IntPtr envBlock, int sessionId)
{
var pi = new PROCESS_INFORMATION();
var saProcess = new SECURITY_ATTRIBUTES();
var saThread = new SECURITY_ATTRIBUTES();
saProcess.nLength = Marshal.SizeOf(saProcess);
saThread.nLength = Marshal.SizeOf(saThread);
var si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = @"WinSta0\Default";
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
si.wShowWindow = SW_SHOW;
if (!CreateProcessAsUser(
token,
null,
cmdLine,
ref saProcess,
ref saThread,
false,
CREATE_UNICODE_ENVIRONMENT,
envBlock,
null,
ref si,
out pi))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateProcessAsUser failed");
}
}
internal static void LaunchAsCurrentUser(Process process)
{
throw new NotImplementedException();
}
internal static void LaunchAsCurrentUser(string v1, string v2)
{
throw new NotImplementedException();
}
private static IDisposable Impersonate(IntPtr token)
{
var identity = new WindowsIdentity(token);
return identity.Impersonate();
}
private static IntPtr GetPrimaryToken(Process process)
{
var token = IntPtr.Zero;
var primaryToken = IntPtr.Zero;
if (OpenProcessToken(process.Handle, TOKEN_DUPLICATE, ref token))
{
var sa = new SECURITY_ATTRIBUTES();
sa.nLength = Marshal.SizeOf(sa);
if (!DuplicateTokenEx(
token,
TOKEN_ALL_ACCESS,
ref sa,
(int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
(int)TOKEN_TYPE.TokenPrimary,
ref primaryToken))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "DuplicateTokenEx failed");
}
CloseHandle(token);
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "OpenProcessToken failed");
}
return primaryToken;
}
private static IntPtr GetEnvironmentBlock(IntPtr token)
{
var envBlock = IntPtr.Zero;
if (!CreateEnvironmentBlock(ref envBlock, token, false))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateEnvironmentBlock failed");
}
return envBlock;
}
public static void LaunchAsCurrentUser(string cmdLine)
{
var process = Process.GetProcessesByName("explorer")[0];
if (process != null)
{
var token = GetPrimaryToken(process);
if (token != IntPtr.Zero)
{
var envBlock = GetEnvironmentBlock(token);
if (envBlock != IntPtr.Zero)
{
LaunchProcessAsUser(cmdLine, token, envBlock, process.SessionId);
if (!DestroyEnvironmentBlock(envBlock))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "DestroyEnvironmentBlock failed");
}
}
CloseHandle(token);
}
}
}
public static IDisposable ImpersonateCurrentUser()
{
var process = Process.GetProcessesByName("explorer")[0];
if (process != null)
{
var token = GetPrimaryToken(process);
if (token != IntPtr.Zero)
{
return Impersonate(token);
}
}
throw new Exception("Could not find explorer.exe");
}
}
答案 0 :(得分:0)
我建议您添加一些调试跟踪,看看您的代码实际运行的帐户是什么,然后验证此帐户是否至少允许查看这些UNC路径/共享。
答案 1 :(得分:0)
我采取了不同的方法来解决问题。我将驱动器映射编译为可执行文件。用计时器建立了一个Windows服务。在服务设置项目中添加了可执行文件作为文件,并在模拟下进行了可执行的服务调用,并且一切正常。如果有人有任何问题或正在努力解决类似问题,这可能有所帮助。如果需要,我很乐意提供详细信息。
谢谢,
雷