Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy can't I access environment variables for CMD.exe if I set them through CreateProcess(CMD.exe, "set ...")?
    primarykey
    data
    text
    <p>See bottom of Q for edits.</p> <p>I'm writing up a plugin in C++ for Notepad++ that will spawn a new process and access VSS through SS.exe for checking in/checking out, etc. </p> <p>Manual commands work fine: <img src="https://i.stack.imgur.com/cehCV.png" alt="Command line works"> </p> <p>But when I create a process to do it <strong><em>in the same folder</em></strong> it fails: <img src="https://i.stack.imgur.com/61A4R.png" alt="Not working"></p> <p>In the above picture, I have the environment variables set in the command that is sent to the created process.</p> <h2>Code:</h2> <pre class="lang-cpp prettyprint-override"><code>void CheckIn() { wcscpy(VSSDir,TEXT("O:\\Modulib\\MOD_C_F")); //CheckWhichDatabase - todo swprintf(CommandLineText, CommandLineLength, TEXT("/K set ssdir=%s &amp; set ssuser=%s") /*&amp; plugins\\VSS\\ss cp $/pcbase/modulib &amp; %s*/, VSSDir, pUsernameShort); int error; memset(&amp;processInfo, 0, sizeof(processInfo)); memset(&amp;startupInfo, 0, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); //::MessageBox(NULL, TEXT("Before Create"), TEXT(""), MB_OK); if (!CreateProcess( TEXT("C:\\Windows\\System32\\cmd.exe"), CommandLineText,//TEXT("/K echo hi &amp;&amp; set ssdir=testestest"), NULL, NULL, TRUE,//FALSE, CREATE_UNICODE_ENVIRONMENT, //NORMAL_PRIORITY_CLASS,//0,//CREATE_NO_WINDOW,// | NULL, NULL,//TEXT("C:\\Windows\\System32"), &amp;startupInfo, &amp;processInfo)) { error = GetLastError(); ::MessageBox(NULL, TEXT("error"), TEXT(""), MB_OK); } //::MessageBox(NULL, TEXT("After create, before wait"), TEXT(""), MB_OK); WaitForSingleObject(processInfo.hProcess, INFINITE); //::MessageBox(NULL, TEXT("After wait, before closehandles"), TEXT(""), MB_OK); TerminateProcess(processInfo.hProcess, 0); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); //::MessageBox(NULL, TEXT("closed"), TEXT(""), MB_OK); } </code></pre> <p><strong>How can I make my automated cmd.exe/ss.exe work, similar to doing it manually?</strong></p> <p>I think this has to do with the way CreateProcess() works and not VSS or CMD.exe, but I am not sure. At first I thought it was the environment variables, but as you can see from the picture I've checked that <a href="http://msdn.microsoft.com/en-US/library/ms181062%28v=vs.80%29.aspx" rel="nofollow noreferrer">SSDIR</a> was set. I'm not familiar with CreateProcess() (if you couldn't tell from all the debug messageboxes) but I couldn't find anything regarding any restrictions of the child process compared to the parent (or any process, for that matter). Is there some reason SS.exe is not able to run properly?</p> <p>I tried looking for error messages/codes that SS.exe might spit out but I just found this <a href="http://support.microsoft.com/kb/151975" rel="nofollow noreferrer">MSDN page</a> that links to itself...</p> <h2>Edit 1:</h2> <p>As noted by Daniel Frey in the comments, my console started with Administrator privileges when I was debugging it with VS2010. Testing an elevated console manually (CMD.exe -> Run as Administrator) showed the same issue which seems to verify this as the cause. <strong>It seems SS.exe doesn't work with drives that are network mapped (if used with administrator privileges) and the fully qualified path to the network folder is required.</strong> Ex: <code>\\path\to\thing</code> instead of <code>X:\thing</code>.</p> <p>On the other hand, after running VS2010 with in a non-elevated state I encounter the same issue. If I place my plugin DLL in the \plugins folder of my Notepad++ installation and run Notepad++ (so not debugging through VS2010) I encounter the same issue. </p> <p>As a test, I manually entered the <code>ssdir</code> and <code>ssuser</code> variables in the cmd.exe prompt after the plugin <em>already sets them</em>. After manually entering them the SS.exe commands work in a <em>non-privileged</em> CMD.exe. Removing <code>/K</code> in my <code>CommandLikeText</code> string doesn't help. It seems to just bring up a CMD.exe, as checking for <code>ssdir</code> or <code>ssuser</code> in the prompt gives me an "environment variables not set" error. </p> <p>It seems that the way CreateProcess handles the passing of the command line arguments (2nd argument of CreateProcess()) isn't working, or I'm doing it wrong. So even though the path issue exists, it is not the (sole) source of my problems.</p> <h2>Edit 2:</h2> <p>Learned that <code>/K</code> (or <code>/C</code> or <code>/S</code>) are needed for the text following "cmd.exe" to be interpreted as command line arguments. I had thought it was only necessary if you were creating a new instance of cmd.exe from within an already opened cmd.exe with the <code>cmd</code> command.</p> <p>Still haven't figured out what was going on with manual passing of commands through the <code>LPTSTR lpCommandLine</code> parameter of <code>CreateProcess()</code>. For now I'm creating an environment block and passing it to CreateProcess instead. The variables stored there seem to be properly accessible compared to the "fake" setting that seemed to occur as described in my previous edit.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload