IsProcessInJob with GetCurrentProcess aways true - jobs

(Visual Studio 2010 - C++)
Hello,
I'm trying to set a JOB to a process, but AssignProcessToJobObject returns ACCESS_DENIED and IsProcessInJob returns TRUE.
I call IsProcessInJob to a process immediately after call CreateProcess (Suspended) end tried call IsProcessInJob with my process (a few lines after main entry point) and it returns true.
void main()
{
BOOL bIsInJob;
IsProcessInJob( GetCurrentProcess(), NULL, &bIsInJob );
printf( "IsProcessInJob (me): %s\n", bIsInJob ? "true" : "false" );
// RET True ! inside and outside IDE
...
Someone saw it before?
Thanks for any help.
Sources:
Kill child process when parent process is killed
How do I automatically destroy child processes in Windows?

I found.
For some reason, my process was child of Explorer.exe then Explorer set a job to my process and the notepad (my child) inherits this job.
I could not find until see with ProcessExplorer. I can not saw my process in process list, when i find below Winlogon->Explorer, i understood.
Resolution: CREATE_BREAKAWAY_FROM_JOB
if (!CreateProcess(L"c:\\windows\\system32\\notepad.exe", L"", NULL, NULL, FALSE,
CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &startupInfo, &processInformation))
...
Thanks for your comments, patience and time.

Related

How to do a non-recurring timeout in Gtk#?

I'm trying to do a thing a second in the future, but only once. The docs for GLib.Timeout.Add say that the "delegate is invoked repeatedly until it returns false", so I'm returning false and then I get an error from glib.
Example code:
using System;
class foo {
static void Main() {
Gtk.Application.Init();
uint t = GLib.Timeout.Add(1000, () => {
Console.WriteLine("returning false from timeout");
Gtk.Application.Quit();
return false;
});
Console.WriteLine("timeout added with source id = {0}", t);
Gtk.Application.Run();
}
}
Sample output:
$ mono foo.exe
timeout added with source id = 6
returning false from timeout
(foo:19030): GLib-CRITICAL **: Source ID 6 was not found when attempting to remove it
How do I stop my timeout from repeating after it times out without getting errors?
$ pkg-config --modversion gtk-sharp-3.0
2.99.3
Note that the error message apparently appears at program exit, and in my real program it does not seem to appear until the gc runs (I can get it immediately after the timeout if I manually call the gc and wait for finalizers).
Short answer, you can't. The timeout won't repeat because it has been properly removed. That's what the "error" is from because the gtk runtime is trying to dispose the timeout twice. This issue isn't just the C# gtk implementation, it's a bug in the C gtk+ library. There is a way to disable gtk from reporting errors, but I'm not sure how to do that.

Having a winforms app wait for a few minutes before proceeding

I've seen a few references on Stack Overflow about using the Timer Class to do what I want but I'm not convinced it's the right solution to the problem.
Basically, I have a button (in .NET 4.0) that when clicked will go through a few different subroutines and do certain things:
Restart some services
Launch a command line application that finishes automatically
Launch a second command line application that finishes automatically
Launch a third command line application that finishes automatically
The problem I have right now is that the program just goes through each thing and fires it off as quickly as possible - not a problem except that the third command line application must only fire after the first three are completed.
I had a sleep call in the code, except that this froze the UI and I have a status bar on this application that I wanted to have update to let the user know things are occurring.
I was thinking about a Timer object but I'm not sure that would actually cause there to be a pause before doing the next thing.
I'm using a Process.Start method to fire off the command line applications, so it doesn't actually raise an event. Should I just have my subroutine raise an event and then have the third Process.Start method wait for that event to fire before it goes?
This small snippet might help you. Try to get the idea and implement your own code.
try
{
Process myProcess;
myProcess = Process.Start("Notepad.exe");
while (true)
{
if (!myProcess.HasExited)
{
// Discard cached information about the process.
myProcess.Refresh();
// Print working set to console.
Console.WriteLine("Physical Memory Usage: "
+ myProcess.WorkingSet.ToString());
// Wait 2 seconds.
Thread.Sleep(2000);
}
else {
break;
}
}
// Close process by sending a close message to its main window.
myProcess.CloseMainWindow();
// Free resources associated with process.
myProcess.Close();
}
catch(Exception e)
{
Console.WriteLine("The following exception was raised: ");
Console.WriteLine(e.Message);
}

WiX Custom Bootstrapper - Single Instance Check

I use the following code to check if a Single Instance of the CustomBA is already running in the Run block of the CustomBA.
When the user starts the "setup.exe" (CustomBA) by double clicking it the code below returns true which is the expected behaviour.
However when the user right clicks and starts it as administrator the code returns false. Why is that?
private bool IsSingleInstanceOfSetupRunning()
{
bool result = true;
Process currentProcess = Process.GetCurrentProcess();
if (Process.GetProcessesByName(currentProcess.ProcessName).Length > 1)
{
result = false;
}
return result;
}
It appears that the WiX Engine detects that the process is running as admin and spins up the secondary process used for actually installing the MSIs. So there really are two processes running with the same name.
You can see the same behavior with the non-admin process once your CustomBA code calls Engine.Apply(). This is typically when the user sees a UAC prompt as the Engine spins up the second, elevated process to handle the actual MSI installs.
Since the main process is already running as admin, and no UAC prompting will occur by spinning up the second process, the Engine goes ahead and starts it immediately instead of waiting for the call to Engine.Apply().
Also note: if you're performing a Major Upgrade, the uninstall of the prior version will be run (in silent mode) during the upgrade, which would result in additional processes. You need to make sure you allow the uninstall process to run even if there is another process already running (your upgrade process).
One approach would be to use a mutex to do the checking, but only when running in DisplayMode Display.Full:
if (DisplayMode == Display.Full)
{
bool mutexCreated = false;
mutex = new Mutex(true, #"My Installer F1096BB9-CFDF-4AD1-91D8-9AA8805784A8", out mutexCreated);
if (!mutexCreated)
{
MessageBox.Show("Another instance of the installer is already running. You may only run one at a time.",
"Installer already running", MessageBoxButton.OK,
MessageBoxImage.Warning);
Log("Installer already running");
Exit(ActionResult.NotExecuted);
}
}
public void Exit(ActionResult actionResult)
{
if (mutex != null)
{
mutex.Close();
mutex = null;
}
Log(string.Format("Exiting with code {0}", actionResult));
Engine.Quit((int) actionResult);
}

GetMessage() function is calling itself infinitely (not coming out of loop)

I am implementing similar type of thing- I have some message box in the else part of the code below..what I get on debugging is that - I have same message box again and again and it doesn't end (which makes my program crash and I need to restart my laptop)..Is there any solution for it? I am using MFC application and creating a button on window explorer's preview pane. Every thing is fine but this is the problem that once if I enter in the loop below I am not able to come out (I mean there is some thing in DispatchMessage or TranslateMessage which calls this function again and again)..I couldn't find whats that ??
the code is as follow-
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
//Onee message box here
}
}
finally i found that when i return true; in this loop the control will come out of the loop(but its not in good approach) but this getmessage was not useful for me infact when i reomved it my program was working fine. In its presence it was having infinite loop.
Because i created the dialog using CreateDialogParam() and then DialogProc is called through this CreateDialogParam() and then i used WM_Commnands to handle the message received according to the application and i feel no use of this getmessage (please point anyone if i am wrong)

How to catch application titlebar change?

We are running on a Windows Client Platform (generally WinXP) in niche industry program that runs in a 640x480 window back to an AS/400 server. To reduce errors I want to watch for when the title bar of the program changes. Then I need to capture the keyboard entries to validate. I'll then make sure each of the entries is valid since the archaic program does no validation. I'll can then do a pop-up then warning the end-user if errors occur and to reduce/eliminate the exception reports.
My question is how can I capture the event of the application title bar change = 'string' that I need? API call? Aiming to do this in VB unless another would be notable cleaner.
WinEvents should work well here. These are lightweight events that get fired when certain UI changes take place - eg names of objects change - which includes Titlebar text changes. One benefit to this type of hook is that you can set it up to deliver the notifications back to your own process, so you don't need to deal with hooking or IPC. (It also works against both 32-bit and 64-bit processes.)
This is easiest to do in plain C/C++; but can be done in .Net (VB, C#) if you add the appropriate [DllImport]'s.
#include <windows.h>
#include <stdio.h>
#define WM_NAMECHANGED WM_APP
HWND g_hwndTarget; // window we're listening to
void CALLBACK WinEventProc(
HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime
)
{
// Check this is the window we want. Titlebar name changes result in these
// two values (obtained by looking at some titlebar changes with the
// Accessible Event Watcher tool in the Windows SDK)
if(hwnd == g_hwndTarget && idObject == OBJID_WINDOW && idChild == CHILDID_SELF)
{
// Do minimal work here, just hand off event to mainline.
// If you do anything here that has a message loop - eg display a dialog or
// messagebox, you can get reentrancy.
PostThreadMessage(GetCurrentThreadId(), WM_NAMECHANGED, 0, 0);
}
return;
}
void ReportName(HWND hwnd)
{
WCHAR szName[128];
GetWindowText(hwnd, szName, ARRAYSIZE(szName));
wprintf(L"hwnd 0x%08lx has title: %s\n", HandleToLong(hwnd), szName);
}
int main()
{
wprintf(L"Place mouse pointer over window titlebar to report name changes for and hit return...\n");
getchar();
POINT pt;
GetCursorPos(&pt);
g_hwndTarget = WindowFromPoint(pt);
ReportName(g_hwndTarget);
// Note: this doesn't work for console windows, which are managed by CSRSS.EXE. Simplest (though not efficient) workaround for those
// is to use threadId=0 and filter by hwnd in the callback.
DWORD threadId = GetWindowThreadProcessId(g_hwndTarget, NULL);
// This says: call the callback when any UI elements in the specified thread change
// name. _OUTOFCONTEXT means deliver the notifications in this process, don't hook.
HWINEVENTHOOK hook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, NULL, WinEventProc, 0, threadId, WINEVENT_OUTOFCONTEXT);
// TODO: add error checking as appropriate.
wprintf(L"Waiting...\n");
// Thread needs to have a message loop for SetWinEventHook to work for out-of-context messages.
UINT count = 10;
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
if(msg.message == WM_NAMECHANGED)
{
ReportName(g_hwndTarget);
if(--count == 0)
{
break;
}
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWinEvent(hook);
return 0;
}
Things to watch for: you might get false-positives; and if the name changes rapidly, by the time you get the first event, the name may be at the second value, so you may appear to see two events for the second value. Neither of these should be an issue if you're just using this as a trigger to check for a specified value, however.
I am assuming that you do not own the code for the target application. In this case, there's no easy "call me back when the title changes" event. You then have 2 options to do what you need, which I will outline below.
Easy but not airtight
Have your application get the main window of the target application (this should be easy enough) and poll its title every 100msec or so. When you detect a change, act accordingly.
Difficult but correct
Hook into the target application using e.g. a global CBT hook. Once your code runs in their process subclass their main window, causing all window messages to go through your code first. When your code sees a WM_SETTEXT message going to the main window, you can actively notify your "other" application on the spot using your choice of IPC. If all you need to do is just shout "hey!" to your other application, do so with an auto-reset event (it will be easiest). Of course all this points heavily to unmanaged code.
If the easy solution is not good enough and the difficult one is too much, you can try using an automation library like White (I 've never used it, so I can't really say more than that).