Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Newbie: TCHAR to BSTR conversion

875 views
Skip to first unread message

Paul

unread,
Nov 2, 2005, 5:24:55 PM11/2/05
to
I need to run a vbs file from the current program directory, everything was
going fine until I had to create a BSTR variable. It's a
pandora's box, and for someone new to C it is mind blowing (at least my mind
anyway). I am not using MFC or ATL. I really have tried to understand the
differences between the types of strings but

#include "stdafx.h"
#import "c:\windows\system32\wshom.ocx" no_namespace
rename("FreeSpace","FSpace") rename("Unknown", "Unk")

#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <atlbase.h>

int main(int argc, char* argv[])
{
USES_CONVERSION;
CoInitialize(NULL);
IWshShell2Ptr myWsh (__uuidof(IWshShell_Class));

BSTR bstrCommand;
VARIANT vtWindowStyle, vtWaitOnReturn;
VariantInit(&vtWindowStyle);
VariantInit(&vtWaitOnReturn);

vtWindowStyle.vt = VT_I2;
vtWindowStyle.iVal = 1;

TCHAR buffer[MAX_PATH];

::GetModuleFileName(NULL,buffer,sizeof(buffer));

if (buffer!=NULL)
printf ("Current path is: %s",buffer);

// Strip off the EXE's file name...
LPTSTR pEnd = _tcsrchr( buffer, L'\\' );

//...and replace it with the name of the file
lstrcpy( pEnd + 1, "test.vbs" );

// Convert from TCHAR to BSTR for COM
bstrCommand = SysAllocString(T2OLE(buffer));

HRESULT hr = myWsh->Run(bstrCommand, &vtWindowStyle, &vtWaitOnReturn);


SysFreeString(bstrCommand);
myWsh = NULL;
CoUninitialize();
return 1;

}
It compiles but the program crashes on the myWsh->Run statement. The script
file itself merely pops up a Hello World message and runs fine from windows
explorer.

Any help would be really appreciated.
Thanks

mfur...@gmail.com

unread,
Nov 2, 2005, 6:41:51 PM11/2/05
to
The easiest way to convert between the two is to use a _bstr_t:

TCHAR buffer[MAX_PATH];
....
_bstr_t bstrResult = _bstr_t(buffer);

I couldn't import wshom.ocx, but this code below accomplishes the task
you're trying to do. You can get the MSScript control here:

http://www.microsoft.com/downloads/details.aspx?FamilyId=D7E31492-2595-49E6-8C02-1426FEC693AC&displaylang=en

Source:

#include "StdAfx.h"

#import "C:\Program Files\Microsoft Windows Script\Windows Script
Control\msscript.ocx" rename_namespace("VBS")

#include <tchar.h>
#include <atlbase.h>
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

string getFile(const string &filename)
{
string strContents;

ifstream file(filename.c_str(), ios::in);

while (file && file.peek() != char_traits<char>::eof())
strContents.append(1, file.get());

file.close();

return strContents;
}

string itos(int i, unsigned int base = 10)
{
char buffer[20];
string strResult = "";
strResult = _itoa(i, buffer, base);

return strResult;
}

string bstos(_bstr_t bstrSource)
//Convert a bstr to a string
{
string Result = "";
if ((BSTR) bstrSource != NULL)
Result = bstrSource;
return Result;


}
int main(int argc, char* argv[])
{

CoInitialize(NULL);

VBS::IScriptControlPtr pScript(__uuidof(VBS::ScriptControl));

try
{
pScript->Language = "VBScript";

TCHAR buffer[MAX_PATH];

::GetModuleFileName(NULL,buffer,sizeof(buffer));

if (buffer!=NULL)
printf ("Current path is: %s",buffer);

// Strip off the EXE's file name...
LPTSTR pEnd = _tcsrchr( buffer, L'\\' );

//...and replace it with the name of the file
lstrcpy( pEnd + 1, "test.vbs" );

string strContents = getFile(buffer);

pScript->ExecuteStatement(strContents.c_str());

}
catch (...)
{
VBS::IScriptErrorPtr pError = pScript->Error;

string strError;
strError += "Description: " + bstos(pError->Description) + "\n";
strError += "Text: " + bstos(pError->Text) + "\n";
strError += "Source: " + bstos(pError->Source) + "\n";
strError += "Number: " + itos(pError->Number) + "\n";
strError += "Line: " + itos(pError->Line) + "\n";
strError += "Column: " + itos(pError->Column) + "\n";

cout << strError;
}

CoUninitialize();

return 1;

}


Best of luck,

Matt Furnari

Paul

unread,
Nov 2, 2005, 7:20:18 PM11/2/05
to
Thank you very much, there is still a problem though, the script executes
and when it is finished, the c++ program dies a horrible death with "... the
memory could not be read"
This happens regardless of the actual script that gets run. To make sure I
commented all the script code and ran it.


Paul

unread,
Nov 2, 2005, 7:37:14 PM11/2/05
to
The failure occurs on
return 1;

in main()

"Paul" <pauln.o...@laberg.com.au> wrote in message
news:uvk2jxA4...@TK2MSFTNGP12.phx.gbl...

Brian Muth

unread,
Nov 2, 2005, 8:53:01 PM11/2/05
to
The scope of smart pointers such as _bstr_t must not encompass the
CoUninitialize().

Confine the sope using braces, as in:

CoInitialize()
{
_bstr_t ...
}
CoUninitialize()

Brian


Paul

unread,
Nov 2, 2005, 9:15:54 PM11/2/05
to
I am very impressed, you guys are amazing

"Brian Muth" <bm...@mvps.org> wrote in message
news:u5oBUlB...@TK2MSFTNGP09.phx.gbl...

0 new messages