Friday, March 20, 2015

Check if program/application is installed on remote computer

public bool IsAppInstalled(string p_machineName, string p_name)
        {
            string keyName;

            // search in: CurrentUser
            keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
            if (ExistsInRemoteSubKey(p_machineName, RegistryHive.CurrentUser, keyName, "DisplayName", p_name) == true)
            {
                return true;
            }

            // search in: LocalMachine_32
            keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
            if (ExistsInRemoteSubKey(p_machineName, RegistryHive.LocalMachine, keyName, "DisplayName", p_name) == true)
            {
                return true;
            }

            // search in: LocalMachine_64
            keyName = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
            if (ExistsInRemoteSubKey(p_machineName, RegistryHive.LocalMachine, keyName, "DisplayName", p_name) == true)
            {
                return true;
            }

            return false;
        }
        private bool ExistsInRemoteSubKey(string p_machineName, RegistryHive p_hive, string p_subKeyName, string p_attributeName, string p_name)
        {
            RegistryKey subkey;
            string displayName;

            using (RegistryKey regHive = RegistryKey.OpenRemoteBaseKey(p_hive, p_machineName))
            {
                using (RegistryKey regKey = regHive.OpenSubKey(p_subKeyName))
                {
                    if (regKey != null)
                    {
                        foreach (string kn in regKey.GetSubKeyNames())
                        {
                            using (subkey = regKey.OpenSubKey(kn))
                            {
                                displayName = subkey.GetValue(p_attributeName) as string;
                                if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true) // key found!
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            return false;
        }

Monday, March 9, 2015

Dispatcher

WPF Thread Affinity

Almost every WPF element has thread affinity. This means that access to such an element should be made only from the thread that created the element. In order to do so, every element that requires thread affinity is derived, eventually, from DispatcherObject class. This class provides a property named Dispatcher that returns theDispatcher object associated with the WPF element.

The Dispatcher Class

The Dispatcher class is used to perform work on his attached thread. It has a queue of work items and it is in charge of executing the work items on the dispatcher thread.
So, when you want to change a property of a WPF element from a thread different from the one who created the element, you should use the element’s Dispatcher property to dispatch the operation to the correct thread. This is done using the BeginInvoke method that accepts a method to be invoked.

Where is the Dispatcher of the Thread Saved?

Every thread should have their dispatcher object, so you would think they will save the dispatcher on the Thread Local Storage (TLS).
It turns out they store a static list of all available dispatcher objects.
Of course, this list is synchronized using a private global static object (this is a common best practice when locking object).
Whenever the dispatcher of an object is needed, they go over the list, comparing the dispatcher’s Threadproperty with the current thread, until they find the correct dispatcher object for this thread.
The reason, as they note in the comments is that managed TLS is rather expensive.
Above this list, they add the following optimization: before going over the dispatchers list, they check if the last given dispatcher is suitable, so only a thread context switch will derive a new list search.
Although strange, this usually isn't such a problem because most applications will only have one thread that creates UI elements, hence only one Dispatcher in the list.

The main method here is tagged with “STAThread” attribute. STA stands for “Single Threaded Apartment” model of programming. What STA states(or enforces) is that only one thread at a time will be executing our code and it will always be the same thread. All our Winform based application runs on STA model. Indeed one thread controlling the complete application looks like a big constraint and WPF people actually decided to move away from this model by opting an all together different approach. But the plan was abandoned because of various compatibility issues with other already existing applications. So our WPF applications too run on STA model. The thread the controls the application is commonly known as UIThread. “Dispatcher” concept is a mechanism introduced in WPF , with the help of which developer can have more explicit control on this UI thread as of what executes when. We will look into this in more details in the remaining section of this article. But before we take a deep dive, just try to keep in mind the below mentioned points about STA model.
  • Thread that creates a given WPF application also own it and its not possible for any other thread to interact with these elements.
  • In practice entire WPF application runs of single thread and its this thread that owns all the elements in the application.
Dispatcher Concept
As the name implies, the dispatching system is responsible for listening to various kinds of messages and making sure that any object that needs to be notified of that message is notified on the UI thread.
The classes responsible for “Dispatcher” concept are : DispatcherObject and Dispatcher. Actually its the “Dispatcher” class which provides the core implementation of dispatching mechanism. But its the “DispatcherObject” class which exposes a public property called “Dispatcher” , through which we can access the current instance of “Dispatcher” class. Have a look at the following class hierarchy diagram :
image

“DispatcherObject” class offers a public accessor property called “Dispatcher” using which we can access the current instance of “Dispatcher” class. Speaking about “Dispatcher” class, it is responsible for managing the work that takes place in our WPF application.Its this class which owns the application thread and internally it maintains a queue of work items. As the WPF application runs , Dispatcher class accepts incoming requests and executes them one at a time. In short dispatcher is an object which receives messages and delivers it to the correct object for further processing. Dispatcher class is pretty dense with lots of properties and methods. Going into the depth of Dispatcher class is beyond the scope of this article. One final thing on dispatcher class is that a given application can have only one instance of dispatcher class( as the application runs on single thread) , so Dispatcher class implements the very famous “Singleton” pattern. Because of that its impossible to create an instance of Dispatcher class in our custom code. Only with the help of public property “Dispatcher” offered by “DispatcherObject” that we can invoke members defined inside the “Dispatcher” class. Dispatcher class is instantiated as soon as any class which derives from “DispatcherObject” is accessed. All further request are processed by this newly created instance.

Coming back to “DispatcherObject” class , it offers two methods namely CheckAccess and VerifyAccess.
  • CheckAccess : Determines whether the calling thread has access to this DispatcherObject. Only possible return values are true and false.
  • VerifyAccess : VerifyAccess is more stringent compared to CheckAccess. It checks whether the calling thread is the one which created the DispatcherObject. If not it throws “InvalidOperationAccess” exception. Getting back to the example which I gave in the beginning, in that we were trying to update the UI through code which was running on a different thread. Internally VerifyAcess is invoked and once it verifies that calling code is different from the one which controls the application, it throws the “InvalidOperationError” exception.
Figure 1 DispatchPriority Prioritization Levels (in Priority Order)
PriorityDescription
InactiveWork items are queued but not processed.
SystemIdleWork items are only dispatched to the UI thread when the system is idle. This is the lowest priority of items that are actually processed.
ApplicationIdleWork items are only dispatched to the UI thread when the application itself is idle.
ContextIdleWork items are only dispatched to the UI thread after higher-priority work items are processed.
BackgroundWork items are dispatched after all layout, rendering, and input items are processed.
InputWork items are dispatched to the UI thread at the same priority as user input.
LoadedWork items are dispatched to the UI thread after all layout and rendering are complete.
RenderWork items are dispatched to the UI thread at the same priority as the rendering engine.
DataBindWork items are dispatched to the UI thread at the same priority as data binding.
NormalWork items are dispatched to the UI thread with normal priority. This is the priority at which most application work items should be dispatched.
SendWork items are dispatched to the UI thread with the highest priority.

Difference between regasm and regsrv32, tlbimp.exe,tlbexp.exe


Regasm.exe(Register Assembly)
regasm.exe is used to create COM Callable Wrapper (CCW) around .NET assemblies. .NET managed assemblies(EXEs, DLLs) are different from COM DLLs (which are unmanaged, ie. they interact with the OS directly). So to register an unmanaged DLL you use regsvr32.exe.

But if you have a managed .NET assembly and want you COM components to use it as if it were a COM assembly, then you need to use regasm.exe.It can generate a .tlb file given the assembly only - it inspects the type infromation stored in the assembly and includes the COM-exposed entities into the type library.

“Regasm.exe, the Assembly Registration tool that comes with the .NET SDK,  reads the metadata within an assembly and adds the necessary entries to the registry, which allows COM clients to create .NET Framework classes transparently. Once a class is registered, any COM client can use it as though the class were a COM class. The class is registered only once, when the assembly is installed. Instances of classes within the assembly cannot be created from COM until they are actually registered.“


Regsvr32
regsvr32 will load the library and try to call the DllRegisterServer() from that library. It doesn't care what DllRegisterServer() actually does - it just calls that function and checks the returned value. You use it to register COM servers in unmanaged DLLs. It can't generate a .tlb file.To register the .dll for the Active Directory Schema

"Regsvr32 is the command-line tool that registers dynamic-link libraries (dlls) and ActiveX controls in the registry.
Tlbexp.exe
The Type Library Importer converts the type definitions found within a COM type library into equivalent definitions in a common language runtime assembly. The output of Tlbimp.exe is a binary file (an assembly) that contains runtime metadata for the types defined within the original type library. You can examine this file with tools such as Ildasm.exe.

Tlbexp.exe generates a type library that contains definitions of the types defined in the assembly. Applications such as Visual Basic 6.0 can use the generated type library to bind to the .NET types defined in the assembly.The entire assembly is converted at once. You cannot use Tlbexp.exe to generate type information for a subset of the types defined in an assembly.

The entire assembly is converted at once. You cannot use Tlbexp.exe to generate type information for a subset of the types defined in an assembly.

You cannot use Tlbexp.exe to produce a type library from an assembly that was imported using the Type Library Importer (Tlbimp.exe). Instead, you should refer to the original type library that was imported with Tlbimp.exe. You can export a type library from an assembly that references assemblies that were imported using Tlbimp.exe.

Tlbexp.exe generates a type library but does not register it. This is in contrast to the Assembly Registration tool (Regasm.exe), which both generates and registers a type library. To generate and register a type library with COM, use Regasm.exe.

Type Library Importer(Tlbimp.exe)
Tlbimp.exe (Type Library Importer) is used to create a Runtime Callable Wrapper around a COM component so that the unmanaged COM library can be used in .NET.
When do we use Tlbimp and not regasm or regsvr32?

Tlbimp.exe performs conversions on an entire type library at one time. You cannot use the tool to generate type information for a subset of the types defined within a single type library.

TlbExp.exe and Regasm.exe tools aid us in exporting assembly information to a type library so that non .NET Applications or unmanaged code use this type library information to call .NET assembly.
Just like tlbimp which works on the entire COM Component tlbexp works on the entire assembly.
The entire assembly is converted at the same time. You cannot use it to generate type information for a subset of the types.
Tbexp only generates the type library information for an assembly but it does not register the type libraries unlikeregasm.exe

Regasm.exe creates a type library as well as registers it whereas tlbexp.exe only creates a CCW but does not register it.
Tlbimp.exe (Type Library Importer) is used to create a Runtime Callable Wrapper around a COM component so that the unmanaged COM library can be used in .NET.
Let us now create an assembly for which we will create a type library and use it through Visual Basic.
  1. Open a new dotnet project (Class Library)
  2. Add a class to the project called MyClass as below
    public class MyClass 
  3. public MyClass() 
  4. public int Add (int i , int j)
  5.  { return i +j;
  6.  } 
  7. public int Mul (int i , int j) 
  8. { return i *j; } }
  9. Strong name your assembly, compile the project and create the assembly
  10. Go to the Visual Studio command prompt and type tlbexp /? to explore all the options. I have enlisted them below:
    /out:FileName File name of type library to be produced 
  11. /nologo Prevents TlbExp from displaying logo
  12.  /silent Prevents TlbExp from displaying success message
  13.  /verbose Displays extra information 
  14. /names:FileName A file in which each line specifies the captialization of a name in the type library. 
  15. /? or /help Displays this usage message
  16. To create a typelibrary from it type the following command tlbexp .dll e.g.tlbexp tlbexp.dll
  17. If the export was successful a success message diplaying the entire path and the name of the .tlb will be shown to you
    Assembly exported to F:\Net\tlbexp\bin\Debug\tlbexp.tlb
  18. You can also use the /verbose option to check out the details of the classes that were exported
  19. Although our typelibrary is created, our assembly is not yet registered. You can register the assembly using regasm tool
  20. Go to the Visual Studio command prompt and type regasm /? to explore all the options. I have enlisted them below:
    /unregister Unregister types /tlb[:FileName] Export the assembly to the specified type library and register it 
  21. /regfile[:FileName] Generate a reg file with the specified name instead of registering the types. This option cannot be used with the /u or 
  22. /tlb options 
  23. /codebase Set the code base in the registry 
  24. /registered Only refer to already registered type libraries 
  25. /nologo Prevents RegAsm from displaying logo 
  26. /silent Silent mode. Prevents displaying of success messages 
  27. /verbose Displays extra information 
  28. /? or /help Display this usage message
  29. To only register the assembly, use the following command: regasm .dll e.g. regasm TlbExp.dll
  30. You can also create a .reg file containing all the registry entries: regasm TlbExp.dll /regfile:myTlbExp.dll .reg
  31. You also create typelibrary from assembly using regasm tool by using /tlb option
  32. To use this component from VB 6.0 put the assembly in GAC. You can do this by either using gacutil or just dragging and dropping the assembly in /winnt/assembly folder
  33. You can now use this assembly from VB 6.0
  34. Open a VB std project. Go to references. Select the .tlb file that we generated from the list
  35. Yes, you can now use your .NET assembly from VB 6.0. The sample code of using your .NET assembly from VB:
    Dim tlbExp As tlbExp.MyClass 
  36. Set tlbExp = New tlbExp.MyClass
  37. Label1.Caption = tlbExp.Add(1, 2)

Followers

Link