我正在构建Windows服务。它需要使用当前用户特权运行命令并删除与子字符串相匹配的所有存储的凭据 - 例如" mystring"。
我在createprocessasuser方法中调用了其他模块。但是,调用cmd.exe模块并传递复杂命令似乎很棘手。
我可能缺少一些逃生字符或一些其他命令行参数,导致复杂命令无法成功运行。如果我调用我的服务,我可以看到cmd提示启动,但不会执行命令。
我确实试图将其进行故障排除。我直接在命令CMD提示符中对其进行了测试。
这是示例:
直接来自CMD提示:
FOR /F "usebackq tokens=1* delims=: " %i in (`cmdkey /list^|findstr MYSTRING`) do cmdkey /delete:%j
通过run box
执行时,同一命令失败:
cmd.exe /K FOR /F "usebackq tokens=1* delims=: " %%i in (`cmdkey /list^|findstr MYSTRING`) do cmdkey /delete:%%j
我尝试添加双引号,逃脱特殊字符,但它不起作用。以下是这样的例子。
cmd.exe /K "FOR /F ^"usebackq tokens=1* delims=: ^" %%i in (`cmdkey /list^|findstr ADAL`) do cmdkey /delete %%j"
cmd.exe /K "FOR /F ^"usebackq tokens=1* delims^=: ^" %%i in (^`cmdkey /list^|findstr ADAL^`) do cmdkey /delete %%j"
事先感谢您的帮助。
编辑:
基于图坎的输入,我能够从运行框运行命令。但是,当我在C#代码中尝试相同的操作时,它在命令提示符中丢弃错误。
命令提示中的错误(由服务创建的过程):
tokens = 1 * delims =:"目前是出乎意料的。
下面是C#方法。
public static bool ClearCredsCache()
{
var hUserToken = IntPtr.Zero;
var startInfo = new STARTUPINFO();
var procInfo = new PROCESS_INFORMATION();
var pEnv = IntPtr.Zero;
int iResultOfCreateProcessAsUser;
//String cmdLine = "cmd.exe "FOR / F "usebackq tokens=1* delims=: " %%i in (`cmdkey / list ^| findstr MYSTRING`) do cmdkey / list %%j"& pause";
String cmdLine = "cmd.exe /K FOR /F "usebackq tokens = 1 * delims =: " %i in (`cmdkey /list^|findstr MYSTRING`) do cmdkey /delete:%j";
//String cmdLine = null;
String appPath = "cmd.exe";
String workDir = null;
bool visible = true;
startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));
try
{
if (!GetSessionUserToken(ref hUserToken))
{
throw new CredMgmtException(CredMgmtException.medium, "StartProcessAsCurrentUser: GetSessionUserToken failed.");
}
uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint)(visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW);
startInfo.wShowWindow = (short)(visible ? SW.SW_SHOW : SW.SW_HIDE);
startInfo.lpDesktop = null;
if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false))
{
throw new CredMgmtException(CredMgmtException.medium, "StartProcessAsCurrentUser: CreateEnvironmentBlock failed.");
}
if (!CreateProcessAsUser(hUserToken,
appPath, // Application Name
cmdLine, // Command Line
IntPtr.Zero,
IntPtr.Zero,
false,
dwCreationFlags,
pEnv,
workDir, // Working directory
ref startInfo,
out procInfo))
{
iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();
throw new CredMgmtException(CredMgmtException.medium, "StartProcessAsCurrentUser: CreateProcessAsUser failed. Error Code -" + iResultOfCreateProcessAsUser);
}
iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();
}
finally
{
CloseHandle(hUserToken);
if (pEnv != IntPtr.Zero)
{
DestroyEnvironmentBlock(pEnv);
}
CloseHandle(procInfo.hThread);
CloseHandle(procInfo.hProcess);
}
//stdOut.
// CredMgmtUtil.WriteEvent("Startupinfo=" + startInfo.hStdOutput)
return true;
}
我确实从run box
进行了测试,并且在Windows 7 x64上没有错误的情况下执行良好。
cmd.exe /K FOR /F "usebackq tokens=1* delims=: " %i in (`cmdkey /list^|findstr tukan`) do echo "test"
双向(cmd.exe
& run box
)正确产生两个回声线。
您有什么窗户?如果您在cmd.exe
中执行,只需cmdkey /list^|findstr ADAL
您得到什么?