|
» Log In » Register » Suggest » Feeds » News » Podcasts » Tags » Pings » Documents » XML » Web Services » Categories » Statistics » Help » Site Map » About |
|
Previous Syndicated Feed |
Random Syndicated Feed |
Next Syndicated Feed |
|
Feed Tags
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Headlines | Enclosures | Poll Results | Statistics | XML | Action Log(2) | Notes(0) | Categories | Contacts | Locations | Subscribers | Changes |
| Title | Description | |
| My blog home... | It's now on http://concrt.spaces.live.com. concrt was available so as that's what's on my mind nowadays, I decided to pick that. This won't be just about ConcRT! :-) |
|
| On Windows 7, the Invariant Culture is an installed culture... | Last month, I investigated an issue for an ISV where their code would work fine on Windows Vista but fail on Windows 7. Not very commom! The cause? CultureInfo.GetCultures(CultureTypes.AllCultures & ~CultureTypes.NeutralCultures) returns an array that does not contain the CultureInfo.InvariantCulture on Windows Vista but does on Windows 7. On Windows 7, the Invariant Culture is considered to be an installed culture. It was not on Windows Vista. From Eric: “The Invariant culture is normally included with NeutralCultures enumerations. It is also specifically excluded from SpecificCulture enumerations. However, there is no attempt to remove it from the InstalledWin32Cultures enumeration and since CultureTypes.AllCultures == CultureTypes.NeturalCultures | CultureTypes.SpecificCultures | CultureTypes.InstalledWin32Cultures, the InvariantCulture is showing up as one of the InstalledWin32Cultures.” Depending on what you do with the result, this might be an issue. For example if you create an instance of RegionInfo RegionInfo(CultureInfo.InvariantCulture.LCID), this will result in an ArgumentException exception being raised. To make sure your code works on both O.S., you might need to introduce the highlighted code below:
J’espère que vous trouverez cela utile. Buen día. |
|
| How to add the application compatibility section with Visual C++ 2008? | If you wonder what I’m talking about when mentioning the compatibility section, have a look at my previous blog entry. To start with, I added a Compatibility.manifest file to my project: <?xml version="1.0" encoding="utf-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> </application> </compatibility> </assembly>
I then specified $(InputDir)\Compatibility.manifest in the Configuration Properties/Manifest Tool/Input and Output/Additional Manifest Files field in the project properties dialog. This automatically added /manifest ".\Compatibility.manifest" to the MT.EXE command line that would be used at build time. Not too sure it would work; I then rebuilt a small C++ program and got: \Compatibility.manifest : manifest authoring warning 81010002: Unrecognized Element "compatibility" in namespace "urn:schemas-microsoft-com:compatibility.v1".
I must be using an old MT.EXE version. I turned off the Suppress Startup Banner, turned on the Verbose Output and rebuilt: Microsoft (R) Manifest Tool version 5.2.3790.2076 Copyright (c) Microsoft Corporation 2005. All rights reserved. \Compatibility.manifest : manifest authoring warning 81010002: Unrecognized Element "compatibility" in namespace "urn:schemas-microsoft-com:compatibility.v1".
Let’s dir C:\MT.EXE /S /B and look at the versions of MT.EXE I have on my hard-disk: C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\mt.exe
No surprise as I have both VS 2008 SP1 and the released Windows 7 SDK installed. Let’s launch the one I hope is the one I’m using: D:\>"C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\x64\mt.exe" /? Usage:
So I am building with the publicly latest and greatest version of MT.EXE! I’m guessing I’ll ignore the warning but I need to make sure this works. First, I loaded my program executable with the Visual Studio Resource Editor (File/Open/File…/Open With…) to look at the MANIFEST resource: yes, the setting was there, as was the Side-by-Side information. But I wanted to go a step further so although I said in my previous blog entry that it was an obscure topic to me, I looked at the sample on the ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION Structure page, but it crashed on my machine. I kept playing around and ended up with the following code: GUID WIN7_CONTEXT_GUID = {0x35138b9a, 0x5d96, 0x4fbd, {0x8e, 0x2d, 0xa2, 0x44, 0x02, 0x25, 0xf9, 0x3a}}; GUID VISTA_CONTEXT_GUID = {0xe2011457, 0x1546, 0x43c5, {0xa5, 0xfe, 0x00, 0x8d, 0xee, 0xe3, 0xd3, 0xf0}}; … HANDLE activationContextHandle = GetModuleHandle(NULL); SIZE_T bufferSize = 0; QueryActCtxW(QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE, activationContextHandle, NULL, /*ACTIVATION_CONTEXT_INFO_CLASS::*/CompatibilityInformationInActivationContext, NULL, 0, & bufferSize); if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { _ASSERTE(bufferSize > 0); vector<BYTE> p(bufferSize); if (QueryActCtxW( QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE, activationContextHandle, NULL, /*ACTIVATION_CONTEXT_INFO_CLASS::*/CompatibilityInformationInActivationContext, & p.front(), bufferSize, &bufferSize)) { ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION * acci = reinterpret_cast<ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION *>(& p.front()); DWORD dw = acci->ElementCount; COMPATIBILITY_CONTEXT_ELEMENT * ce = acci->Elements; while (dw) { if (ce->Type == ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS) { if (ce->Id == WIN7_CONTEXT_GUID) { wcout << L"Windows 7 is supported" << endl; } if (ce->Id == VISTA_CONTEXT_GUID) { wcout << L"Windows Vista is supported" << endl; } } ce++; dw--; } } } I ran it and got: Voilà! Como de costumbre, nous terminons avec une liste de ressources: · Input and Output, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box · Understanding Manifest Generation for C/C++ Programs (Thanks to everyone who answered my e-mails while working on this. You know who you are!)
|
|
| The new compatibility section in the Application Manifest | This is still the same Application Manifest that you store in your Win32 Resource or put next to your executable (i.e. "MyExecutable.exe.manifest" ). Under Windows XP, this manifest allowed you to create Isolated Applications and Side-by-side Assemblies. Under Windows Vista, we added the DPI Awareness and execution level for your application. Under Windows 7, we introduced a new section called compatibility. If it’s not present, your application will get the Windows Vista behavior by default on Windows 7 and future Windows versions. This new section allows us: 1. To provide new behavior to new developer-created software while maintaining the compatibility for existing software. 2. To help Windows deliver greater compatibility in future versions of Windows as well. So the question is what’s the Windows Vista behavior? In my personal order of preference: 1. Program Compatibility Assistant (PCA) 2. GetOverlappedResult API 3. RPC Default Thread Pool 4. DirectDraw Lock 5. DirectDraw Bit Block Transfer (Blt) to Primary without Clipping Window Here is an example using the corresponding pre-defines GUIDs: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!--The ID below indicates application support for Windows Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!--The ID below indicates application support for Windows 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> </application> </compatibility> </assembly>
Chris Jackson goes into a bit more details here and voici a bit more resources: - Application Manifest in the Windows 7 and Windows Server 2008 R2 Application Quality Cookbook - The still obscure (to me) activation context stuff: the QueryActCtxW Function and COMPATIBILITY_CONTEXT_ELEMENT Structure Y colorín colorado, este cuento se ha acabado... |
|
| Consider not using the Frame Pointer Optimization when building your software | Stack tracing is a very useful functionality for tracking both the causes of performance problems and reliability issues. With Frame Pointer Optimization disabled, one can easily build the call chain by walking through the stack frame pointers. Because of potential code size increase and performance degradation, Independent Software Vendors tend to use the /Oy C++ compiler option when building their software. The Windows group performed some testing years ago to verify those beliefs and they concluded that the benefits of not using this optimization were bigger than the minimal cost it implied. Additionally, one of the gentlemen who performed those measurements at the time told me that for modern machines, there should be no noticeable performance difference. I just want to encourage you to turn off FPO and if you don’t believe us, please do your own testing and see if you want to follow our advice. It will help both of us! More detailed information courtesy of Ken: - Frame pointer omission (FPO) optimization and consequences when debugging, part 1 - Frame pointer omission (FPO) optimization and consequences when debugging, part 2 Tchau. |
|
| UI0Detect, WlS0WndH and a lie... | http://blogs.msdn.com/yvesdolc/archive/2009/09/11/ui0detect-wls0wndh-and-a-lie.aspx In my prior to last entry, I took a shortcut: your Windows Service user interface can be seen on Windows Vista and still on Windows 7. But beware, it’s not by default, not without additional end user involvement and very likely to no longer be there under Windows 8! It’s all about the Interactive Service Detection Windows Service (%SystemRoot%\System32\UI0Detect.exe) and the DLL injected in your service to detect if it displays anything in Session 0 (%SystemRoot%\System32\WlS0WndH.dll and %SystemRoot%\SysWOW64\WlS0WndH.dll) Instead of trying to repeat the excellent work that Alex Ionescu did in his blog, let me highly advise you to take the time to read it. It’s a bit complex but very helpful to understand how this all works, even under Windows XP: - Inside Session 0 Isolation and the UI Detection Service - Part 1 - Inside Session 0 Isolation and the UI Detection Service - Part 2 Let me finish by adding two things: 1. This mechanism is very very likely not to be there any longer in Windows 8. 2. The CreateProcessAsUser() API might actually not be the best solution when you need more complex interface for your service. Both Services in Windows Vista and Impact of Session 0 Isolation on Services and Drivers in Windows Vista are being updated to reflect this. I’ll keep you updated. ¿Querían noticias? ¡Pues ahora, ya las tienen! |
|
| If you develop/test on Windows 7, you might want to turn off the Fault Tolerant Heap… | It might interfere with your testing and after your software has crashed a couple of times, your application might start to no longer behave erratically.
As JohnFrum wrote: “I learned about this feature a few weeks ago while debugging my service. It had been crashing and then it seemed fixed and I couldn't repro it again. Moved it to another box and it started crashing again. Finally I noticed a line in the debugger that I knew wasn't mine about FTH and thought ‘WTH? Ahh, nice!’ I like it but I'll turn it off on my test systems.” The Fault Tolerant Heap page has the details about disabling it. For more information about this, check the video at Silviu Calinoiu: Inside Windows 7 - Fault Tolerant Heap
À demain si on le veut bien. |
|
| Do you still use the MessageBox API in your Windows Service? | Or do you display any type of User Interface? Starting with Windows Vista and above, user interfaces generated by Windows services can’t be seen. And even worst, your service could be stuck waiting for some user input that the user cannot give as she does not see anything! Why did we do that? Well it’s all explained in Impact of Session 0 Isolation on Services and Drivers in Windows Vista: “In Microsoft® Windows® XP, Microsoft Windows Server™ 2003, and earlier versions of the Windows operating system, all services run in the same session as the first user who logs on to the console. This session is called Session 0. Running services and user applications together in Session 0 poses a security risk because services run at elevated privilege and therefore are targets for malicious agents who are looking for a way to elevate their own privilege level. The Microsoft Windows Vista™ operating system mitigates this security risk by isolating services in Session 0 and making Session 0 noninteractive. In Windows Vista, only system processes and services run in Session 0. The first user logs on to Session 1, and subsequent users log on to subsequent sessions. This means that services never run in the same session as users’ applications and are therefore protected from attacks that originate in application code.” You can no longer use the MB_SERVICE_NOTIFICATION flag when calling the MessageBox API. It’s useless on Vista and higher. So how do you display a simple message from your Windows Service? For simple interactions, services can display a message box in the user's session by calling WTSSendMessage. For more complex interactions, services must use an approach such as calling CreateProcessAsUser to create a UI process in the user's session. That process handles user interaction and communicates with the service through RPC or named pipes. I will illustrate the simple case in this blog entry. In the SimpleService I’m attaching, here is how I display a message when the event named "Global\\SimpleService.HelloWithWtsSendMessage" is set: DWORD physicalConsoleSession = WTSGetActiveConsoleSessionId(); if (0xFFFFFFFF != physicalConsoleSession) { wostringstream b; b << L"Hello!" << endl << L"The active console session ID is 0x" << std::hex << physicalConsoleSession << L'.' << endl; LPWSTR title = const_cast<wchar_t *>(ServiceTable[0].lpServiceName); DWORD titleLength = static_cast<DWORD>(wcslen(title) * sizeof(*title)); std::wstring messageString(b.str()); LPWSTR message = const_cast<wchar_t *>(messageString.c_str()); DWORD messageLength = static_cast<DWORD>(wcslen(message) * sizeof(*message)); DWORD response; WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, physicalConsoleSession, title, titleLength, message, messageLength, MB_OK | MB_ICONINFORMATION, 0, & response, FALSE); After building the service, don’t forget to give access to the executable (i.e. SimpleService.exe) to LOCAL SERVICE so that the SCM can reach it when you indicate that you want to start it! You might have noticed that the event name is create in the global namespace. As the document clearly explains: “Because services run in Session 0, named objects created or opened by services are usually in \BaseNamedObjects\. However, if a user application assumes that it is running in the same session as the service and synchronizes with the service by creating or opening objects with the Local\ prefix (or no prefix, which defaults to Local\), the application no longer works as expected. This is because the create or open request is specific to that session (due to the Local\ prefix) and the objects that the application creates or opens are in \Sessions\<n>\BaseNamedObjects instead of \BaseNamedObjects\. The correct way for user applications to synchronize with a service is to explicitly use the Global\ prefix when creating or opening objects in \BaseNamedObjects\.” I also had to change the security around the event: only LocalService could touch it and I wanted applications running under other principals to be able to set/reset it: // We give EVENT_MODIFY_STATE (0x0002) access to the Interactive User // and // GENERIC_ALL (GA) to the Local Service (LS) under which this service is installed/running by default // Resources: // - Security Descriptor Definition Language: http://msdn.microsoft.com/en-us/library/aa379567(VS.85).aspx // - ConvertStringSecurityDescriptorToSecurityDescriptor: http://msdn.microsoft.com/en-us/library/aa376401%28VS.85%29.aspx // - Synchronization Object Security and Access Rights: http://msdn.microsoft.com/en-us/library/ms686670%28VS.85%29.aspx if (!ConvertStringSecurityDescriptorToSecurityDescriptor(L"D:(A;;0x00000002;;;IU)(A;;GA;;;LS)", SDDL_REVISION_1, & securityDescriptorPointer, NULL)) { goto cleanup; } SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), securityDescriptorPointer, FALSE}; // The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. // The remainder of the name can contain any character except the backslash character (\). serviceContext.HelloWithWtsSendMessageEvent = CreateEvent(&sa, FALSE, FALSE, L"Global\\SimpleService.HelloWithWtsSendMessage"); serviceContext.HelloWithMessageBoxEvent = CreateEvent(&sa, FALSE, FALSE, L"Global\\SimpleService.HelloWithMessageBox"); LocalFree(securityDescriptorPointer);
There’s a little application to test: int wmain() { //Sleep(30000); HANDLE e = OpenEvent( EVENT_MODIFY_STATE, FALSE, L"Global\\SimpleService.HelloWithWtsSendMessage"); if (e) SetEvent(e); else wcout << L"Error " << GetLastError() << L" calling OpenEvent()" << endl; return 0; }
You can uncomment the Sleep call and once launched, hurry up and switch to another user. You can also change the event name in the test to "Global\\SimpleService.HelloWithMessageBox" and watch your service freeze… Pay attention to my usage of _InterlockedAnd and _InterlockedOr: those can be very helpful. As usual, any comment is welcomed. À demain si on le veut bien. |
|
| Do you receive WM_PAINT when waiting for a COM call to return? | When a COM call is made that involves a COM Proxy or a call to CoWaitForMultipleHandles() (e.g. in a .NET Runtime Callable Wrapper), you could see this behavior where you would not have under pre-Vista versions of Windows. We made the design change in Vista, among other reasons, to allow proper painting of the applications when the consent dialog is shown. If you suffer from this design change and you cannot easily modify your code to handle gracefully this type of reentrancy, you’ll want to ensure that Windows behaves the way it used to. How do you do that? As explained in this Connect Feedback: You can work around this by doing an application compatibility shim. The flag is DisableNewWMPAINTDispatchInOLE. Once you have downloaded the Application Compatibility Toolkit (version 5.5 as of 8/4/2009), run the Compatibility Administrator program to create a new database for your software and follow the steps to produce an SDB for your software. This could include several .EXEs but no DLLs, as those cannot be shimmed. You’ll want to make sure you pick the right flag in the following dialog: Once you’ve created you .SDB file, you can register the information it contains by running sdbinst.exe on the file. When installing your software, you’ll want to have a Windows Installer Customer Action launching sdbinst.exe with the same .SDB file as parameter. I’m no A.C.T. guru so please look at the Application Compatibility site for more information.
Note added after initial post: Ensure that the cache is flushed: · Elevate cmd · Execute the following line from the elevated console Rundll32 apphelp.dll,ShimFlushCache |
|
| Developing native applications for Windows 7 in C++ | A gentleman from Germany asked on one of our forums: “I am interested in developing native Windows 7 Apps (64 and 32-Bit) with Visual C/C++. How can I do this?” You’ll first need a C++ compiler. You can find that on the MSDN Visual C++ page. Then the Windows 7 Software Development Kit can be downloaded from Windows SDK. It includes the header files, libraries and tools you need to develop for Windows 7 (Release Candidate as of 8/5/2009). Although the SDK contains good documentation, those are mostly tools. So where do you go for more information? I’d say that Develop for Windows 7 and Windows Vista MSDN is a good start. A lot of links I wanted to include here are actually there already. This is a very high level answer to very high level question but I hope it helps this gentleman a bit. And others too. Auf Wiedersehen. |