A Day in the Life

A day in my life. Thoughts on leadership, management, startups, technology, software, concurrent development, etc... Basically the stuff I think about from 10am to 6pm.

6/17/2007

One door closing...

Update...this post was taken down because...well there were unintended interpretations to what I wrote. This may go back up later after a little more editing.

Well, the toned down version of this post is that I find that for personal reasons I had to leave Digipede. I loved working there. Great team, great product but things don't always work out the way we want them to. So…a door closing.

6/04/2007

We all need a little help from our friends...

All right all you developers out there...you have GOT to start blogging because I am really tired of running into error messages and situations that I KNOW someone has gotten around but no one has bothered to share the solution for. Now I know for a fact that my blog is not in the top 10000 of blogs that are widely read, but I can tell you from my traffic that my blog does help folks. You can help folks too. Be altruistic and give back to the community, there is so much software left to build that there is no reason to hoard information.

As I was searching Google for the answer to the error message below I saw the same error message pop-up in Groups and on the Web but with no solution ever presented. This is not the first time I've encountered this problem, it won't be the last, but maybe we can change this...one post at a time. Okay, that was my call to arms. Now onto the error message and the solution.

--------------------------

I don't know if my solution will work for you, but here is my situation and the accompanying solution.

I'm trying to open a password protected Excel workbook from a VBScript file. The problem I ran into is that there are "empty parameters" between the filename and the password for the Workbooks.Open call; in C# those empty parameters are filled with the word 'missing', but what to do about VBS?

Here is the error message generated with all my attempts to make the call:

"Unable to get the Open property of the Workbooks class."

Here is the correct syntax:

Set oWorkBook = myExcelWorker.Workbooks.Open
(strWorkerWB, , , , "password")

Where strWorkerWB is a variable containing the name of my Excel workbook, "password" is the Password to open for the workbook, and the command is typed into your script on one line (While the line is split in this post, don't split it in your code).

6/01/2007

Fun with vbc.exe...snore

I created a .NET 1.1 and a .NET 2.0 VB.NET sample for the Digipede Network. One of the requirements for our sample code is that the samples can be built from the command-line. The first thing I had to do for this test was to make sure that I had an open Command Prompt window with the PATH correctly containing only .NET 1.1 and VS2003 references.

Then it was time to start building my batch file. Since my sample is based on a C# sample I started by copying the build.bat file from the C# sample, thinking that that would work just fine after I changed a few things. Boy was I wrong.

.NET 1.1/VS2003

My VB.NET project builds fine when built inside VS2003. This is what my batch file started out looking like:

copy ..\..\Digipede.Framework.dll 
copy ..\..\Microsoft.Web.Services2.dll

cd MonteCarloLibrary
vbc.exe /t:library /out:MonteCarloLibrary.dll
/r:..\Digipede.Framework.dll piworker.vb

cd ..
copy MonteCarloLibrary\MonteCarloLibrary.dll

vbc.exe /t:winexe /out:MonteCarloPi.exe
/r:Digipede.Framework.dll /r:MonteCarloLibrary.dll
MainForm.vb

This didn't work and generated a plethora of bugs.

The build command for the MonteCarloLibrary changed to look like this:

vbc.exe /t:library /out:MonteCarloLibrary.dll 
/r:..\Digipede.Framework.dll /r:Microsoft.VisualBasic.dll
/r:System.Data.dll piworker.vb

Apparently the IDE automatically includes the Microsoft.VisualBasic.dll and System.Data.dll files for you and when compiling on the command-line you have to reference them yourself. Additionally, I had to make changes to my code so that my Imports list contained everything I would need. That list changed from:

Imports Digipede.Framework
Imports Digipede.Framework.Api

to:

Imports System
Imports System.Data
Imports System.XML
Imports System.Runtime.Serialization
Imports Digipede.Framework
Imports Digipede.Framework.Api

These changes got me around most of the BC30002 errors.

The next thing that was a problem was that in my executable I referenced my DLL as MonteCarloLibrary.MonteCarloLibrary.PiWorker. This compiled just fine in the IDE but not from the command-line. When compiling from the command-line I got the following error:

MainForm.vb(468) : error BC30002: Type 
'MonteCarloLibrary.MonteCarloLibrary.PiWorker' is not defined.
Dim jobTemplate As JobTemplate = JobTemplate.NewWorkerJobTemplate
(GetType(MonteCarloLibrary.MonteCarloLibrary.PiWorker))

This puzzled me for awhile until I changed my code to be:

Dim jobTemplate As JobTemplate = JobTemplate.NewWorkerJobTemplate
(GetType(MonteCarloLibrary.PiWorker))

Notice I deleted the Namespace 'MonteCarloLibrary'. This change compiled just fine from the command-line but not from the IDE. What was going on?

It seems that in the IDE my MonteCarloLibrary had a Root namespace defined in the project. Now I don't remember ever setting this so I don't know if I put it in or the IDE put it in, regardless...there it was. And that, so to say, was the root of my problem.



I deleted the Root namespace. Changed my code to remove the namespace reference and was then around that problem.

Onward...though not upward.... As you can see I've switched over to errors reported by my executable WorkerLibraryFormsVB.exe

vbc : error BC30420: 'Sub Main' was not 
found in 'WorkerLibraryFormsVB'.

A quick Google search yielded no valid answer so I decided to bite the bullet and actually look at the VB.NET compiler settings by typing:

vbc /?

This looked good:
/main:
option is defined as

Specifies the Class or Module that contains Sub Main. It can also be a Class that inherits from System.Windows.Forms.Form. (Short form: /m)

New command-line:

vbc /t:winexe /main:MonteCarloForm 
/out:WorkerLibraryFormsVB.exe /r:Digipede.Framework.dll
/r:MonteCarloLibrary.dll MainForm.vb

Which got past the ‘Sub Main’ error but there were still more....

vbc: error BC30451: Name 'MessageBox' is not declared.

To get around the problem above you'll need to do two things. The first thing to do is to verify that you have

Imports System.Windows.Forms

at the top of your file. (In this case I added the Imports command to the top of MainForm.vb)

The second thing is to add additional references to your build command-line:

vbc /t:winexe /main:MonteCarloForm /out:MonteCarloPi.exe 
/r:Digipede.Framework.dll /r:MonteCarloLibrary.dll
/r:System.Windows.Forms.dll /r:Microsoft.VisualBasic.dll
/r:System.Data.dll MainForm.vb

I had one error left and that was:

\MainForm.vb(534) : error BC30451: Name 'ControlChars' 
is not declared.

Dim errMsg As String = [String].Format("Job submission
failed with error:" + ControlChars.Lf + "{0}",
e.Error.Message)

I changed the line to read:

Dim errMsg As String = [String].Format
("Job submission failed with error:" +
Microsoft.VisualBasic.ControlChars.Lf + "{0}",
e.Error.Message)

Notice I told the compiler EXACTLY where to find ControlChars....and then everything was just fine.

Here is the new, working build.bat file:

copy ..\..\Digipede.Framework.dll 
copy ..\..\Microsoft.Web.Services2.dll

cd MonteCarloLibrary
vbc.exe /t:library /out:MonteCarloLibrary.dll
/r:..\Digipede.Framework.dll /r:Microsoft.VisualBasic.dll
/r:System.Data.dll piworker.vb

cd ..
copy MonteCarloLibrary\MonteCarloLibrary.dll

vbc.exe /t:winexe /out:WorkerLibraryFormsVB.exe
/r:Digipede.Framework.dll /r:MonteCarloLibrary.dll
/r:Microsoft.VisualBasic.dll /r:System.Data.dll
/r:Mscorlib.dll /r:System.dll
/r:System.Windows.Forms.dll /r:System.Drawing.dll
/main:MonteCarloForm MainForm.vb

.NET 2.0/VS2005

Once testing indicated that I had the .NET 1.1/VS2003 version working I then copied my new build.bat file over to the .NET 2.0/VS2005 project. I made the necessary code changes with my Imports and namespace, and then tried to build. I got the following warning:

warning BC42025: Access of shared member, 
constant member, enum member or nested type through
an instance; qualifying expression will not be evaluated.

Dim jobTemplate As JobTemplate = jobTemplate.NewWorkerJobTemplate
(GetType(MonteCarloLibrary.PiWorker))

Although not an error, only a warning, I don’t like to see either in my output and it needed to go. This is what my code looked like to me in VS2003:

Dim jobTemplate As JobTemplate = 
JobTemplate.NewWorkerJobTemplate(GetType(
MonteCarloLibrary.PiWorker))

Notice that in the error message it is jobTemplate.NewWorkerJobTemplate and in my code it is JobTemplate.NewWorkerJobTemplate. Damned if VB wasn’t making my capital J a lowercase j. It was actually funny (for all of 30 seconds) to change the lower case j to an upper case J and watching the IDE change it back for me. It was like a magic trick; only after the first few laughs it wasn't funny any more. Quite frankly I have better things to do than waste my time on this kind of crap. A quick look through the VS2005 Options pages and nothing jumped out to make this stop. So I changed my variable name to myJobTemplate.

Conclusion
One thing that would have been really handy is if the IDE would have displayed the command-line it was using. This option is available for other languages why not VB.NET?