Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

SOLVED: Windows cmd.exe for loop issue

Indranil:

I am building a Windows Service. It needs to run a command using current user privileges and delete all stored credentials which matches a substring - e.g. "MYSTRING".

I have invoked other modules in CreateProcessAsUser method which does work. However, invoking a cmd.exe module and passing complex command seems to be tricky.

I am probably missing some escape characters or some additional command line arguments, causing complex command to fail to run successfully. If I invoke my service I can see cmd prompt starting, but it does not execute the command.

I did try to troubleshoot it. I tested it in the command cmd prompt directly, which works.

Here are the examples:

Directly from cmd prompt:


FOR /F "usebackq tokens=1* delims=: " %i in (`cmdkey /list^|findstr MYSTRING`) do cmdkey /delete:%j

Same command fails when executed via the run box:


cmd.exe /K FOR /F "usebackq tokens=1* delims=: " %%i in (`cmdkey /list^|findstr MYSTRING`) do cmdkey /delete:%%j

I tried adding double quotes, escaping special characters, but somehow it is not working. Below are such examples.


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"

Thanks in advance for your help.

Edit:

Based on tukan's input I was able to run the command from run box. However, when I try the same in the C# code, it is throwing error in the command prompt.

Error in command prompt (process created by service):

tokens = 1 * delims =: " was unexpected at this time.

Below is the C# method.


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;
}



Posted in S.E.F
via StackOverflow & StackExchange Atomic Web Robots
This Question have been answered
HERE


This post first appeared on Stack Solved, please read the originial post: here

Share the post

SOLVED: Windows cmd.exe for loop issue

×

Subscribe to Stack Solved

Get updates delivered right to your inbox!

Thank you for your subscription

×