Skip navigation
All Places > PI Developers Club > Blog > 2012 > January


Posted by MvanderVeeken Employee Jan 26, 2012


One of the common things I have noticed with Web Services is that after you installed them you need a quick way to test them to say they work or not. As PI Web Services responds to web queries using the Simple Object Access Protocol (SOAP) related data from the PI Server and/or the PI AF Server, you need to test the pathways. Many components are involved during the installation: configure the virtual application on the Web Server (IIS), ASP.NET, application pool, web.config, PI SDK, AF SDK, security, etc. Also, other elements can come into the game: questions related to Active Directory forest, domain(s) and workgroup, and the network routes and filters. Looking at all these details, I know many things can go wrong. So, my focus is starting from a basic scenario to test the main components to assess a minimal set of things. I learned with Web Services that the more security layer you add the more difficult it becomes. Anyway, your first idea should be testing that each components can communicate and close the loop. The higher level of security will come up at a later time.


The first test to do is to try to open a connection on your Web Server, then try to reach the folder of your virtual application (here it is the PI Web Services). Try to retrieve the service descriptors (WSDL) which will be returned when you query the service handler at this URI: http://<server>/PIWebServices/PITimeSeries.svc?wsdl. If you got success until that part you need to test a specific method provided by this service but you will need to either code your application or use a Web Service functional tool. Both of these solutions require time or an installation process that would leave a footprint on the machine. What you want it's an easy solution that could say my installation is working from A to Z. This takes more sense if you are performing the installation at a customer's site on production assets. There are a lot of chances they would refuse you the rights to install other pieces of software that might affect the server.


An easy solution is possible for you and it is a Powershell script. For those of you which would not be familiar with Powershell, I propose you a nice and short description coming from Wikipedia which is: "Windows PowerShell is Microsoft's task automation framework, consisting of a command-line shell and associated scripting language built on top of, and integrated with the .NET Framework. PowerShell provides full access to COM and WMI, enabling administrators to perform administrative tasks on both local and remote Windows systems."


The use of scripts give you strong advantages, as it does not install a codebase on the machine and it can be easily modified to suit your needs. You will need Powershell version 2.0 and later to achieve this. The version 1.0 of Powershell was based on .NET Framework 2.0 only but the later version was ported to use the .NET Framework 3.5. As we are communicating with Web Services implementing the Windows Communication Foundation (WCF) which was introduced with the .NET Framework 3.5 we need Powershell version 2.0. For an easy introduction, I will cover only the basics to connect using basic bindings (meaning with no security), other bindings would be part of a later post.


The script contains two cmdlets: PIWS-TestGetPIArchiveDataWithSOAP and Format-XML, the first one is to send a SOAP message to PI Web Services via a WebClient object and receive the answer, the second is process for processing the XML returned string. Starting from cmdlet PIWS-TestGetPIArchiveDataWithSOAP, we need to create a Webclient object to communicate with the PI Web Services, a WebHeaderCollection object to define the content of the message and the SOAP action, and finally an XML message that will contain all the necessary information for the Web Services. Using the [string]::Format method, you can easily manipulate an XML template with the different arguments to replace within to form your message. The final stage is to post your message to PI Web Services and wait for an answer. This is done as a synchronous process. The returned XML is formatted with the second cmdlet and output to the console. The PIWS-TestGetPIArchiveDataWithSOAP cmdlet is called with the last instruction which is part of the main of your script. You need to pass the endpoint, the URI of PI Web Services, the item which is a valid path, the start and end time, and the number of values to return for interpolated values. Save your file with the name PIWS-TestGetPIArchiveDataWithSOAP.ps1.


To utilize your script, you will need to open a command prompt and call powershell or call powershell directly from the Run command. As a very important step, you will need to unlock the policy for using this type of script by invoking the cmdlet: Set-ExecutionPolicy RemoteSigned at the Powershell prompt. Afterward, you can invoke your script wherever you saved it by simply typing its full path and name. If you receive errors directly inside the Powershell session, it means something is not configured properly somewhere. Otherwise in case of success you will receive a screen that looks like the following.





The same error message will be sent thorough Powershell then if it was your Visual Studio environment. Try different paths involving PI AF to test this part of the configuration. After successful tests from the machine, you can copy your script to a client machine and see if it still works from there. This completes the testing workflow for basic bindings.







Get a copy of this script from this link (as publishing Powershell scripts is not nice on the Web). Stay tune for later blog posts and a white paper to test all other Web methods offered by PI Web Services. Did you use scripts of your own before, share some thoughts with me by replying to my blog.



I have added a link to a new version of the script here. It fixes the PIArcManner object parameters to handled properly.


Are you up for the challenge?

Posted by jlakumb Jan 24, 2012

As Jon Peterson announced last month, we're looking for customers and partners who would like to join the PI Server 2012 Technology Adoption Program (TAP).  This release of PI Server offers significant gains in scalability and performance, as well as improvements in manageability and reliability.  If you haven't already seen it, check out this video of our vCampus Live! presentation for a sneak peek.  Do you have a particularly interesting use case which could benefit from PI Server 2012?  Are you willing to share your story with other customers and partners?  Then send us an e-mail at and we'll follow up with a short survey.  The first beta version will be available to TAP participants by the end of January.


Think you're up for the challenge?

Recently I built for myself a brand new PI System environment to test and develop around the new PI System for my upcoming role in vCampus (Yes I joined the team this week).  I was looking for installing a virtual machine that would host the server components of the PI System: PI Server 2010 SP1 and PI AF 2010 R3. I decided I’ll test the use case of an environment with no graphical user interface such as Windows Server core.  


For those of you that would not be familiar with what Windows Server Core is, it is a significantly scaled-back installation where no Windows Explorer shell is installed. All configuration and maintenance is done entirely through command line interface windows, or by connecting to the machine remotely using Microsoft Management Console. You can learn more about it using this Microsoft link and is offered free by Microsoft up to now and since its initial release.


My next step was to verify the OS specifications for the different components required such as Microsoft SQL Server, .NET Framework 4, PI Server 2010 SP1, PI AF 2010 R3, PI SDK 1.4, etc. and all of them could work on a Windows Server core environment (offered by Windows Server 2008 R2 SP1). So, I downloaded it from one of the Microsoft Download sites, installed and configured it with an unprecedented ease with a very nice tool called Core Configurator (available here at CodePlex). I’ll blog later on the advantages given by this tool.





The installation process didn’t go as a straight line for some components but I found my way out. How I succeeded would be part of further blog posts. As a final step, I launched the pisrvstart.bat script from the command prompt to start the PI Server and PI AF Server, and watched the messages returned by the different PI Subsystems at the look of any eventual errors but none of them came. I utilized PI System Management Tools and PI System Explorer from a client machine to validate my new installation and everything was up and running smoothly. Congratulations! The PI Server and PI AF components were installed and functioning at 100%.







I started wondering if all the pieces installed with the PI Server and PI AF, such as the PISDKUtility.exe could run directly from this core environment. I invoked the pisdkutility.exe command, the tool that replaced the former AboutPI-SDK.exe and I got the PI SDK Utility window in my screen. I tested all the options and all of them were working great.







An idea started to take form in my head. What about PI ACE! Wouldn’t be that great if it could work within such an environment? I looked at the documentation and nothing was said that it works or not. Thus I copied the setup kits, launch the installation and respond to standard installation questions. I was brought up to the point of choosing the components to be installed, from which I only selected the PI ACE Scheduler 2.x item and click on the OK button. The installation had completed perfectly and left me at the command prompt. Knowing that PI ACE Scheduler service is not started by default, I started it by using the sc start piacenetscheduler command and verified its status with sc query piacenetscheduler command a few seconds later.







A few glimpses at the PI Message Log using the PI SDK Utility returned me that the PI ACE (PI Advanced Computing Engine) 2010 R2 (version was running on a Windows Server core and awaiting my first calculation module.  A few minutes later, I had created a typical basic calculation module firing naturally and made of the multiplication by two of the CDT158 point into an output point which was holding the results. The results seen were more than expected. I just started imagining all the new horizons and use cases that could be addressed with a core environment (This will be part of a further blog post).


 Have you attempted some other tests with PI System components and the Windows Server Core environment? Please share your attempts, your ideas or your questions.

Recently, there was a discussion thread within the vCampus community regarding whether a facelift is needed for our beloved PI ProcessBook.


In the ensuing discussion, there were several comments on desired changes to PI ProcessBook functionality (which is not the same as a visual update in any way). Part of that commentary was an expressed frustration with not knowing how to get enhancement requests addressed. I wanted to take some time to be frank about proposed changes to PI ProcessBook as we know and love it.


It is no great secret that PI ProcessBook has been evolving from the original code base for about 15 years now. It is also no secret that the technology on which it is based is rather dated. Furthermore, as features have been added over the years, the code has grown more complex and difficult to maintain. As a result, the last few releases of PI ProcessBook have featured new capabilities that have added on to the existing features rather than re-writing them. One reason for this approach has been that we are ever sensitive to the investment existing users have made in PI ProcessBook content and we have no intention of releasing a new version that breaks their existing displays, to the best of our ability to prevent that. (I recently received anecdotal evidence that displays created 10 years ago or more continue to be used in PI ProcessBook today--not a bad testimony to the product's overall stability.)


The effect of this conservative approach is that we don't intend to make deep architectural changes to PI ProcessBook. So, things like changing the way symbols are drawn or rendered are not going to happen.


That doesn't mean there isn't anything useful to add to the existing capabilities.


Of those requested changes that do not represent deep changes to how the product works, there is a rather long list of things that could be done. Requests for change are weighed against one another as well as other factors. For example, those cross-product capabilities of the PI System that the company is focused on may take priority over smaller requests for changes that only affect PI ProcessBook. Problems customers have in making displays work the way they were intended (and for which there isn't any remedy) often take precendence over requests that would be handy but can still be done in some fashion. New versions of Microsoft technologies that have an impact on PI ProcessBook (e.g., a new operating system, new versions of .NET, etc.) need to be tested for compatibility and any issues considered. Capabilities that allow PI ProcessBook to be useful in newer markets (e.g., customers outside of North America) may also get precendence, if that is strategic for the company.


Whenever we plan a new release of PI ProcessBook, we look at the major new capabilities we plan to provide and then consider which of the outstanding requests would fit in with the planned work. Sometimes, priorities change between the initial planning and final release of a new version. Our PI System Roadmap, available on the Technical Support web site, characterizes those enhancements to which we've committed for an upcoming release and, often, the additional changes we've considered adding (but which may change). We don't list every single change we are planning (on the Roadmap) because that information can change more quickly as particular requests are investigated (for example), and keeping such a list truly up-to-date is difficult at best. We do try to mark the planned items when a release is started, but the work may get delayed for many reasons (there is a technical barrier, the developers don't understand the desired functionality well enough, another item with higher priority intrudes, there are conflicting requests from different customers, etc.). This process isn't designed to frustrate our customers, but it is a reality in a product-development company that serves many industries that have a variety of similar yet unique requirements for displaying time series data in a graphical fashion.


Hopefully, I've been clear about the sort of decison-making we go through at OSIsoft. I do understand that it can be very frustrating not to know when your particular request will get addressed, for sure, but that doesn't mean we aren't trying to provide new and useful features to PI ProcessBook.

There are a lot of examples available on vCampus on how to access PI Web Services from .NET. PI Web Services is based on Windows Communication Foundation (WCF) and integration with Visual Studio is very good. There are less examples on how to access PI Web Services from Java yet, and there has been some interest in this. Steve Mohr posted a Java sample for the CTP release of PI Webservices earlier.


I haven't worked with Java for years, so I thought it would be a nice challenge to dive into it a little bit and share it with the community.


Getting started


To get started, you will need the following

  • PI Web Services. PI Web Services in available at the Download Center. The PI Web Services User Guide (pdf or chm) is available in the Library under 'vCampus Library > vCampus PI Products Kit > Data Access Technologies'.
  • Java Development Kit (JDK). You need the JDK to develop, you cannot use the Java Runtime Environment (JRE) in this case. You can download the newest JDK versions here.
  • Eclipse. An IDE for Java, you can download it for free here. There is no installation required. You can run eclipse.exe it when you unpack it. You probably want to unpack it at a convenient location (e.g. 'C:\Program Files\Eclipse')
  • GlasFish Metro. The web service stack for Java we are going to be using. This is also free. You can download it here

Installing Metro is very straight forward. Go to a directory where you want to install Metro, copy the Metro_1_4.jar file and execute it by double clicking or running 'java -jar metro-1_4.jar' in the command prompt. This will create a new 'metro' sub directory.


Creating the Java classes for PI Web Services


What we want to do first is let Metro create all the appropriate Java classes for PI Web Services. We are going to use a tool called 'wsimport', which is roughly the equivalent of Microsoft's 'svcutil' tool. In order to do this, we are going to make a small 'description' file for our PI Web Services client. 


Go to the directory where you just installed 'Metro'. Create a new XML file called 'PIWebservices.xml' with the following content:














    <bindings node="wsdl:definitions">








The URL (in red) should be the URL to you PiTimeSeries.svc service, don't forget the port number (e.g. http://piserver:8080/PIWebservices/PiTimeSeries.svc?wsdl). The 'enableAsyncMapping' makes sure we also generate asynchronous methods to the server. Save this file and close it. We are not ready to generate the java classes with wsimport. Startup a command prompt and navigate to your Metro directory.


First, we want to make sure we set the 'JAVA_HOME' variable. If it is already set properly (you can check this by executing 'echo %JAVA_HOME%' in the command prompt), you can skip this step. wsimport makes use of this variable to access the java tools from the JDK. When we are sure JAVA_HOME is set correctly, we can execute the following command:


bin\wsimport -extension -keep -Xnocompile -b PIWebservices.xml http://ultralisk/piwebservices/pitimeseries.svc?wsdl


Again, make sure that the URL in red is the URL to your PITimeSeries.svc file. The PIWebservices.xml file is the XML file we created previously. You should get the following output:




If you look closely, you will see that a new directory called 'com' has been created in your Metro installation directory. If you browse to it, you will notice that it is a few levels deep ('\com\osisoft\xml\services\pidataservice'). You will see that a lot of .java files have been created. If you are familiar with PI Web Services, you will notice that these files are named after PI Web Services operations and data structures.




Creating the Java Project


We are going to use these generated classes in our Java project. Start up Eclipse, and create a new Java Project (File > New > Java Project) called 'PIWebservicesClient.




Click Finish. In the package explorer, expand the 'PIWebservicesClient' node and right click on the 'src' folder. Select New > Class, and name it 'Main'. Also make sure the wizzard creates the 'public static void main(String[] args)' entry method.




Click Finish. Now we are going to import the .java files we generated with wsimport. In Windows Explorer, select the 'com' folder (in the Metro directory) and drag the folder to the 'src' folder in Eclipse. If it asks how the files and folders should be imported, select 'Copy files and folders'. Click OK. You will see that a new '' package has been created in your 'src' folder.




Now that all the preparations are done, let's get to some Java coding. For our first example we are going to get the snapshot value of a PI Point using the getPISnapshotData method.


Go to your Main class, and change it to look like this:

import javax.xml.namespace.*;

public class Main {

      * @param args
     public static void main(String[] args) {
          // TODO Auto-generated method stub
          try {
               PITimeSeriesService service = new PITimeSeriesService(new URL("http://ultralisk/PIWebservices/pitimeseries.svc?wsdl"),
                         new QName("", "PITimeSeriesService"));
               IPITimeSeries port = service.getBasicEndpoint();
               ArrayOfString paths = new ArrayOfString();
               ArrayOfTimeSeries result = port.getPISnapshotData(paths);
               TimeSeries timeSerie = result.getTimeSeries().get(0);
              TimedValue value = timeSerie.getTimedValues().getTimedValue().get(0);
               System.out.println(timeSerie.getPath() + " " + value.getTime() + " " + value.getValue());
          } catch (Exception e) {
               // TODO Auto-generated catch block

 Again, make sure you set the URL's to your PI Web Services URL, and change the path of the PI Point ('sinusoid') to your PI Server. Please note the double backslashes used for escaping. If we run this code in Eclipse, the output should be:




This means we have successfully called the GetPISnapshotData method on our PI Web Services service! You will probably have noticed that all the data is in container structures, so it's a little bit different than we are used to.


A little bit more advanced example would be getting archive data.

// TODO Auto-generated method stub
          try {
               PITimeSeriesService service = new PITimeSeriesService(new URL("http://ultralisk/PIWebservices/pitimeseries.svc?wsdl"),
                         new QName("", "PITimeSeriesService"));
               IPITimeSeries port = service.getBasicEndpoint();
               ArrayOfPIArcDataRequest requests = new ArrayOfPIArcDataRequest();
               PIArcDataRequest request = new PIArcDataRequest();
               TimeRange timeRange = new TimeRange();
               PIArcManner manner = new PIArcManner();

               ArrayOfTimeSeries result = port.getPIArchiveData(requests);
               TimeSeries serie = result.getTimeSeries().get(0);
               for (TimedValue value : serie.getTimedValues().getTimedValue())     {
                    System.out.println(serie.getPath() + " " + value.getTime() + " " + value.getValue());
          } catch (Exception e) {
               // TODO Auto-generated catch block

 If we run this, the output should be something like:




From here


If you look at the 'PI Web Services User Guide', you should be able to roughly translate all the operations and structures to their Java equivalent. Getting the Java classes generated and creating the connection objects is probably the unfamiliar part. Once that is set up, accessing the right PI Web Services methods and extracting the right information from the structures should be straight forward.


If you have any questions about PI Web Services, please have a look at the Web Services and PI discussion forum.







Posted by mhamel Employee Jan 16, 2012

Have you ever use the reflection to examine your code produced after a successful compilation of your PI System application using the PISDK? For those of you that are not familiar with the reflection principle, it is the process by which a computer program can observe (do type introspection) and modify its own structure and behavior at runtime. I did recently for one of my project where I had to write the same project but using C# instead of Visual Basic. Something caught my eyes when reviewed the code. Some of the declarations I made with the PISDK objects were replaced with PISDKClass instead as shown below.




'Class Member Objects.



Private Sub OpenPIServerConnection()       

    _MyPISDK = New PISDK.PISDK       

    _PIServer = _MyPISDK.Servers(_TargetPIServer)

    If Not _PIServer.Connected Then


    End If

End Sub

Excerpt of my project written in VB.NET




'Class Member Objects.



Private Sub OpenPIServerConnection()

    Me._MyPISDK = New PISDKClass

    Me._PIServer = Me._MyPISDK.Servers.Item(Me._TargetPIServer)

    If Not Me._PIServer.Connected Then


    End If

End Sub

Excerpt of the code rendered via reflection




Why the compiler replaced the instantiation of the _MyPISDK object with the PISDKClass instead of the PISDK one? Several examples of codes in these forums show connectivity with the PI Server using the PISDKClass class instead of the PISDK one as described in the PISDK help file. I dug the subject a bit and here what I found.




If you look carefully at the PI SDK object model you can see the PISDK object is declared as a COM class, meaning this object is creatable by using its constructor; if you compare the COM Interop library OSIsoft.PISDK.dll, the same object is declared as an interface. Let refresh our mind on the basic definition of a class and an interface enumerated below.


Class Definition


A class is a construct that is used as a blueprint to create instances of itself (referred most of the time as instance objects). A class defines constituent members which enable these class instances to have state and behavior.


Interface Definition


An interface contains only the signatures of methods, delegates or events. The implementation of the methods is done in the class that implements the interface. An interface is not creatable by definition.


Declare a New Object from an Interface?


Per the documentation we should be able to create a new PISDK top-level object with the New keyword either in the COM or the .NET world. How will it be possible within the .NET world as the New keyword cannot be used with an interface?


The answer lies into how a COM Interop library is formed. A class is COM's language-independent way of defining a class in the object-oriented sense. A class can be a group of similar objects or a class is simply a representation of a type of object; it should be thought of as a blueprint that describes the object. A coclass supplies concrete implementation(s) of one or more interfaces (a default interface and sometimes secondary interfaces). In COM, such concrete implementations can be written in any programming language that supports COM component development, e.g. Delphi, C++, Visual Basic, etc.


When this COM coclass is converted into the .NET world i.e. a .NET interop, a public interface with the same name as the COM coclass is created; it is known as a coclass interface and has no members itself. This .NET interface derives from the converted COM coclass’ default interface. Both created interfaces are marked with the same IID. To complete the conversion of this COM coclass, another piece is created to bridge the COM and .NET worlds. This piece is a Runtime Callable Wrapper (RCW) class that will be named with the COM class name and the "Class" suffix. The RCW class calls the native CoCreateInstance COM function for creating the COM object that it wraps. The RCW class will convert each call to the COM calling convention.


Creating a new object derived from a coclass interface will result into creating the desired COM object via the RCW class. The coming example will shed some light on how this done. The RunTime Callable Wrapper is explained in the following section.


Runtime Callable Wrapper


COM differs from the .NET Framework object model in several important ways:


·          Clients of COM objects must manage the lifetime of those objects; the Common Language Runtime (CLR) manages the lifetime of objects in its environment.


·          Clients of COM objects discover whether a service is available by requesting an interface that provides that service and getting back an interface pointer, or not. Clients of .NET objects can obtain a description of an object's functionality using reflection (analysis of the libraries/assemblies themselves).


·          .NET objects reside in memory and are managed by the .NET Framework execution environment. The execution environment can move objects around in memory for performance reasons, in which case it will update all references to the objects it moved. Unmanaged clients, having obtained a pointer to an object, rely on the object to remain at the same location. These clients have no mechanism for dealing with an object whose location is not fixed.


To overcome these differences, the runtime provides wrapper classes to make both managed and unmanaged clients think they are calling objects within their respective environment. Whenever your managed client calls a method on a COM object, the runtime creates a runtime callable wrapper (RCW). RCWs abstract the differences between managed and unmanaged reference mechanisms, among other things. The runtime also creates a COM callable wrapper (CCW) to reverse the process, enabling a COM client to seamlessly call a method on a .NET object. As the following illustration shows, the perspective of the calling code determines which wrapper class the runtime creates.







Creating a top-level PISDK object like presented below is correct from the .NET world because the PISDK interface is in fact a coclass interface defaulting to the RCW class called PISDKClass.



The .NET Visual Basic or .NET C# linker or interpreter will change your code to respect the official syntax to create a variable to the PISDK interface and instantiate it with the PISDKClass class:




You can then interchangeably use these:


'Example 1




'Example 2


Mainly the difference resides on the members exposed by both implementations, the PISDK coclass interface inherits only from the IPISDK interface and the PISDKClass class inherits from the IPISDK, PISDK, IPIAppIdentity and the IPIGlobalRestorer. Creating an object instance from the PISDKClass will give you natively access to members of all implemented interfaces without having to cast the object into another interface. This is a faster and more straight-forward way to use the PISDK top-level objects, as shown in the following examples.


' Use the PISDK coclass interface and derived into a different

' interface to access more members.

' Variables / Ojects.


Dim AppIdentity as PISDK.IPIAppIdentity

Dim PIserver As PISDK.Server


'Derive this object to the IPIAppIdentity interface.

AppIdentity = DirectCast(MyPISDK, IPIAppIdentity)


' Set a unique identifier for your application.

AppIdentity.Identifier = "00000000-0000-0000-0000-000000000000"


' Set a reference to the PI Server.

PIserver = MyPISDK.Servers.DefaultServer


' Open the connection.




' Access directly all members by using the PISDKClass RCW class.

' Variables / Objects.


Dim PIserver As PISDK.Server


' Set a unique identifier for your application.

MyPISDK.Identifier = "00000000-0000-0000-0000-000000000000"


' Set a reference to the PI Server.

PIserver = MyPISDK.Servers.DefaultServer


' Open the connection.




All COM coclasses from the PI SDK can be instanciated using the RCW classes the same way. The RCW classes in the COM Interop library are adding the "Class" suffix at the end such as for PIValueClass and PIValuesClass for handling the PIValue and PIValues class definitions from the COM world.


I hope this shed some light on the topic. Either you choose the standard PISDK and let the compiler replaces it or you use directly the PISDKClass definition in your project, it will perform the same.

Maybe you have seen the blog post with attached video about a little project I've been working on. The project is to create a .NET object Serializer for PI AF.


In the previous video I made some suggestions for improvements, and there is some progress there. It is more and more starting to look like a nice abstraction of the AF SDK. It makes for a more declarative way of handling AF data.


Please find the update video below (or download it here), and you can find the updated source code attached to this post.


Please let me know what you think!



A lot of us are developing applications against PI AF. The AF SDK or PI OLEDB Enterprise are the way to go when you need access to PI AF data.


The AF SDK is very powerful when it comes to dealing with AF Data. There are a lot of options, and I think the SDK is very well structured. However, if you are like me a lot of the time you just want to quickly put data in AF, and want to quickly pull it. In a lot of cases this involves translating AF SDK calls into .NET objects.


This concept shows a simple AFSerializer library that allows you to quickly store .NET objects in PI AF. I think this can be much more enhanced to make PI AF more of a flexible .NET object database. Please find the demo video below (or download it here (mp4)).


Code sample and source code is attached below.


Enjoy! And let me know what you guys think of the concept.



Everyone on vCampus knows Rhys Kirk (AKA Rhys @ Wipro). He is a 2 time vCampus All-Star, and one of the most active users on the forums.


11/18/2008 3:38:03 PM was the date he joined us and his first post (1000 so far, and many more to come) was Dec 2 2008. 


We as the vCampus Team (and a few others!) would like to congratulate and thank you!


Thank you for all your contributions and hard work!



Filter Blog

By date: By tag: