Consoles for Mr.GUI !!!

Learnt something new, a small one but very useful.
Many times I have seen GUI applications accompanied by console windows that show logs or trace information of the application. How do we do that for our application ?

Any GUI application can create its own console window just by calling AllocConsole Win32 API. Actually any process can use that API to allocate a new console. And the application must also learn to be disciplined enough to FreeConsole. Ok, fine. I used that in my small MFC application and was happy to see the console. But I did not see anything displayed on the console. As we know, each process has its own stdin, stdout and stderr. So redirect the console output of your parent application to the console. How do you do that ?

Use the FILE *freopen(const char *path, const char *mode, FILE *stream); API. The freopen function closes the file currently associated with stream and reassigns stream to the file specified by path. By that way, call freopen as follows:-

FILE *fpStdOut = freopen (“CONOUT$”, “w”, stdout);

This means that I want to reassign the standard console output stdout with the console output of the parent application CONONUT$. So any printf calls will print the characters on the console. Cool !!!

Setting Environment Variables !!!

Need to change or set the value of an environment variable programmatically and without the need to restart/log off the machine. I need the change to reflect for all processes, ie, I need to change the global environment value and not the one in the PEB [Process Environment Block] of a process. Frustated with setting the value of an environment variable !!!

For getting the set of environment variables or to get the value of an environment vaible from your C# program, there is the GetEnvironmentVariables/GetEnvironmentVariable API in the System.Environment class. But there is no API for setting the value of an environment variable.

The system environment variables are stored in the registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment.

The [current] user environment variables are stored in the registry under HKEY_CURRENT_USERE\Environment.

When the system boots up, the environment is built from this list in the registry. If we change the value directly in the registry, the change does not effect. For example, change the value of TEMP variable that specifies the temporary files directory, in the registry and check with the set command in the command prompt, you won’t see the change you made. Or just create a new entry in the registry under the one of the above mentioned registry paths, you won’t see the change. Also you can verify that programmatically with GetEnvironmentVariable API.

But the changes you made will be reflected after a log off or restart. After some research, I found the Win32 SDK API SetEnvironmentVariable. But unfortunately, it just the changes the variable value in the PEB of that process alone, it does not effect the global environment values. Pathetic.

There is definitely a solution for this simple and primary problem. All we have to do is to update the registry as we discussed before, and also notify that the global enviroment variable list has been modified. Ok, how do we do that ?

Simple, one line of code.

// Broadcast the WM_SETTINGCHANGE message for Enviroment

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
(LPARAM) “Environment”,
SMTO_ABORTIFHUNG,
5000, &dwReturnValue);

Of course, this is C++ code. Not a big deal to do that in C# or whatever.

CoMarshal…. working in NT, Not working in XP !!!

Problem:-

I have created a multi-threaded application which works without any problems on a NT-4.0 Workstation/Server. When I try to run the same application in Windows XP, I get an error in a call to CoMarshalInterThreadInterfaceInStream which returns -2147418113.
I have provided a snippet of the code below where the call fails in Windows XP.
Environment – Windows-XP,SP-2,Visual Studio 6.0,SP-4,ATL-3.0
Should I be doing anything different in Windows XP?

HRESULT hr = S_OK;
IUnknown** pp = p->m_vec.begin();
while (pp m_vec.end() && hr == S_OK)
{
if (*pp != NULL)
{
IEvent* pEvent = (IEvent*)*pp;
IStream* pIStream;
HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IEvent, pEvent, &pIStream);
if(SUCCEEDED(hr))
{
CComPtr pMarshalEvent;
hr = CoGetInterfaceAndReleaseStream(pIStream, IID_IEvent, (void**)&pMarshalEvent);

if(SUCCEEDED(hr))
hr = pMarshalEvent->NewCurrentCassette(m_pCurrentCassette, m_setBy);
}
P++;
}

Thread 2:-

I remember facing this problem long time back.The reason it happened was b’cos of the Free-Threaded marshaller code in Finalconstruct and FinalRelease even though i don’t remember the logic behind it.In my case commenting the Free-Threaded marshaller code did the trick.

1) The commented code in FinalConstruct was
hr = CoCreateFreeThreadedMarshaler( GetControllingUnknown(), &m_pUnkMarshaler.p);
PROCESS_HR(IID_ISomeThing);

2)In FinalRelease it was the corresponding m_pUnkMarshaler.Release(); that was commented.

3)In the header,DECLARE_GET_CONTROLLING_UNKNOWN() and COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p) and CComPtr m_pUnkMarshaler; was commented.

4)Remove marshalling code i.e,CoInterface and related marshalling code.The interface pointer can be accessed in the secondary thread directly,no need of marshalling.

I remember faintly that Free-Threaded marshaller is basically to optimize marshalling.So in my case removing it did not have any side-effects as we were not worried about Free-Threaded marshaller.Again the above fix might work but the best thing to do will be to anaylze the apartment link(STA,MTA etc.) between say the client and the component and then come to a conclusion.

Thread 3:-

You need not marshal/unmarshal to call a method on the interface pointer since the sink class itself deriving from the IConnectionPointImpl takes care of unmarshalling. You can see the code in your connection point implementation class.

Thread 4:-

I don’t think IConnectionPointImpl class as such has anything to do with marshalling, it is the m_pUnkMarshaler member object.It is the call to CoCreateFreeThreadedMarshaler in FinalConstruct that initializes the m_pUnkMarshaler object.I suggest reading the documentation about CoCreateFreeThreadedMarshaler in order to come to a conclusion whether to use it or not.By default ATL provides the code calling CoCreateFreeThreadedMarshaler API to do efficient marshalling across *thread of the same process(Refer doc)*, but depending on our need we may or may not use it.In my case we did not need it so we commented it out.It depends on the need,but generally i think it is safe to comment it out if we are going to access interface pointers in secondary threads.Hope this helps.

Consts in .NET !!!

I was doing some programming with C# and I had to use some ‘const’s as everybody does generally in programming. I had a class that simply had const string variables for my DB table names and stuff like that. My program was not working well and I started debugging and in the debugger, I was shocked to see that the const variables did not show the string values I had assigned. I did rebuilt and other non-sensical stuff like that until I learnt this about the consts in .NET:- ‘const’ variables in .NET do not exist as variables out of the assembly they exist in. Instead, during compilation, they get embedded [hard-coded] where ever you use them, and so when you debug, you do not see the proper value that you had assigned. For debugging purposes you have to output diagnostic trace messages and verify.