
Back to Blog index.
Microsoft fellow Mark Russinovich is at it again. This time, he writes about the inner workings of Vista UAC in his TechNet magazine article "Inside Windows Vista User Account Control". Recommended reading!
If you use C# to write your applications, you will without doubt want to add your application details into the attributes in your AssemblyInfo.cs file. For example, you might want to fill in the AssemblyDescription, AssemblyCopyright or AssemblyCompany attributes, among others. Sometimes, you might also want to display this same information in your user interface, for example in a log file, About box, and so forth. But what is the easiest to way to read this information from C# code? Here's one example:
using System.Reflection;
...
private string ReadDescription()
{
Assembly assembly = Assembly.GetExecutingAssembly();
object[] attributes = assembly.GetCustomAttributes(
typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length == 0) return "(no description)";
string desc = ((AssemblyDescriptionAttribute)attributes[0]).Description;
return desc;
}
As the method name already tells you, this method gives you the value of the AssemblyDescriptionAttribute inside your EXE or DLL (current assembly as returned by GetExecutingAssembly). With this kind of code, it is easy to read any attribute value you've added/embedded into your assembly.
If you want to create proper Windows Vista compatible application (especially for visual studio and UAC), you will need to add a manifest into your EXE files. There are multiple ways to do this (with and without Visual Studio), but my recommendation is that you use the MT.EXE utility, which is part of the Windows SDK.
With this tool, you can first create your XML based manifest file, set the proper requestedExecutionLevel value for UAC, and then use the MT.EXE tool for instance like this:
mt.exe -manifest MyManifest.xml -outputresource:MyApp.exe
Of course, you might also compile a .RES file from your XML based manifest with RC.EXE (Resource Compiler), but when you link this file into your executable with Visual Studio 2005/C#, the problem is that your assembly/version information and copyrights will then get lost under Project properties/Application/Assembly Information. This is the reason I'm recommending you to use MT.EXE instead of embedding your manifests directly.
Note: there are newer and older version of MT.EXE available in different SDKs. Unfortunately, not all versions work correctly, and I recommended that you use at least version 5.2.3790.2075 (dated 19-Oct-2006). It comes at least with the Windows Vista SDK.
There are certain situations when you might need to edit your Visual Studio project files. For example, you might wish to add a Win32 resource to your project, or might want to add a custom MSBuild task to your project file -- something you cannot do with the Visual Studio 2005 IDE directly. However, there's a problem with this: you cannot simply edit the XML based project file in Visual Studio without doing a simple trick first called unloading the project.
Now, when you load a project (solution) into Visual Studio, you can see the project's structure in Solution Explorer. Here, you can right-click your project, and select "Unload project" from the popup menu:

Next, the project goes into "Unavailable" mode, meaning the project is now effectively disabled. After this, right-click the project node again, and choose Edit [project], and then your .CSPROJ file open in the editor. Once you are done editing, simply save your file and choose Reload [project], and you are done!
PS. I also did a Finnish post on ITpro.fi about this.
Keywords: howto, how to edit Visual Studio project file, C#.
If you are a frequent MSDN or Technet browser, you might remeber several different layout/graphics tests from the past year. Now, Microsoft has finally settled on one specific improvement, and the result is a new look (and feel) on both MSDN and Technet. Improvements include:
The Finnish Helsinki School of Economics and Marianne Kivelä has produced an interesting study titled "Dynamic Capabilities in Small Software Firms", which will be presented on 29th this month.
I'd very much like to get my hands on this publication, unfortunately it appears not to be available online, only in print. ISBN is 978-952-488-12. I have to see how much does this publication cost, or whether I could get a press copy.
Some more miscellaneous information regarding Microsoft's forthcoming Windows Server 2008, from an eWeek article:
Numerous other kernel improvements are also to be served to us. Sounds great!
Microsoft has now announced the marketing name of its next-generation Windows server operating system. Previously known with the codename "Longhorn", the next OS will be called simply Windows Server 2008. Although unsurprising, I believe it's a good name because it follows the rule set forth by Windows 2000 Server and Windows Server 2003.
Since Expression Blend is also part of my MSDN subscription, I decided to download the ISO image and test the thing on my Vista box. Works like a charm, though it's not just an afternoon stroll to master this application. The user interface is black and limited saturation, which makes it look like Adobe Lightroom (LR), though I'd still give slight edge to LR in visual appeal. Blend is faster to use, though. And reminds me of my beloved old ImageStyler.

Now then, what can Blend do? It allows your to create native .NET applications with both C# and VB.NET, and it is easy to get started. The applications used XAML and Windows Presentation Foundation (WPF), and under the hood there's your C# compiler (csc.exe) or the VB.NET equivalent, if you like. For example, when testing my simple Hello World application, the Results pane showed the following command line:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701,1702 /define:DEBUG;TRACE /reference:"C:\Program Files\Reference Assemblies\Microsoft\ Framework\v3.0\PresentationCore.dll" /reference:"C:\Program Files\Reference Assemblies\ Microsoft\Framework\v3.0\PresentationFramework.dll" /reference:C:\Windows\Microsoft.NET\ Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\ v2.0.50727\System.Xml.dll /reference:"C:\Program Files\Reference Assemblies\Microsoft\ Framework\v3.0\WindowsBase.dll" /debug+ /debug:pdbonly /out:obj\Debug\Hello__World_.exe /resource:obj\Debug\Hello__World_.g.resources /target:winexe /win32icon:Application.ico App.xaml.cs AssemblyInfo.cs Window1.xaml.cs "C:\Users\Jani Järvinen\Documents\Expression\ Expression Blend Projects\Hello, World!\obj\Debug\Window1.g.cs" "C:\Users\Jani Järvinen\ Documents\Expression\Expression Blend Projects\Hello, World!\obj\Debug\App.g.cs" Hello, World! -> C:\Users\Jani Järvinen\Documents\Expression\Expression Blend Projects\ Hello, World!\bin\Debug\Hello__World_.exe The build has successfully completed.
Looks familiar! And Blend can be used to build Silverlight applications as well, though I'm yet to figure out how.
The CodingHorror blog has an interesting article from few days back. It talks about why some people (read: developers) seem to hate Microsoft, and what sounds to be their current problem: too many things in so little time. Hmm, is that really a problem? I don't think so, since if there's rapid innovation going on, let it come. Long gone are times when one person could say s/he wholly mastered a development tool, language or operating system. Today, it just cannot be done.
There's also commentary about the same post in CodeGear's blog, and the last paragraph tells it all, I think. Sorry, but I'd much rather have the new technology than stay behind -- as long as I can still use the older one instead of the new, if I so choose.
I think I've got a pretty nice junk mail filter in my Outlook, but sometimes one odd spam e-mail comes through. Today's lonely spam was titled "The implementation of the IPersistStream standard interface deserves a more detailed examination". Wow, that's clever. Sounds like we developers are one of the last islands of people that don't have spam tailored to us. Or, using a rather sensible subject line just makes it easier to fool the mail filters. Just like combining both German and English in the same message. Somebody must run a full-time job figuring out these.
Both RegDeveloper and ZDNet report (and numerous MSDN blog posts, of course) that SQL Server's next version, currently only greeted with the codename "Katmai" should be out next year. There are also rumors floating around that SQL Server 2005 Release 2 (R2) or something the like might be on the horizon. Sounds again a busy (fiscal) year for Microsoft with new Visual Studio, Windows server operating system and now SQL Server in the works.
My TechNet webcast about Windows Vista secure application development was a success yesterday, thanks Janne for your help and company. I promised to put the Finnish material available online, so here you go:
As said, the slide deck uses PowerPoint 2007 (.pptx files) and the two-button sample application was written with Visual Studio 2005 and C# 2.0. Enjoy, and continue discussion on ITpro.fi!
If you are interested in Windows Vista application development and especially security, I'm running a Microsoft TechNet webcast presentation tomorrow 9th of May at 3:00 pm Finnish time (EET, GMT+2). The presentation will be in Finnish this time, and to attend, please follow the TechNet event ID 1032326812 link, titled "Tietoturvallisten sovellusten kehittäminen Windows Vistalle". There's also a link to the event registration page at the front page of ITpro.fi.
Welcome!
A C# application I'm developing uses an Oracle database, which I've installed into a VMware virtual machine. It is Oracle 10g (10.2.0) on top of Windows Server 2003.
My application was happily working on Friday, but after the weekend it stopped working altogether. From both the client and from the server console, I only got the error message "ORA-12514: TNS:listener does not currently know of service requested in connect descriptor." or the System.Data.OracleClient.OracleException .NET exception. On my Windows XP with Finnish regional settings the error was "ORA-12514: TNS: kuuntelija ei tällä hetkellä tunne palvelua, jota pyydettiin yhteyskuvaajassa."
How and why did this all happen? All I can come up with is that I updated the VMware Tools inside the virtual machine after Oracle was installed, and that must have changed some of the network settings that Oracle binds to. I don't know Oracle well enough to solve the issue, so my resolution was to return to a previous snapshot with the older VMware Tools still installed. This solution worked well, and immediately the error disappeared.
Another Oracle tip: the crucial TNS (Transparent Network Substrate, I'm told) is a text file that on Oracle 10g lives on this path on the client:
C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\tnsnames.ora
The configuration file is most easily edited with the GUI tools (Java based), but in case you need an example, here's an example of such a file:
MY-DATABASE-NAME =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = myhost.domain.local)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)
Keywords: Oracle 10g, network problem, virtual machine, ORA-12514 error.
If you are developing applications for Windows Vista, you are surely aware of User Account Control or UAC. With UAC, even users that belong to the Administrators group are running Vista with standard user rights. But with a process called elevation, users can raise their rights to real administrators. Of course, the question is: how to detect is the user is running your application with real administrative rights, and isn't just a standard user beloning to the admin group? The code is quite simple, thanks to the extensive .NET base class libraries:
using System.Security.Principal;
using System.Threading;
public bool RunningAsAdministrator()
{
AppDomain.CurrentDomain.SetPrincipalPolicy(
PrincipalPolicy.WindowsPrincipal);
// read current identity for this thread
WindowsPrincipal principal = (WindowsPrincipal)Thread.CurrentPrincipal;
WindowsIdentity identity = (WindowsIdentity)principal.Identity;
// can the Administrator role be found?
bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
return isAdmin;
}
Keywords: HowTo, RunningAsAdministrator, RunningAsAdmin, IsAdmin, .NET, C#, Visual Studio, Microsoft Windows Vista.
In certain situations you need to be aware for (against) which .NET Framework version an assembly (executable or library, you decide) was built (compiled, written). For instance, you might have used Visual Studio 2002 or 2003 to develop a library and then an application (such as Visual Studio 2005) can load it as an add-in. Or, like I mentioned yesterday, you try to reference an assembly built for .NET 2.0 with Delphi 2006.
Now, .NET assemblies can indeed work in a mixed-version environment, but sometimes this just isn't the case. In these situation you need to be able to determine which .NET Framework version was used to build the given assembly.
So the question is: how do you easily determine this version? The information is stored in the file's CLR header, and you can use the dumpbin.exe utility that comes with Visual Studio to see this header:
dumpbin /clrheader myassembly.exe
However, I've noticed that this method is not a very clear one (it always appears to say version 2.0), and thus I wanted to build my own solution with C#. I named my application simply Show Assembly Version, and when you browse or drag-and-drop a file onto the main window, the .NET version of the assembly is shown:
To programmatically determine the assembly's original .NET version, you can use the managed (i.e. .NET) APIs, for instance Assembly.LoadFrom, or an unmanaged API function called GetFileVersion from MSCOREE.DLL. The header file MSCOREE.h defines this function as follows:
STDAPI GetFileVersion(LPCWSTR szFilename, LPWSTR szBuffer, DWORD cchBuffer, DWORD* dwLength);
Translated into C#, the wrapper around this function would be:
using System.Runtime.InteropServices;
...
[DllImport("mscoree.dll", CharSet=CharSet.Unicode)]
public extern static int GetFileVersion(
string szFilename, StringBuilder szBuffer,
int cchBuffer, out int dwLength);
To call this function, my sample application uses the following code:
private void UpdateVersionInformation()
{
string filename = selectedFileLabel.Text;
StringBuilder buf = new StringBuilder(20);
int len = 0;
int result = NetCoreApi.GetFileVersion(filename,
buf, buf.Capacity, out len);
if (result == 0)
{
if (len > 0)
{
dotNetVersionLabel.Text = ".NET " + buf.ToString();
}
else
{
dotNetVersionLabel.Text = "Unknown .NET version";
}
}
else
{
const uint COR_E_BADIMAGEFORMAT = 0x8007000B;
if ((uint)result == COR_E_BADIMAGEFORMAT)
{
dotNetVersionLabel.Text =
"File appears not to be a .NET assembly";
}
else
{
dotNetVersionLabel.Text = "Error " + result;
Marshal.ThrowExceptionForHR(result);
}
}
}
The function returns a simple string such as "v1.1.4322" or "v2.0.50727", which I then store in a label. If you select a non-.NET application such a regular native Win32 application, the message "File appears not to be a .NET assembly" is shown.
In these cases GetFileVersion returns 0x8007000B (-2147024885 decimal) which equals to the constant COR_E_BADIMAGEFORMAT. Note how I'm using the Marshal.ThrowExceptionForHR call to raise an exception in case the given HRESULT is something else. See MSDN for more info.
If you are using Delphi to develop .NET applications, you might have needed to add references to new assemblies, even ones you've written yourself. However, Delphi/BDS 2006 isn't very clever when you point it at an assembly that was built for .NET 2.0. (Remember, Delphi 2006 is still only .NET 1.1). In such situations, all you will get is an error such as this:
D:\DLLs\InteropTest.dll is not a valid assembly, type library, or COM object.
Of course, this doesn't help you much, if you want to import such an assembly (DLL or otherwise) into your Delphi project. Even more so because you cannot easily detect against which .NET Framework version an assembly was originally built. Stay tuned for a C# based solution...
Stuff I found from CodePlex.com: Package This. This fancy little GUI application lets you select a subset of MSDN documentation, and save it into your local hard disk for viewing later. Very convenient if you don't have for example Visual Studio's documentation installed, but want to browse the documentation when sitting for example in an airplane without an Internet connection. Download your copy today!
I read from Somasegar's blog today, that you can now use Longhorn Beta 3 and IIS 7.0 Beta 3 that is included in it to go live! In this context, "Go Live" means that you can use the beta products to host public web sites, and then convert them to the RTM version once it is here.
Cool! How about hosting your personal web pages with IIS 7.0? :-)
› Blog Archive