CFExecute not performing command - coldfusion

<cfset LOCAL.cmd = expandPath('..\library\gm.exe') />
<cfset LOCAL.args = "convert image1.jpg image2.jpg" />
<cfexecute variable="gm" errorVariable="error"
name="#LOCAL.cmd#"
timeout="10"
arguments="#local.args#" />
<cfdump var="#gm#" />
This code always results in an empty string in gm. No matter how I execute gm with or without parameters. Other examples work fine like running cmd.exe or netstat.exe as is in the CFDocs example. I get no errors thrown or warnings in errorVariable, it simply does nothing.
I modified the code, this version does not work either:
<cfset LOCAL.cmd = expandPath('..\library\gm.exe') />
<cfset LOCAL.args = "convert ""#variables.uploadDirectory##LOCAL.file.source#"" ""#variables.uploadDirectory#optimal-#LOCAL.file.source#""" />
<cfexecute errorVariable="error"
name="c:\windows\system32\cmd.exe"
timeout="10"
outputFile="#expandPath('.\gm.log')#"
arguments="/C #local.cmd# #LOCAL.args#" />

Permissions problems are the most common cause. However, if you are running CF8, you might also try redirecting the error stream and adding an explicit terminate flag. Just to see if you get any output or see different behavior. Early versions did not capture the error stream, which caused some processes to hang. It was fixed in one of the CF8 updaters.
Update: I just noticed your image paths are relative. Perhaps the program is having difficulty locating them. Try using absolute paths for the images.
Update: I tested it with CF9. It does work when using absolute image paths. Though the "gm" variable is understandably empty, since the output is directed to an image file.
<cfexecute variable="gm"
errorVariable="errorOut"
name="C:\GraphicsMagick-1.3.12-Q16\gm.exe"
timeout="10"
arguments="convert c:\art.gif c:\artCopyFromCF9.gif" />
<cfdump var="#variables#">

Without seeing code or your server setup, I would guess you need to check permissions for the user account CF runs under.
If CF is running under the default user, you may need to create a user with access to whatever it is you are trying to do. Then change the service(s) to run under this user. Alternately, you could assign more liberal permissions to the resource you're trying to access.

I have also encountered this with cfexecute and GraphicsMagick. I think the deal is that GM is operating asynchronously and returns before it completes. Running some tests with outputFile/errorFile instead of their variable equivalents, followed by cffile reading the fileInfo on the output file (which is empty per the test script but observed to have contents when opened), I see that the modified time of the output file with contents is actually after the last modified timestamp yielded by FileInfo.
I think if you output to a session variable or something of the sort that could be picked up by another template you could observe the results of the execution having populated the session variable, provided the other template executes after the variable is actually set.

Related

Executing a batch file using CFEXECUTE

I tried to run test.bat file using cfexecute. It shows timeout error after loding for sometime. The output file is blank. But when i double click the test.bat file it works fine. My code is this,
<cfexecute name="C:\Windows\System32\cmd.exe" arguments="/C C:\ColdFusion2018\cfusion\wwwroot\test.bat" timeout="60" outputfile="C:\ColdFusion2018\cfusion\wwwroot\log_output1.txt"></cfexecute>
We recommend using CFX_EXEC (Windows) instead of the built-in CFExecute. When running BAT files, we've encountered many cases where we needed to run it under a separate Windows account that had privileges different than the CF Service. CFX_EXEC enabled us to specify the specific account whereas CFExecute doesn't have the option at all. We also use CFX_EXEC for performing IP/DNS look-ups as it's a lot faster than Java, honors TTL and doesn't cache the lookup results "forever".
If you want to run test.bat using cfexecute, test.bat should be the value of the name attribute, not the arguments attribute.
<cfexecute name="C:\ColdFusion2018\cfusion\wwwroot\test.bat"
timeout="60"
arguments ="whatever applies"
outputfile="C:\ColdFusion2018\cfusion\wwwroot\log_output1.txt">
</cfexecute>
Thanks for your response,
The batch file successfully executed after suppressing the 'Press any key to continue..'(pause) in the command line. It makes the cfexecute loading till timeout. That was the issue here.

coldfusion 8 and 2016: CFEXECUTE not returning result/error

All I get in my browser is a blank screen. If I don't use IsDefined, I would get an error in the page stating the variable doesn't exists.
If I misspell a command (example: using /bin/bsh instead of /bin/bash), I get an exception stating CF cannot find the program. So it seems to be working. I just want to check if it's really running.
Here's my code:
------
<cfexecute name="/bin/ls" arguments=" -la /" errorVariable="error" variable="result"></cfexecute>
<cfif IsDefined("result")>
<cfdump var="#result#">
</cfif>
<cfif IsDefined("error")>
<cfdump var="#error#">
</cfif>
<cfexecute name="/bin/bash" arguments=" -c '/bin/ls -la /'" errorVariable="error" variable="result"></cfexecute>
<cfif IsDefined("result")>
<cfdump var="#result#">
</cfif>
<cfif IsDefined("error")>
<cfdump var="#error#">
</cfif>
You need to specify a timeout on cfexecute in order to get a valid result/error sequentially.
The default timeout is 0, which is non-blocking, which means your command is executing asynchronously. This means you don't immediately have a result.
I'm not sure whether, to Adobe, "non-blocking" means the variable and error attributes are ignored completely or eventually set. If you're curious you could toss in a cfsleep and find out, just please not in production. :)
You have to specify the Absolute path of the application to execute.On Windows, specify an extension, for example, C:\myapp.exe.
I've run the my sqlCMD by using cfexecute, Here I've passed the absolute path of an MS sql server.
<cfexecute name="C:\Program Files\Microsoft SQL Server2016\Client SDK\ODBC\130\Tools\Binn\SQLCMD.EXE" arguments=" -S localhost -U sa -P sqlPwd#12## -i" timeout="0" errorFile="#logsDir#/#TableSqls.name#_error.txt">
</cfexecute>
I hope it's will help you.

<cffile action="write"> refusing to work

I'm pulling my hair our here and really can't figure out why this code will not work. I need to use <cffile action="write"> to put a document on the server.
I've stripped the code to its bare minimum in an attempt to get the file to write to the server, however it still won't budge. The code I am running is this.
<cffile action = "write"
file = "test.txt"
output = "Content"
>
When I run this code on the server, it does nothing. I get no error messages on-screen, however no file appears on the server either.
I've been searching for a while and the only thing I could seem to come up with was writing the absolute file path, so I've also tried this too
<cffile action = "write"
file = "http://www.my_url.com/test.txt"
output = "Content"
>
Which does get me an error message (see below), however searches for how to sort this error message have been less than useful.
An error occurred when performing a file operation write on file
http://www.my_url.com/test.txt.
The cause of this exception was: java.io.FileNotFoundException:
http://www.my_url.com/test.txt.
I thought this could be a problem with my privileges, however there is no 'access is denied' error on the end of the FileNotFound, so I really am lost as to what to do.
It's doubly infuriating because on this exact site I am also using <cffile action="upload"> which works absolutely fine!
As mentioned above, cffile only operates on the server file system. So you need to use a physical file path, not a url. Also, the documentation says if you use a relative path the file is written to:
"...(a path) relative to the ColdFusion temporary directory, which
is returned by the GetTempDirectory function."
So if you did not receive an error, the file was created, just not where you expected. To avoid this kind of confusion, use absolute paths:
<cffile action="write" file="c:/path/to/test.txt" output="Content">

First call to Windows Performance Counters (PDH) sometimes fails

I'm having a problem where sometimes my code will function correctly, but other times it will fail.
This is the first bit of PDH related code that I run:
const std::wstring pidWildcardPath = L"\\Process(*)\\ID Process";
DWORD bufferSize = 0;
LPTSTR paths = NULL;
PDH_STATUS status = PdhExpandCounterPath(
pidWildcardPath.c_str(),
paths,
&bufferSize);
checkPDHStatus(status, PDH_MORE_DATA, L"Expected request for more data.");
The result of the PdhExpandCounterPath function call is 0x800007D0 (PDH_CSTATUS_NO_MACHINE). The checkPDHStatus function is a simple function that I wrote that asserts that the status is equal to the second parameter. In this case, I expect the result to be PDH_MORE_DATA because paths is NULL and bufferSize is 0. The goal of this call is to determine the size of the buffer I must allocate to store all of the results for a subsequent call to PdhExpandCounterPath. This is described in the PDH documentation under the Remarks section.
The list of PDH error codes describes PDH_MORE_DATA as "Unable to connect to the specified computer, or the computer is offline." As you can see by the performance counter path in the code above, I am not even trying to connect to a different computer than my own.
It is interesting the way that this code fails. Sometimes it works fine and then other times, it will fail on multiple back-to-back executions of my application. I have #include <pdh.h> in my header file and I have a section in my property sheet for this DLL that looks like this:
<Tool
Name="VCLinkerTool"
AdditionalDependencies="pdh.lib"
/>
I'm not sure if it matters, but this program is built by Visual Studio 2005 and run on Windows XP. Am I doing something incorrectly?
I'm a co-worker of Dave's and have discovered the following during my investigation:
the code above runs fine when run from a logged-in interactive session
the code runs fine when initiated as a Scheduled Task AND the user is logged in at the time the scheduled task is fired off
the code FAILS only when run as a Scheduled Task AND the user is NOT logged in at the time the task starts
the code continues to fail if the user logs in after the failing task has started but while it is still running (because it is looping "endlessly" until it gets a PDH_MORE_DATA status back).
In the failing instances, the following environment variables have not been established/set for the program: APPDATA, HOMEDRIVE and HOMEPATH ... I don't think this is a problem. However, the failing program also lacks the SeCreateGlobalPrivilege from its token; the passing programs all have this privilege in the token and PERFMON shows it as "Default Enabled". The other difference is that failing program has the NT_AUTH\BATCH user group in the token, while the passing program has NT_AUTH\INTERACTIVE instead ... all other user groups and privileges are the same for both cases. I think the global privilege is coming from the interactive login, but don't know if it has any bearing on PDH operation.
I cannot find anything in the Performance Counter/PDH documentation that talks about needing any special permissions or privileges for this functionality to succeed. Is the global privilege required to use Performance Counters ?
Or is there some other context/environment difference between running Scheduled Tasks (as a specific user) when that user is/isn't logged in at the time the task starts, that would account for the PDH call succeeding/failing respectively ?
Try this format, indicating the local computer:
const std::wstring pidWildcardPath = L"\\.\Process(*)\ID Process";

What XSLT do you use to format MsBuild XML output in CruiseControl.Net?

We currently don't format our msbuild output in CC.NET (CruiseControl.Net) and as a result, finding the cause of a broken build involves reading the XML to find the last 'success="false"' instance in the output.
What XSLT do you use to format your msbuild output, and are you happy with the resulting HTML? I.e. do you find it easy to identify the cause of a broken build?
Thanks
b
EDIT:
Here's a sanitised sample of one of our CC project XML elements. I'm now wondering whether the merge of logs is the issue.
<project name="StackOverflowSample">
<workingDirectory>D:\_300</workingDirectory>
<webURL>&viewFarmReportWebURL;</webURL>
<sourcecontrol type="multi">
<sourceControls>
<vsts>
<!-- We get latest from TSF -->
</vsts>
</sourceControls>
</sourcecontrol>
<triggers>
<intervalTrigger seconds="60" />
</triggers>
<tasks>
<msbuild>
<executable>&msbuildExecutable;</executable>
<workingDirectory>app\consoleApp1</workingDirectory>
<projectFile>consoleApp1.sln</projectFile>
<buildArgs>/noconlog /p:Configuration=Release /v:quiet</buildArgs>
<logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,"D:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll"</logger>
</msbuild>
<nunit>
<path>&nunitConsoleExecutable;</path>
<assemblies>
<assembly> D:\_300\app\consoleApp1\bin\Release\consoleApp1.exe</assembly>
</assemblies>
</nunit>
<exec>
<executable>&ncoverExecutable;</executable>
<buildArgs>"&nunitConsoleExecutable;" "app\consoleApp1\bin\Release\consoleApp1.exe" /nologo</buildArgs>
</exec>
<exec>
<executable>&ndependExecutable;</executable>
<buildArgs>D:\_300\app\consoleApp1.xml /Silent</buildArgs>
</exec>
<merge>
<files>
<file>D:\_300\app\consoleApp1\unit-test.xml</file>
<file>D:\_300\app\consoleApp1\ApplicationMetrics.xml</file>
<file>D:\_300\app\consoleApp1\AssembliesBuildOrder.xml</file>
<file>D:\_300\app\consoleApp1\AssembliesDependencies.xml</file>
<file>D:\_300\app\consoleApp1\AssembliesMetrics.xml</file>
<file>D:\_300\app\consoleApp1\CQLResult.xml</file>
<file>D:\_300\app\consoleApp1\InfoWarnings.xml</file>
<file>D:\_300\app\consoleApp1\NDependMain.xml</file>
<file>D:\_300\app\consoleApp1\TypesDependencies.xml</file>
<file>D:\_300\app\consoleApp1\TypesMetrics.xml</file>
</files>
</merge>
</tasks>
<publishers>
<merge>
<files>
<file>D:\_300\app\consoleApp1\SymbolModule.Xml</file>
</files>
</merge>
<xmllogger logDir="." />
&emailconsoleApp1;
</publishers>
</project>
I've tried CruiseControl.Net 1.4.4.83 with Rodemeyer.MsBuildToCCnet.dll 1.0.0.5 as a logger coupled with msbuild2ccnet.xsl, and the output is nothing like the output samples from the article:
Build started
Project "" (Integration.Common.csproj target(s)):
error CS1002:
Build succeeded
error CS1002:
1 Error(s)
0 Warning(s)
Time elapsed
Using ThoughtWorks.CruiseControl.MSBuild.dll as a logger coupled with msbuild.xsl, the results are just fine:
Build started 07/16/2009 13:46:38
Person.cs (18,53): error CS1002: ; expected
Build FAILED
Person.cs (18,53): error CS1002: ; expected
1 Error(s)
0 Warning(s)
Time elapsed 00:00:00
After a conversation the developers (I have been told that the alternative logger you link to is quite old and it's usage is discouraged), I am using the default, standard logger and xslt. If it does cause problems for you, please report a bug on CruiseControl.Net Jira, the more people vote on this the sooner someone with commit access to the code might look into it.
"View Build Log" is a raw view, not usable except for debugging the build server setup - for some of my project this is almost 5MB large and does not cause any problems for the server (although opening it hangs the browser for a while). NCover can cause problems inflating buildlog.xml to over 100MB - you have to use NCoverExplorer to analyze the results before merging them if this happens(but don't bother before you start getting exceptions from the server).
To see the formatted MSBuild results in the WebDashboard, make sure that the dashboard configuration includes msbuild.xsl (this will give you a link to "MSBuild Report" on ViewBuildReport page and include some basic information on the page itself).
It feels a bit wierd answering my own question, but there is a chance that someone might have the same question and appreciate my answer so here it is.
I visited the following page http://confluence.public.thoughtworks.org/display/CCNETCOMM/Improved+MSBuild+Integration that describes the use of a different logger than the traditional logger (normal logger produces very large files that bog the server down when performing the XSLT transformations).
The page provides the logger and an XSLT file along with simple and clear instructions on how to incorporate this into your CC.Net project. I tried this logger and XSLT and found I was still getting the raw XML; in fact, ALL of the XML combined in one HUGE page.