I am trying to use QTP/UFT's DotNetFactory utility in standalone vbs files. I believe UFT is using DotNetFactory.dll found in the C:\Program Files (x86)\HP\Unified Functional Testing\bin to implement the feature. I have checked and found that the DLL is registered and its ComVisible property is also set to True. So effectively, I should be able to CreateObject to create an instance. However, VBScript (32-bit or 64-bit) is not able to create or get object for this dll.
None of the following is working
Set objDotNet = GetObject("C:\Program Files (x86)\HP\Unified Functional Testing\bin\DotNetFactory.dll")
Set objDotNet = GetObject(,"Mercury.DotNetFactory.1")
Set objDotNet = CreateObject("Mercury.QTP.Utils.DotNetFactory")
Set objDotNet = CreateObject("Mercury.DotNetFactory.1")
Related
I use the following command to launch a JS script: C:\Windows\System32\cscript.exe /nologo //E:{16d51579-a30b-4c8b-a276-0ff4dc41e755} in order to use the latest Chakra engine.
In my script, the command WScript.Echo( ScriptEngineMajorVersion() + "." + ScriptEngineMinorVersion() + "." + ScriptEngineBuildVersion()); outputs 11.0.19326.
I know this increases performance, and I thought I'd be also able to use the latest XMLHttpRequest instead of the good old Microsoft.XMLHTTP (I need responseURL) but it looks like I am not.
Is there a solution?
My guess is, the way you're loading the Chakra engine it's loading an invisible IE instance. But according to this MDN compatibility table there is no version of Internet Explorer that supports responseURL.
edit: don't use JScript
Through much testing, attempting to load Edge's Chakra engine into Windows Script Host, I can land on no permutation that works. Creating an htmlfile COM object and forcing compatibility using x-ua-compatible, attempting the same with an HTA application (both natively and again with an htmlfile COM object), attempting to create a MSXML2.ServerXMLHTTP.6.0 object, no Windows Script Host hack I can conceive will expose the .responseURL property of an XMLHttpRequest object.
Best bet would be to pick a different language. In PowerShell you could do something like this:
$req = [Net.WebRequest]::Create("https://youtu.be/")
$resp = $req.GetResponse()
$resp.ResponseURI.AbsoluteURI
... which would print
https://www.youtube.com/?feature=youtu.be
And if you need the equivalent of .responseText, just add the following:
$reader = new-object System.IO.StreamReader $resp.GetResponseStream()
$responseText = $reader.ReadToEnd()
If you want to parse $responseText using DOM methods...
$htmlfile = new-object -COM htmlfile
$htmlfile.IHTMLDocument2_writeln($responseText)
$buttons = $htmlfile.getElementsByTagName("button")
You can see the original revision of this answer for an example of what doesn't work.
In a VB.NET application I need to set a button to start a program - specifically, Steam. But I need to allow for the user having installed the program somewhere other than the default location "C:\Program Files (x86)\Steam". So all I know is the executable name: "steam.exe".
In searching for an answer it looks like I should be able to get the path using Microsoft.Win32.Registry somehow, but the examples I'm seeing aren't helping me (I guess I'm just not getting how to apply those examples to my situation).
This tutorial gives the example of finding the path to the excel executable:
Dim regKey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\MICROSOFT\Windows\CurrentVersion\AppPaths\excel.exe")
Dim path As String = regKey.GetValue("Path").ToString
But I'm getting a value of "Nothing" for regKey. Not only that, even if it did get a value for regKey, how would I know the registry path for another program (Steam, in my case)?
And how much will the version of Windows change the possible registry location of a program - if at all?
I have following problem. I would like to use jsShell.dll (Link to dll and description) in my project. I use Win7 64 bit.
I downloaded dll and put it in C:\Windows\system\jsshell (files jsShell.dll and khook.dll)
I succesfully registered dll using c:\Windows\SysWOW64> regsvr32.exe c:\Windows\system\jsshell\jsShell.dll (it is not needed to register khook.dll)
Then I tried to run test file jsshell\jsShell DLL\demo scripts\window.vbs which is part of jsShell.zip by:
a) double click to window.vbs and getting following error:
SCRIPT: C:\Users\joe\Downloads\jsshell\jsShell DLL\demoscripts\windows.vbs
LINE: 6
CHAR: 3
ERROR: ActiveX component can't create object: 'jsShell.Ops'
CODE: 800A01AD
SOURCE: Microsoft VBScript runtime error
This is the line with error: Set jsS = CreateObject("jsShell.Ops")
b) loading in WEB-ED Editor (Link to WEB-EDD) and running script over via editor, which works perfectly.
Could somebody please explain me, where is the difference between (a) and (b)? And what have to be done in order to run my script using (a) variant?
Thx a lot
I need to get the path (not the executable) where my application is running from:
System.AppDomain.CurrentDomain.BaseDirectory()
When I run the above statement with & "/images/image.jpg" on my local machine it works fine but when I install the application on another machine it says it cannot find the file and there is a lot of extra path information some.
I just need the directory of where the app is running. I am coding in VB.NET with Visual Studio 2008.
Thanks!
This is the first post on google so I thought I'd post different ways that are available and how they compare. Unfortunately I can't figure out how to create a table here, so it's an image. The code for each is below the image using fully qualified names.
My.Application.Info.DirectoryPath
Environment.CurrentDirectory
System.Windows.Forms.Application.StartupPath
AppDomain.CurrentDomain.BaseDirectory
System.Reflection.Assembly.GetExecutingAssembly.Location
System.Reflection.Assembly.GetExecutingAssembly.CodeBase
New System.UriBuilder(System.Reflection.Assembly.GetExecutingAssembly.CodeBase)
Path.GetDirectoryName(Uri.UnescapeDataString((New System.UriBuilder(System.Reflection.Assembly.GetExecutingAssembly.CodeBase).Path)))
Uri.UnescapeDataString((New System.UriBuilder(System.Reflection.Assembly.GetExecutingAssembly.CodeBase).Path))
---
Edit October 18, 2021:
Sigh... None of the above work if using net5.0 or net6.0 and publishing app as single-file bundle. Best I got now is:
// This will give you the directory but not the assembly
string basedir = AppContext.BaseDirectory;
// Before you package the app as a single file bundle, you will get the dll.
// But after you publish it, you'll get the exe.
string pathToExecutable = Environment.GetCommandLineArgs()[0].Replace(".dll", ".exe");
Dim strPath As String = System.IO.Path.GetDirectoryName( _
System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
Taken from HOW TO: Determine the Executing Application's Path (MSDN)
I needed to know this and came here, before I remembered the Environment class.
In case anyone else had this issue, just use this: Environment.CurrentDirectory.
Example:
Dim dataDirectory As String = String.Format("{0}\Data\", Environment.CurrentDirectory)
When run from Visual Studio in debug mode yeilds:
C:\Development\solution folder\application folder\bin\debug
This is the exact behaviour I needed, and its simple and straightforward enough.
Dim P As String = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
P = New Uri(P).LocalPath
You could use the static StartupPath property of the Application class.
You can write the following:
Path.Combine(Path.GetParentDirectory(GetType(MyClass).Assembly.Location), "Images\image.jpg")
Is there a way to read the properties inside an MSI file?
For example, given a MSI file named Testpackage.msi, I need to find
productName
PackageCode
version
This I am going to use it with WMI uninstall
string objPath = string.Format("Win32_Product.IdentifyingNumber='{0}', Name='{1}', Version='{2}'", "{AC9C1263-2BA8-4863-BE18-01232375CE42}", "testproduct", "10.0.0.0");
Using Orca is a great option, if this can be achieved programmatically. Then I can use this to generate automatic release notes. And in un-installing program too.
You can use the COM-based API for working with MSI, and do something like
Function GetVersion(ByVal msiName)
Const msiOpenDatabaseModeReadOnly = 0
Dim msi, db, view
Set msi = CreateObject("WindowsInstaller.Installer")
Set db = msi.OpenDataBase(msiName, msiOpenDatabaseModeReadOnly)
Set view = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'")
Call view.Execute()
GetVersion = view.Fetch().StringData(1)
End Function
WiX toolset: WiX quick-start tips (collection of links to resources). WiX installs DTF.
I just want to mention that things have gotten even easier now. There is a full .NET wrapper for the Windows Installer object model, so you can avoid any COM interop clunkiness.
DTF - Getting Started: Main file: Microsoft.Deployment.WindowsInstaller.dll
Download and install the WiX toolkit
Find the files below in the WixInstallPath\SDK directory
The wrapper is called "Deployment Tools Foundation" (DTF) and here is the basic description: "Deployment Tools Foundation is a rich set of .NET class libraries and related resources that together bring the Windows deployment platform technologies into the .NET world. It is designed to greatly simplify deployment-related development tasks while still exposing the complete functionality of the underlying technology".
Here is a stripped-down, hands-on sample:
using (var db = new Database(FullPath, DatabaseOpenMode.ReadOnly))
{
PackageCode = db.SummaryInfo.RevisionNumber;
AppVendor = db.SummaryInfo.Author;
AppName = db.SummaryInfo.Title;
ProductName = db.SummaryInfo.Subject;
ProductCode = (string)db.ExecuteScalar("SELECT `Value` FROM "+
"`Property` WHERE `Property` = 'ProductCode'");
AppVersion = (string)db.ExecuteScalar("SELECT `Value` FROM "+
"`Property` WHERE `Property` = 'ProductVersion'");
UpgradeCode = (string)db.ExecuteScalar("SELECT `Value` FROM "+
" `Property` WHERE `Property` = 'UpgradeCode'");
}
Primary DTF files (the latter two are the most used ones):
Microsoft.Deployment.Compression.dll - Framework for archive packing and unpacking.
Microsoft.Deployment.Compression.Cab.dll - Implements cabinet archive packing and unpacking.
Microsoft.Deployment.Resources.dll - Classes for reading and writing resource data in executable files.
Microsoft.Deployment.WindowsInstaller.dll - Complete .NET based class library for the Windows Installer APIs.
Microsoft.Deployment.WindowsInstaller.Package.dll - Extended classes for working with Windows Installer installation and patch packages.
Just create a C# project, reference these files, and code your own deployment application with whatever control you desire and need. I am not set up with the tools for DTF at the moment, but see this sample for a general idea of how a C# program would work.
DTF is included with WIX. Download WiX from here.
The DTF dlls are in the SDK folder in the main WiX installation folder (the default location is: %ProgramFiles(x86)%\WiX Toolset v3.10\SDK). The version number will probably be different by the time you see this. Just look for the WiX folder under %ProgramFiles(x86)%.
Look for the DTF help files in the "doc" folder. DTF.chm and DTFAPI.chm. Absolutely excellent documentation for the object model and its usage.
See this serverfault.com post for some more DTF details
Some starter suggestions for working with WiX
You can use Microsoft's Orca.exe. Orca will allow you to open the MSI and edit/view all the tables in it. You will have to download the entire Windows SDK in order to get it, but thankfully that is free.
One alternative (which might be faster due to the download size of the SDK) is to use dark.exe from the WiX project. Dark is a MSI decompiler, which will export everything into an XML file and collection of resources. The XML it outputs will have the information you are looking for.
Here's a similar example in VBScript which I use as part of my build process in creating bootstrapper executables...
Option Explicit
Const MY_MSI = "product.msi"
Dim installer, database, view, result, sumInfo, sPackageCode
Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase (MY_MSI, 0)
Set sumInfo = installer.SummaryInformation(MY_MSI, 0)
sPackageCode = sumInfo.Property(9) ' PID_REVNUMBER = 9, contains the package code.
WScript.Echo "ProductVersion=" & getproperty("ProductVersion")
WScript.Echo "ProductCode=" & getproperty("ProductCode")
WScript.Echo "PackageCode=" & sPackageCode
WScript.Echo "ProductName=" & getproperty("ProductName")
Function getproperty(property)
Set view = database.OpenView ("SELECT Value FROM Property WHERE Property='" & property & "'")
view.Execute
Set result = view.Fetch
getproperty = result.StringData(1)
End Function
I found a lightweight non-programmatic solution in lessmsi. It apparently uses wix and just explodes the whole .msi into a specified folder. (It also has a UI but it didn't render great for me on Win7).