Tuesday, June 29, 2010

Windows 7 Blackscreen of Death BSOD - Completely black desktop with mouse activity.

Just got a windows 7 notebook machine back up and running after suffering the BlackScreenOfDeath Issue.

Initially I suspected that the screen settings had shifted the desktop off to an external monitor which was not currently attached. But when no context menu came up from a right click of the desktop, I realized there was no desktop running. This led me to believe that explorer.exe had not started. So with a ctrl+alt+del I got to the task manager (good sign) and could see that indeed there was no explorer.exe process running.

The next step was to try and fire it up manually using the "New Task" button on the Task Manager. This only returned an error message stating that no explorer.exe could be found. I did a little Google-ing to confirm that explorer  was still explorer in Windows 7 (which it is). Along with that Google search I found out that I was experiencing the BlackScreenOfDeath issue and that the security company PrevX had a solution (PrevX Article).

I later read that the PrevX solution was not the fix-all. It did address the issue of a possible missing registry key which points to the location of explorer.exe for the system to launch the desktop process when a user logs on. After confirming the registry key was intact, off to confirming the location of the exe.

The explorer.exe file should be located in the Windows directory, but it was not. Which explains why the desktop failed to launch leaving the user with the BSOD. I did a search of the user's hard drive and found several versions of the exe in question in subdirectories located in the Windows\winsxs directory. Curiously, I launched one of the executables located under an "AMD64..." directory (even though this was an INTEL) and the desktop loaded. The explorer.exe's under the "WOW64..." and "X86..." directories failed to launch with an error.

In the end, I copied the explorer.exe (the one that worked) from the Windows\winsxs\AMD64... directory into the Windows directory and restarted the machine.

Whaa Lahh, the machine is golden. Hope this helps.

Wednesday, June 23, 2010

From TIM


Serialize (convert an object instance to an XML document):
// Assuming obj is an instance of an object
XmlSerializer ser =
new
XmlSerializer(obj.GetType());
System.Text.StringBuilder sb = new
System.Text.StringBuilder();
System.IO.StringWriter writer = new
System.IO.StringWriter(sb);
ser.Serialize(writer, obj);
XmlDocument doc = new
XmlDocument();
doc.LoadXml(sb.ToString());

Deserialize (convert an XML document into an object instance):
//Assuming doc is an XML document containing a serialized object and objType is a System.Type set to the type of the object.
XmlNodeReader reader =
new
XmlNodeReader(doc.DocumentElement);
XmlSerializer ser = new
XmlSerializer(objType);
object
obj = ser.Deserialize(reader);// Then you just need to cast obj into whatever type it is eg:
MyClass myObj = (MyClass)obj;



Thanks Tim

Monday, June 14, 2010

To add user to ASAM
1) Create account
2) Add account and areacode relationship(s)

To add Sity client reports to a Client
1) Add Client SQLRS server account as "browser" to SityClient Reports folder.
2) Add Client SQLRS server account to the [AparcSystemsSpExecutor] role


NOTE:

Be sure all NEW procedures are added to the [AparcSystemsSpExecutor] role

To Add a SQLRS user
1) Create new machine/Windows account ("svcServiceAccount")
2) Add user to SQL server instance(s)
3) Add to:
i) AparcSystems with R/W permissions and AparcSystemsSpExecutor
ii) SityDb with R permissions
iii) SityDbxxxxx Client DB with R permissions and AparcSystemsSpExecutor
4) Add user account to SQLRS reports user param for Client via ASAM.

Saturday, June 12, 2010

When Posting Sity Client Reports, all reports must have their datasource properties changed to use:



Hit <Apply>

Thursday, June 03, 2010

When passing SQLRS report parameters through the URL be sure to use the ReportServer and not the Reports

Want to pass hidden parameters to an SQLRS report in a browser?
Just add the parameter name and value to the query string pointing at the ReportServer URL like so:

http://reportingserver.aparcsystems.com/ReportServer/Pages/ReportViewer.aspx?%2fReports%2fTransactionDetails&rs%3aCommand=Render&PARAMNAME=PARAMVALUE

Wednesday, May 05, 2010

Loading an unmanaged C++ dll into a managed c# class (.Net 3.5)

I am developing a .NET 3.5 C# Webservice which calls methods from within an unmanaged C++ dll. Aside from the basic issues of wrapping the structs and method calls for use by the C# class, I ran into a couple of hurdles deploying.

ISSUES:
(1)
Server was unable to process request. ---> System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

(2)
Server was unable to process request. ---> Unable to load DLL 'SPInterface.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

SOLUTIONS:
(1)
Be sure that your app_pool managing your webservice/site is allowing 32bit applications if running on a 64bit platform (IIS7)
OR
Be sure that your application is built as an x86 project
goto Configuration Manager and set the project to build as x86
(If Configuration Manager is not available, goto Tool>Options>Projects and Solutions>General>Show advanced build configurations)

(2)
Be sure that your unmanaged dll appears in your site bin folder.
Be sure that all resources (dll, lib, etc.) referenced by your dll are also in your bin.

Wednesday, April 21, 2010

While loading controls inside an asp:LinkButton will render correctly on Page_Load, after post back the control loses the contained controls

e.g.
<asp:LinkButton id="btnShowReport" runat="server" OnClick="btnShowReport_Click">
<img src="images/16doc.gif" height="16" width="16" />
<asp:Label id="lblReportTitle" runat="server"/>
</asp:LinkButton>

This code appeared within an asp:Repeater, where the CommandName and CommandArgument of the LinkButton were being set dynamically along with the Text property of the Label. But on postback to bthShowReport_Click, all the links essentially disappeared. I discovered that the <a> tags where still in the page on PostBack, but the contents making them functional where gone.

It was a nice try but now... Just as simple but perhaps more elegant, but mostly IT WORKS!

<asp:ImageButton id="btnShowReport" runat="server" OnClick="btnShowReport_Click" ImageUrl="images/16doc.gif" style="vertical-align: middle"/>
<a>
<asp:Label id="lblReportTitle" runat="server" AssociatedControlID="btnShowReport"/>
</a>

I use the associated control to tie the label to the click event of the image button and some anchor tags give the linkbutton feel to the label.
Could have made the label a linkbutton and use the same onclick event handler as the imagebutton . But in the method I would have to check the type to do the correct cast of sender in order to get the command name and argument.

Dumb problem, simple solution. It just drove me nuts to see all the links disappear on postback so had to blog it.

Monday, April 19, 2010

Born in the West Indies, but for the next 2 weeks I'm a PROUD CANADIAN!

GO CANADA!
http://picasaweb.google.com/trinijessel See my photos from the 2010 Winter Olympics here in Vancouver

Wednesday, February 10, 2010

A Simple(rudimentary) implementation of XPath node search (SelectSingleNode) for OpenEdge 10.2A

- DOES NOT implement Node value filtering (yet)
- Implements Positional referencing/filtering
- DOES NOT implement Attribute searching (yet)
- DOES NOT implement Multiple node result selection like SelectNodes (new function coming)

NOTE: This is a work in progress.

NOTE: You will need to declare the following global variable:
DEFINE VARIABLE recurseXPath AS LOGICAL NO-UNDO.

FUNCTION SelectSingleNode RETURNS LOGICAL (INPUT hXBaseNode AS HANDLE,INPUT xPath AS CHARACTER, OUTPUT hXNode AS HANDLE):
DEFINE VARIABLE hXCurrentNode AS HANDLE.
DEFINE VARIABLE hXChildNode AS HANDLE.
DEFINE VARIABLE childCount AS INTEGER.
DEFINE VARIABLE currentPosition AS INTEGER.
DEFINE VARIABLE startPosition AS INTEGER.
DEFINE VARIABLE endPosition AS INTEGER.
DEFINE VARIABLE iterationDone AS LOGICAL.
DEFINE VARIABLE nodeName AS CHARACTER.
DEFINE VARIABLE pathSegment AS CHARACTER.
DEFINE VARIABLE nodeFilter AS CHARACTER.
DEFINE VARIABLE fqNodeName AS CHARACTER.
DEFINE VARIABLE subPath AS CHARACTER.

CREATE X-NODEREF hXCurrentNode.
CREATE X-NODEREF hXChildNode.

IF (SUBSTRING(xPath, 1, 2) = "//") THEN DO:
recurseXPath = TRUE.
subPath = SUBSTRING(xPath, 3).
hXCurrentNode = hXBaseNode:OWNER-DOCUMENT.
END.
ELSE IF (SUBSTRING(xPath,1,2) = "..") THEN DO:
subPath = SUBSTRING(xPath, 3).
hxBaseNode:GET-PARENT(hXCurrentNode).
END.
ELSE IF (SUBSTRING(xPath,1,2) = "./") THEN DO:
subPath = SUBSTRING(xPath, 3).
hXCurrentNode = hxBaseNode.
END.
ELSE IF (SUBSTRING(xPath, 1, 1) = "/") THEN DO:
subPath = SUBSTRING(xPath, 2).
hXCurrentNode = hxBaseNode.
END.
ELSE DO:
subPath = xPath.
hXCurrentNode = hxBaseNode.
END.

iterationDone = FALSE.
pathSegment = ENTRY(1, subPath, "/").
subPath = SUBSTRING(subPath,LENGTH(pathSegment) + 1).

/* need to validate prefixes used. */
DO ON ERROR UNDO, LEAVE:
fqNodeName = ENTRY(1, pathSegment, "[").
nodeFilter = ENTRY(2, pathSegment, "[").
nodeFilter = SUBSTRING(nodeFilter, 1, LENGTH(nodeFilter) - 1).

CATCH err AS Progress.Lang.SysError:
nodeFilter = "".
fqNodeName = pathSegment.
/* LOG ERROR */
END CATCH.
END.

/* need to validate prefixes used. */
DO ON ERROR UNDO, LEAVE:
nodeName = ENTRY(2, fqNodeName, ":").
CATCH err AS Progress.Lang.SysError:
nodeName = fqNodeName.
/* LOG ERROR */
END CATCH.
END.

DO ON ERROR UNDO, LEAVE:

startPosition = 1.
endPosition = hXCurrentNode:NUM-CHILDREN.

DO currentPosition = startPosition TO endPosition:
hXCurrentNode:GET-CHILD(hXChildNode, currentPosition).
IF (hXChildNode:SUBTYPE = "ELEMENT") THEN DO:
IF (hXChildNode:NAME = fqNodeName) THEN DO:
/* apply filter */
IF (nodeFilter = "" OR (hXChildNode:CHILD-NUM = INTEGER(nodeFilter))) THEN DO:
hXCurrentNode = hXChildNode.
hxNode = hXCurrentNode.
iterationDone = TRUE.
recurseXPath = FALSE.
LEAVE.
END.
END.
IF (recurseXPath = TRUE AND hXChildNode:NUM-CHILDREN > 0) THEN DO:
DEFINE VARIABLE hxFirstChild AS HANDLE.
CREATE X-NODEREF hxFirstChild.
hXChildNode:GET-CHILD(hxFirstChild,1).

IF (hxFirstChild:SUBTYPE = "ELEMENT") THEN DO:
iterationDone = SelectSingleNode(hXChildNode, pathSegment, hxNode).
IF (hxNode:NAME = fqNodeName) THEN DO:
hXCurrentNode = hxNode.
iterationDone = TRUE.
recurseXPath = FALSE.
END.
END.
END.
END.
END.

IF (iterationDone = TRUE) THEN
DO WHILE (ENTRY(2, subPath, "/") <> ""):
RETURN SelectSingleNode(hXCurrentNode, subPath, hxNode).
END.

RETURN iterationDone.

CATCH err AS PROGRESS.Lang.SysError:
RETURN iterationDone.
END CATCH.
END.
RETURN iterationDone.
END FUNCTION.
A simple pair of Get and Set Inner Text functions for OpenEdge Xml:

FUNCTION SetInnerText RETURNS CHARACTER (INPUT hxDoc AS HANDLE, INPUT-OUTPUT hXBaseNode AS HANDLE, INPUT nodeValue AS CHARACTER):
DEFINE VARIABLE hxTextNode AS HANDLE NO-UNDO.
CREATE X-NODEREF hxTextNode.

DO ON ERROR UNDO, LEAVE:
IF(hxBaseNode:NUM-CHILDREN > 0) THEN DO:
hxBaseNode:GET-CHILD(hxTextNode, 1).
IF (hxTextNode:SUBTYPE = "TEXT") THEN DO:
hxTextNode:NODE-VALUE = nodeValue.
RETURN hxTextNode:NODE-VALUE.
END.
ELSE
RETURN "".
END.
ELSE DO:
hxDoc:CREATE-NODE(hxTextNode, "", "TEXT").
hxTextNode:NODE-VALUE = nodeValue.
hXBaseNode:APPEND-CHILD(hxTextNode).
RETURN hxTextNode:NODE-VALUE.
END.
CATCH err AS PROGRESS.Lang.SysError:
RETURN "".
END CATCH.
END.
END FUNCTION.

FUNCTION GetInnerText RETURNS CHARACTER (INPUT hXBaseNode AS HANDLE):
DEFINE VARIABLE hxTextNode AS HANDLE NO-UNDO.
CREATE X-NODEREF hxTextNode.

DO ON ERROR UNDO, LEAVE:
hxBaseNode:GET-CHILD(hxTextNode, 1).
IF (hxTextNode:SUBTYPE = "TEXT") THEN DO:
RETURN hxTextNode:NODE-VALUE.
END.
ELSE
RETURN "".
CATCH err AS PROGRESS.Lang.SysError:
RETURN "".
END CATCH.
END.
END FUNCTION.
SOAP Sniffing in OpenEdge 10.2.A

From the OpenEdge development environment prompt run the following:

proenv>prosoapview PORTNUM

E.G.

proenv>prosoapview 4444

Thursday, February 04, 2010

Creating a SOAP header with AuthHead tags in Progress OpenEdge 10.2.A


DEFINE VARIABLE hWebService AS HANDLE NO-UNDO.
DEFINE VARIABLE hPortType AS HANDLE NO-UNDO.



PROCEDURE CreateMessageAuthHeader :
    DEFINE OUTPUT PARAMETER hSOAPHeader AS HANDLE .
    DEFINE INPUT PARAMETER cOperationNamespace AS CHARACTER .
    DEFINE INPUT PARAMETER cOperationLocalName AS CHARACTER .
    DEFINE OUTPUT PARAMETER lDeleteOnDone AS LOGICAL .

    DEFINE VARIABLE hTmpSoapHeader AS HANDLE NO-UNDO.
    DEFINE VARIABLE hSoapHeaderRef AS HANDLE NO-UNDO.
    DEFINE VARIABLE hNodeAuthHead AS HANDLE NO-UNDO.
  
    CREATE SOAP-HEADER hTmpSoapHeader.
    CREATE SOAP-HEADER-ENTRYREF hSoapHeaderRef.

    CREATE X-DOCUMENT hXDocAuthHeader.
    CREATE X-NODEREF hNodeAuthHead.

    hTmpSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderRef).

    hXDocAuthHeader:CREATE-NODE-NAMESPACE(hNodeAuthHead, cNsUri, cNsPrefix + ":" + "AuthHeader", "ELEMENT").
    AddMessageElement(hNodeAuthHead, hXDocAuthHeader, "username", "username", cNsUri, cNsPrefix).
    AddMessageElement(hNodeAuthHead, hXDocAuthHeader, "password", "password", cNsUri, cNsPrefix).

    hSoapHeaderRef:SET-NODE(hNodeAuthHead).
    hSoapHeader = hTmpSoapHeader.

    lDeleteOnDone = TRUE.

END PROCEDURE .


FUNCTION ConnectWebService RETURNS INT ().
        /*Connect to Webservice*/
        CREATE SERVER hWebService.
                                
        /* replace connection string with config val */
        hWebService:CONNECT("-WSDL 'http://www.someservicesite.com/webservice.asmx?wsdl'").
        RUN PortType SET hPortType ON hWebService.

        /* Set up webservice call/callback */
        hPortType:SET-CALLBACK-PROCEDURE("REQUEST-HEADER", "CreateMessageAuthHeader").
END FUNCTION.


/***********************Web Methods*********************************/

FUNCTION GetStatus RETURNS INT
  (INPUT IdNumber AS CHARACTER)
  IN hPortType.

/***********************Business Methods*********************************/
FUNCTION GetMyStatus RETURNS INT (INPUT IdNumber  AS CHARACTER).
    ConnectWebService().
    statusResult = GetStatus(IdNumber).
END FUNCTION.

Using OpenEdge 10.2.A from Progress to consume a webservice:

When passing an EXTENT LONGCHAR containing an array of XML messages as a parameter to a web method, the xml message(s) are being partially HTML-ENCODED. Which the receiving web method does not appreciate in the slightest.

When I say the XML is being partially HTML-ENCODED, I mean that the '<' and '"'s are being replaced with '<' and '"' respectively. The '>'s are not being replaced. I have no access to the code block where the web call is being made and the encoding occurs as the WSDL is downloaded by Progress OpenEdge on each call. The WSDL is processed and the methods + signatures determined dynamically.

The Schema used defined a custom element type of "anyType". This was the source of the problem. Progress would not interpret the usage/implementation of this node correctly - where the anyType node was meant to be replaced by any other element in the schema defined as type anyType.

Taking the WSDL and manually modifying the schema portion of it to build the message without the anyType did the trick. The encoding also ceased.

Thursday, January 21, 2010

To have your Satellite Forms project produce an '.exe', you must have an icon file in the '\Images' directory of your project.

Note: The icon file must have the same name as your project (.sfa file), but the project may have a different application name. The application name will be the name of your '.exe' with the icon from the '\Images' directory

Monday, June 04, 2007

The amount of help you can find on the web about binding a datasource to a datagrid is astounding. Once you bound your datagrid and populated it, the user of course wants to see it.

They may optionally want to update, delete or insert data into your nicely bound datagridview.

All of the above is well documented on the web and easy to pull off. So now what?

Let's suppose you want to "Do" something with the data, say.... save it back to a source?

Well if you were using an unbound datasource and populated it on the fly, AND thought you could persist some data in hidden columns, you are sadly mistaken.

The data in hidden columns is never bound on the databind(). That’s right, a predefined column with the datafield attribute set and the visible attribute set false will not bind to the datasource datafield.

The trick is to define all columns of data you wish to persist to visible columns and then after you call the databind(), hide the columns you don't want to show the user. The data will now persist.

CAUTION! If you rebind (update the datagrid datasource) after you've hidden the columns, the data will be lost again. You must first make the columns visible again, then rebind the datagrid and then you may hide the columns once more.

Tuesday, April 03, 2007

Speeding up Vista with ReadyBoost USB RAM drive

I personally am not running any Vista PCs or notebooks (don't have the hardware base). But if anyone is experiencing the Vista hardware drain, Alec Saunders has blogged a bit on his experience with ReadyBoost included with Microsoft Windows Vista.

I'd love to know if anyone else has had positive results with it.

Speeing up Windows Vista http://saunderslog.com/2007/04/02/speeding-up-windows-vista/

Thursday, March 29, 2007

InfoPath goes to XML Schemaville

OK, in XML schemaville, when you define an element (<xsd:element></xsd:element>) you define the the type of element it is and what type of children it will contain (text or other xml elements) if you want it to do both (contain text nodes and element nodes) you have to explicitly define it like that typically you define element nodes that contain child element nodes to not contain text nodes as well.

In InfoPath, elements that contain other child elements are called "groups". The IP schema tool does support defining mixed content nodes. So, since your target node is a "group" it is not allowed to contain text. You must either change it to an element (remove group & re-add element by same name) or do not write to it (add a child element to it to write to) .

Thursday, March 15, 2007

Generate Xpath Statement

Ever want to work out what the Xpath statement would be for a current node of an XML document? Well here you go. This little tid bit will quickly work its way back up the parent-grandparent tree, up to the root node of the document. And when it's done, you'll be returned the Xpath statement.

Code: (generated for InfoPath C# managed code)

private string GenerateMatchPath(IXMLDOMNode sourceNode, string xPath)
{
IXMLDOMNode parentNode = sourceNode.parentNode;
while (parentNode != null && parentNode.nodeName != "#document")
{
xPath = parentNode.nodeName + "/" + xPath;
parentNode = parentNode.parentNode; } return "/" + xPath;
}//GenerateMatchPath

Now, why would this be useful?

Suppose you would like to compare the data of a pair of XML documents (docA and docB).

If you used an Xpath query (xmlDoc.selectNodes("//descendant-or-self::node()")) to generate a nodelist of all elements in docA, you could:
  • loop through each node from docA
  • get its value
  • generate the xpath
  • use the xpath to get the value from docB
  • compare values
  • take appropriate action (update docA? update docC?)

[Snippet to follow...]

Tuesday, March 13, 2007

Clearing Windows network passwords.

I have recently found problems with my Visual Source Safe 2005 (VSS) solution bindings breaking in Visual Studio .NET 2005 (VS2005). On two occassions in the last week I have encountered "Invalid Handle" errors when trying to check-in my solutions.

The invalid handle error is due to the VSS bindings. The solution has been to restablish the bindings, however, this was hampered by the root problem ;) Somehow a bad password was saved, and the connection to the VSS server could not be established. So, the corrupt credentials must be removed.

To do this, I found James Geurts' Blog on 'Clear saved windows networking passwords' where he supplies the following:

Start>Run>rundll32.exe keymgr.dll, KRShowKeyMgr

The same dialog can be opened via:

Start>Control Panel>User Accounts>Advanced Tab>Manage Passwords

I prefer the latter option as it is easier to remember and find again ;)

(James Geurts' Blog http://biasecurities.com/blogs/jim/archive/2005/12/20/3876.aspx)

Saturday, October 21, 2006

Missing nodes from a webservice.

InfoPath is very particular about the type of document it processes - this due to its very stringent implementation of XSD Schemas. InfoPath will complain immediately if it encounters nodes that do not fit the schema design (nodes not defined in schema, nodes out of position, multiple nodes where not defined as repeating)

If a node is missing from the instance document and the schema dictates the optional presence of this node, InfoPath will accept the document as valid. However, if there are any controls being bound to the missing field, InfoPath will disable the field in the UI, as nothing can be written to a missing node.

This became painfully apparent in our early iterations of our InfoPath form. We noticed several fields being locked out in the form only to discover the fields were missing from the XML documents returned by our Webservice. We tracked this down to the Enterprise Library's Database Datatable to XML conversion.

Any null values in a recordset are not converted to empty fields in the resulting XML, but rather they are just omitted. Our solution was to use the schema to build ourselves an empty instance document and populate it with the data from the recordset. This way we are guaranteed to get all required nodes returned from a webservice

Since a schema document is simply another XML document, parse the XSD document and programmatically build the instance document starting from the root node element definition.. TBC