I am executing a program from inside a service like this:
CreateProcessAsUserWrapper.LaunchChildProcess("C:\\someDirectory\\notify.exe 1");
It works fine with just notify.exe, but it doesn't work when I attempt to send the parameter 1. I get no error or notification, just nothing happens.
The code for CreateProcessAsUserWrapper can be found here:
http://www.getcodesamples.com/src/FBB7577C/7A33AB93
I added a ChildProcArg to try to get it to work
public static void LaunchChildProcess(string ChildProcName, string ChildProcArg)
{
...
bool ChildProcStarted = CreateProcessAsUser(
hToken, // Token of the logged-on user.
ChildProcName, // Name of the process to be started.
ChildProcArg, // Any command line arguments to be passed.
IntPtr.Zero, // Default Process' attributes.
IntPtr.Zero, // Default Thread's attributes.
false, // Does NOT inherit parent's handles.
0, // No any specific creation flag.
null, // Default environment path.
null, // Default current directory.
ref tStartUpInfo, // Process Startup Info.
out tProcessInfo // Process information to be returned.
);
so when I call it, it now looks like this:
CreateProcessAsUserWrapper.LaunchChildProcess("C:\\someDirectory\\notify.exe", "1");
... but it is still not passing the argument. At least the program runs now, but the argument is ignored.
What am I missing?
Thanks in advance.
I figured it out.
For future searchers I will include answer here.
The full program and path must be provided along with the argument.
So I just added this:
ChildProcArg = ChildProcName + " " + ChildProcArg;
... just above this ...
bool ChildProcStarted = CreateProcessAsUser(
hToken, // Token of the logged-on user.
ChildProcName, // Name of the process to be started.
ChildProcArg, // Any command line arguments to be passed.
Related
I'm trying to write a Jenkins plugin that provides Step myStep which expects a block with a single parameter per below
myStep { someParameter -> <user code> }
I've found that BodyInvoker ( retrieved from StepContext.newBodyInvoker() ) provides no facilities to invoke the user provided block with parameters.
Expanding the environment would not be ideal, even though the type of the parameter is serializable ( to/from String ), i'd have to provide additional helpers to carry out this serialization, e.g
myStep { deserialize "${env.value}" <user code> }
do i have any other option to pass a non-string type in to the provided block? would type information of the parameter survive even if i did?
nb: i understand you can return a value from your Execution.run() which will be the return value of the step in the pipeline. It's just that in a related shared pipeline library i'm already heavily leaning in to this pattern of:
withFoo { computedFoo ->
# something with computedFoo
withBar computedFoo { computedBar ->
}
}
i prefer this over
computedFoo = withFoo
# something with computedFoo
withBar(computedFoo)
..then again, i couldn't find any plugins pulling this off.
no matter how close i look at workflow-step-api-plugin this doesn't seem possible today. The options are:
expand the environment context with a string value
add a custom object to the context ( requires access to step context in pipeline )
use a return value
Need to develop a package which should read number of files from ftp/folder. If the count is less than 25 , keep looping, Go to the next task once the count reaches 25.
What i tried is:
I used a script task, created few variable and variable have file count(Successfully). I used expression in precedence constraint for checking if the number of files in a particular folder is 25. if not it wont go to another task. What i cant do is keep the script task looping until the file count becomes 25. I tried using for each loop but couldn't get trough. please suggest.
Please have a look at this. i have 2 script tasks. first one counts and display the number of files in a folder. here is the script for that.
enter code here
public void Main()
{
// TODO: Add your code here
String FolderPath =
Dts.Variables["User::FolderPath"].Value.ToString();
string Prefix =
Dts.Variables["User::prefix"].Value.ToString();
Int32 FileCnt = 0;
var directory = new DirectoryInfo(FolderPath);
FileInfo[] files = directory.GetFiles(Prefix + "*");
//Declare and initilize variables
//Get one Book(Excel file at a time)
foreach (FileInfo file in files)
{
FileCnt += 1;
MessageBox.Show(file.Name);
}
MessageBox.Show(FileCnt.ToString());
Dts.Variables["User::FileCnt"].Value =
Convert.ToInt32(FileCnt);
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of
this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
then i edited the precedence constraint and wrote and expression #FileCnt == 25, which means next script task will only be executed when the number of files in the folder is 25. what i want now is that the first script task should be running in a loop until the folder gets 25 file. i think we need to use foreachloop container here. did you get what im looking for now??
2 Jenkins jobs: A and B.
A triggers B as blocking build step ("Block until the triggered projects finish their builds"). Is there a way to include B's console output into A's console output?
Motivation: for browser use of Jenkins A's console output contains a link to B's console output which is fine. But when using Jenkins via command line tools (jenkins-cli) there's no quick and easy way to see B's console output.
Any ideas?
Interesting. I'd try something like this.
From http://jenkinsurl/job/jobname/lastBuild/api/
Accessing Progressive Console Output
You can retrieve in-progress console output by making repeated GET requests with a parameter. You'll basically send GET request to this URL (or this URL if you want HTML that can be put into tag.) The start parameter controls the byte offset of where you start.
The response will contain a chunk of the console output, as well as the X-Text-Size header that represents the bytes offset (of the raw log file). This is the number you want to use as the start parameter for the next call.
If the response also contains the X-More-Data: true header, the server is indicating that the build is in progress, and you need to repeat the request after some delay. The Jenkins UI waits 5 seconds before making the next call. When this header is not present, you know that you've retrieved all the data and the build is complete.
So you can trigger a downstream job, but don't "block until downstream completes". Instead, add an extra step (execute shell, probably) and write a script that will read the console output of the other job as indicated above, and display it in console output of current job. You will have to detect when the child job finished by looking for X-More-Data: true header, as detailed above.
I know this is an old question, but i had to this myself recently. I figure this would help someone else looking to do the same. Here's a Groovy script that will read a given job's progressiveText URL. The code is written in such a way that it should be plug and play. Make sure to set the jenkinsBase and jobName first. The approach is no different to what has already been mentioned.
Here's a short set of instructions on how to use this: (1) Configure downstream job so that anonymous users hasRead and ViewStatus rights. (2) In the upstream job, create a Trigger/call builds on other projects step that will call the downstream job. (3) Do not check the "Block until the triggered projects finish their builds. (4) Right after that step, create an Execute Groovy script step and paste the following code:
def jenkinsBase = // Set to Jenkins base URL here
def jobName = // Set to jenkins job name
def jobNumber = 'lastBuild' // Tail last build
def address = null
def response = null
def start = 0 // Start at offset 0
def cont = true // This semaphore holds the value of X-More-Data header value
try {
while (cont == true) { // Loop while X-More-Data value is equal to true
address = "${jenkinsBase}/job/${jobName}/${jobNumber}/logText/progressiveText?start=${start}"
def urlInfo = address.toURL()
response = urlInfo.openConnection()
if (response.getResponseCode() != 200) {
throw new Exception("Unable to connect to " + address) // Throw an exception to get out of loop if response is anything but 200
}
if (start != response.getHeaderField('X-Text-Size')) { // Print content if the starting offset is not equal the value of X-Text-Size header
response.getInputStream().getText().eachLine { line ->
println(line)
}
}
start = response.getHeaderField('X-Text-Size') // Set new start offset to next byte
cont = response.getHeaderField('X-More-Data') // Set semaphore to value of X-More-Data field. If this is anything but true, we will fall out of while loop
sleep(3000) // wait for 3 seconds
}
}
catch (Exception ex) {
println (ex.getMessage())
}
This script can be further improved by programatically getting the downstream job number.
There is also a Python version of this approach here.
I'm exeucting my Lua script once per program cycle of 10 ms. using the same Lua_state (luaL_newstate called once in my app)
Calling luaL_loadbuffer complies the script very fast for sure, still it seems unneccessary to do this every time the script is executed since the script does not change.
Tried to save binary using lua_dump() and then execute it, but lua_pcall() didn't accept the binary for some reason.
Any ideas on how to optimize? (LuaJIT is not an unfortenately an option here)
Jan
You're correct, if the code is not changing, there is no reason to reprocess the code. Perhaps you could do something like the following:
luaL_loadbuffer(state, buff, len, name); // TODO: check return value
while (true) {
// sleep 10ms
lua_pushvalue(state, -1); // make another reference to the loaded chunk
lua_call(state, 0, 0);
}
You'll note that we simply duplicate the function reference on the top of the stack, since lua_call removes the function that it calls from the stack. This way, you do not lose a reference to the loaded chunk.
Executing the loadbuffer compiles the script into a chunk of lua code, which you can treat as an anonymous function. The function is put at the top of the stack. You can "save" it the way you would any other value in Lua: push a name for the function onto the stack, then call lua_setglobal(L, name). After that, every time you want to call your function (the chunk), you push it onto the Lua stack, push the parameters onto the stack, and call lua_pcall(L, nargs, nresults). Lua will pop the function and put nresults results onto the stack (regardless of how many results are returned by your function -- if more are returned they are discarded, if fewer then the extras are nil). Example:
int stat = luaL_loadbuffer(L, scriptBuffer, scriptLen, scriptName);
// check status, if ok save it, else handle error
if (stat == 0)
lua_setglobal(L, scriptName);
...
// re-use later:
lua_getglobal(L, scriptName);
lua_pushinteger(L, 123);
stat = lua_pcall(L, 1, 1, 0);
// check status, if ok get the result off the stack
When Using SharpSSh and the SshExec class, I can't get the RunCommand to work, it always returns an empty string. When I debug the SharpSsh library it returns -1 when it tries to read the command from a stream. It works when I use the sftp class in the same library, but that class doesn't support all the ftp commands I need.
Here is a standard example, I can't get this to produce a correct result either
SshConnectionInfo input = Util.GetInput();
SshExec exec = new SshExec(input.Host, input.User);
if(input.Pass != null) exec.Password = input.Pass;
if(input.IdentityFile != null) exec.AddIdentityFile( input.IdentityFile );
Console.Write("Connecting...");
exec.Connect();
Console.WriteLine("OK");
while(true)
{
Console.Write("Enter a command to execute ['Enter' to cancel]: ");
string command = Console.ReadLine();
if(command=="")break;
string output = exec.RunCommand(command);
Console.WriteLine(output);
}
Console.Write("Disconnecting...");
exec.Close();
Console.WriteLine("OK");
Any ideas on how I can get the RunCommand function to run some commands?
Thanks for any help :)
To get the standard output and error streams from .RunCommand,
I'll repeat the answer I posted to: SharpSSH - SSHExec, run command, and wait 5 seconds for data!
You may want to try the following overload:
SshExec exec = new SshExec("192.168.0.1", "admin", "haha");
exec.Connect();
string stdOut = null;
string stdError = null;
exec.RunCommand("interface wireless scan wlan1 duration=5", ref stdOut, ref stdError);
Console.WriteLine(stdOut);
exec.Close();
If their API does what the name implies, it should put the standard output of your command in stdOut and the standard error in stdError.
For more information about standard streams, check this out: http://en.wikipedia.org/wiki/Standard_streams