Trying to display a file properties dialog programmatically in Windows 10, I first tried specifying the "properties" verb in a call to ShellExecute from VBScript. This produced a baffling warning:
Qt: Untested Windows version 10.0 detected!
I haven't installed Qt on this machine, and this is produced from somewhere in the innards of the Windows script support and/or even the API level, where evidently there is a Qt hook installed.
Next, I tried another angle, using the Shell scripting object to invoke the "properties" verb. No ShellExecute here. But same result, except that now it also happens (not entirely reproducable) that I get this error box:
Code:
option explicit
dim fs: set fs = CreateObject("Scripting.FileSystemObject")
sub writeline( s )
WScript.StdOut.WriteLine s
end sub
dim fArg: fArg = WScript.Arguments.Item( 0 )
dim itemPath: itemPath = fs.GetAbsolutePathName( fArg )
dim itemFolderPath: itemfolderpath = fs.GetParentFolderName( itemPath )
dim itemName: itemName = fs.GetFileName( itemPath )
writeline itemPath
writeline itemFolderPath
writeline itemName
dim winShell: set winShell = CreateObject( "Shell.Application" )
dim folder: set folder = winShell.NameSpace( itemFolderPath )
writeline "Folder title: " & folder.title
dim item: set item = folder.Items.Item( itemName )
writeline "Item name: " & item.Name
dim verbs: set verbs = item.Verbs ' !Produces Qt warning.
writeline "--------------------------------------------"
writeline verbs.Count & " verbs:"
dim propertiesVerb : set propertiesVerb = Nothing
dim verb: dim verbName
for each verb in verbs
verbName = verb.Name
writeline " -> " & verb.Name
if UCase( Replace( verbName, "&", "" ) ) = "PROPERTIES" then
set propertiesVerb = verb
end if
next
if propertiesVerb is Nothing then
writeline "!Properties verb not found"
else
writeline "Displaying properties dialog..."
propertiesVerb.DoIt
end if
The baffling Qt warning, indicating a Qt hook somewhere in Windows, is produced by the so commented line, which just invokes the Verbs property on a folder item (scripting object).
I want to do this, display the properties dialog for a specified file, entirely in scripting, not at the Windows API level via e.g. C++ or C# which I suspect would just work.
Update:
By just adding
WScript.Sleep 200
after the invocation of the verb item, the dialog now shows. However, the Qt warning is there still. I don't want that.
Related
I am attempting to generate a multi-page pdf document in my ASP.Net application using wkhtmltopdf by passing in multiple URLs.
Here is the code that gets called -
Public Shared Function WKHtmlToPdf(ByVal url As String, ByVal OutputDir As String, ByVal OutputFileName As String) As Boolean
Dim blnReturn As Boolean = False
Dim wkhtml As String = HttpContext.Current.Server.MapPath("~/resources/wkhtmltopdf/wkhtmltopdf.exe")
Dim p As New Process()
p.StartInfo.CreateNoWindow = True
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
p.StartInfo.RedirectStandardInput = True
p.StartInfo.UseShellExecute = False
p.StartInfo.FileName = wkhtml
p.StartInfo.WorkingDirectory = OutputDir
p.StartInfo.Arguments = url & " " & OutputFileName
p.Start()
p.WaitForExit(60000)
Dim returnCode As Integer = p.ExitCode
p.Close()
If returnCode = 0 Then
blnReturn = True
End If
Return blnReturn
End Function
Now the problem I am having is it errors at
p.WaitForExit(60000)
with the following error message.
Process must exit before requested information can be determined.
However, this error only seems to occur when I pass in more than 4 or 5 URLs, it seems random, sometimes its less, sometimes its more. This causes the process to take a long time to generate the PDF and thus error at p.WaitForExit...
I wondered if there some kind of Request limit being hit? I can generate the PDF with as many URLs I need when using the command prompt directly.
The issue is the process is waiting for the exit code which is never returned under normal settings (60 secs).
If you are using the latest version, it supports 'quiet' parameter, this allows the exit code to be returned correctly.
https://wkhtmltopdf.org/usage/wkhtmltopdf.txt
--disable-javascript --quiet --disable-smart-shrinking --print-media-type --margin-top 10mm --margin-bottom 10mm --margin-right 10mm --margin-left 10mm --page-size A4 "https://www.google.com" google.pdf
Am Using Inventor api for customizing inventor documents.Here I use vb.net code for start an instance of the Inventor .my code is
inventorApp = CreateObject("Inventor.Application", "")
inventorApp.Visible = True
it is ok and working fine .but when we open the visual studio run as administrator then the createobject having some error.Any one know any other way to start an instance of Inventor?
Try using the marshal method instead.
Dim m_inventorApp As Inventor.Application
Try ' Try to use active inventor instance
Try
m_inventorApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application")
m_inventorApp.SilentOperation = True
Catch ' If not active, create a new instance of Inventor
Dim inventorAppType As Type = System.Type.GetTypeFromProgID("Inventor.Application")
m_inventorApp = System.Activator.CreateInstance(inventorAppType)
' Must set visible explicitly
m_inventorApp.Visible = True
m_inventorApp.SilentOperation = True
End Try
Catch
'Cant get or create an instance of inventor.
End Try
Private Sub Open_Button_Click()
ThisApplication.SilentOperation = True 'Suppresses the resolve links dialog
Dim myPath As String
myPath = FileName.Text 'Gets the string, FileName, from module 1
Dim Shell As Object
Set Shell = CreateObject("Shell.Application")
Shell.Open (myPath) 'Opens selected file
Resolve_and_Open.Hide 'Hides module
CompareStrings
End Sub
This is to open a sad assembly that needs to resolve links. I'm not sure if this will get around that error, but try using this:
ThisApplication.SilentOperation = True
Either that, or creating a shell and then opening it that way instead of directly.
I'm looking to run a command prompt with a "dir" command in my web app and read the response...which I've got working but I need to to do another command first i.e. I need to use a CD to get to the proper directory.
I can get a DIR response and write it to the screen by basically using this link :
http://weblogs.asp.net/guystarbuck/archive/2008/02/06/invoking-cmd-exe-from-net.aspx
or here is the code:
If Not IsPostBack Then
Dim _info As New ProcessStartInfo("cmd", "/C " & "DIR")
' The following commands are needed to redirect the
' standard output. This means that it will be redirected
' to the Process.StandardOutput StreamReader.
_info.RedirectStandardOutput = True
' Set UseShellExecute to false. This tells the process to run
' as a child of the invoking program, instead of on its own.
' This allows us to intercept and redirect the standard output.
_info.UseShellExecute = False
' Set CreateNoWindow to true, to supress the creation of
' a new window
_info.CreateNoWindow = True
' Create a process, assign its ProcessStartInfo and start it
Dim _p As New Process()
_p.StartInfo = _info
_p.Start()
' Capture the results in a string
Dim _processResults As String = _p.StandardOutput.ReadToEnd()
' Close the process to release system resources
_p.Close()
' Return the output stream to the caller
Response.Write(_processResults)
End If
The trouble it's in the wrong directory...how can I do a CD otherdir first?
Anyone know?
Thanks,
You could try with this command concatenation character
Dim _info As New ProcessStartInfo("cmd", "/C C: & CD C:\TEMP & DIR")
Why so complicated? You can use this one-liner:
string[] filePaths = Directory.GetFiles(#"c:\MyDir\", "*.bmp");
to get an array of all files (in this case, all .bmp-files) in the given directory. The extension parameter is optional.
Whenever page is created or modified we want it to be published to Staging target.
For this we have Manual Activity "Create or Edit Page", then we have automatic activity "Publish to Staging" in this we have written following code, but page is not getting published when it is created or modified. Also no error is shown how to debug where things are going wrong.
' Script for Automatic Activity Content Manager Workflow
Set oTDSE = CreateObject("TDS.TDSE")
Call oTDSE.Initialize
Set ObjCurrentItem = CurrentWorkItem.GetItem(3)
sDestinationServer = "tcm:0-2-65538"
Set oPage = oTDSE.GetObject(ObjCurrentItem.ID, 3)
Call oPage.Publish(sDestinationServer, True, True, True)
FinishActivity "Publish to Staging for Review"
set oPage = Nothing
set ObjCurrentItem = Nothing
set oTDSE = Nothing
Since you mentioned this is your first workflow implementation, here are some other basics to try/look for. Since this is a Page Workflow, I'm assuming that the Structure Group that you are creating/editing the page in has already been associated to a Workflow Process Definition in that SG's workflow tab.
Create a new page (or edit a page) in the SG with the Workflow process definition set.
Verify that the Page is locked and in Workflow. From the Shortcuts section, goto "My Tasks". You should see your page there. If not, then the SG is probably missing the Process Definition.
Right click the page from "My Tasks" and click "Finish Activity". This should finish your Manual Step and send it to your Automatic Activity. That Activity should then execute the script, which will publish the page and then finish the automatic activity, sending the workflow process to your next step.
Verify that the Page has been published (check publishing queue).
If the page has not been published, go to the page and check its status. If an error happens during an Automatic Activity, the workflow item will be "suspended" and stuck on that activity. If you see this, you can get details of the error from the Event Log under Source "Workflow Script".
If following the above, and the workflow item is moving along the workflow process correctly (getting past your automatic activity without error and to your next activity) and you are still not seeing it being published, then verify what Nuno suggested.
Also note that you don't have to open the page using the TDSE object as you already have it opened via the CurrentWorkItem.GetItem() method... your script can be shortened:
Dim ObjCurrentItem
Set ObjCurrentItem = CurrentWorkItem.GetItem()
Call ObjCurrentItem.Publish("tcm:0-2-65538", True, True, True)
FinishActivity "Publish to Staging for Review"
Set ObjCurrentItem = Nothing
As you can see this is a very old code but works to publish objects via Workflow. "This code also publishes the pages/where this items is referenced."
Apart from looking at various logs, would suggest set the clean=false and check till what point the packages are created. This will give you idea how far it has reached. Ofcourse put bit of debug messages to see if all executes well.
Sub WFPublishPages( ByRef oComponent, ByRef targets, ByRef activateBlueprinting, ByRef activateWorkflow, ByRef rollbackOnFailure, ByRef publishTime, ByRef unpublishTime, ByRef deployTime, ByRef resolveComponentLinks, ByRef priority, ByRef ignoreRenderFailures, ByRef maximumRenderFailures )
' If IsNull(publishTime) Then
' publishTime = 0
' End If
' If IsNull(unpublishTime) Then
' unpublishTime = 0
' End If
' If IsNull(deployTime) Then
' deployTime = 0
' End If
' If IsNull(resolveComponentLinks) Then
' resolveComponentLinks = True
' End If
' If IsNull(priority) Then
' priority = PublishPriorityNormal
' End If
' If IsNull(ignoreRenderFailures) Then
' ignoreRenderFailures = false
' End If
' Is IsNull(maximumRenderFailures) Then
' maximumRenderFailures = 0
' End If
Dim Debugstring
Debugstring = ""
Dim oLRF
Set oLRF = TDSE.CreateListRowFilter()
Call oLRF.SetCondition("ItemType", ItemTypePage)
Call oLRF.SetCondition("OnlyLatestItems", True)
Dim oXML
Set oXML = CreateObject("MSXML2.DOMDocument.6.0")
Call oXML.setProperty("SelectionNamespaces", "xmlns:tcm=""http://www.tridion.com/ContentManager/5.0"" xmlns:xlink=""http://www.w3.org/1999/xlink""")
Call oXML.loadXML(oComponent.Info.GetListUsingItems(XMLListID, oLRF))
Dim oNode
Dim oPage
Dim strPageID
Debugstring = Debugstring & " DUBUG: ComponentID " & oComponent.ID & vbCrLf
For Each oNode In oXML.selectNodes("/tcm:ListUsingItems/tcm:Item")
strPageID = oNode.selectSingleNode("#ID").text
Debugstring = Debugstring & " DUBUG: PageID " & strPageID & vbCrLf
Set oPage = TDSE.GetObject(strPageID, OpenModeView )
Debugstring = Debugstring & " DUBUG: oPage.Title "
Debugstring = Debugstring & oPage.Title
Debugstring = Debugstring & vbCrLf
Call oPage.Publish(targets , activateBlueprinting, activateWorkflow, rollbackOnFailure, publishTime, unpublishTime, deployTime, resolveComponentLinks, priority,ignoreRenderFailures,maximumRenderFailures )
Call WriteLog("Publish Page: " & oPage.Title & " for component " & oComponent.Title & " - renderTime is " & publishTime & " - deployTime is " & deployTime)
Set oPage = Nothing
Set oNode = Nothing
Next
Set oXML = Nothing
Set oLRF = Nothing
Thanks
Vin
Here's a few things you can test:
Run the publisher in debug mode (stop the service, open a command prompt, run c:\Program Files (x86)\Tridion\bin\TcmPublisher /debug) and check for errors
Try publishing the page from the "My Tasks" view
Check if your page's current approval status is higher or equal than the Publication Target's "Minimum approval Status"
In command line it works fine:
net USE T: \123.45.67.89\TEST mytestuser /user:MYTESTUSER
But using asp.net, with the following code, the Exception with the following error is always thrown: 'The local device name is already in use' when mapping drive
I have tried disconnecting from all drives first, mapping to a different Drive letter. I have done this from different servers, and to different servers
Is the problem definitely with drive letter?
temp = MapDrive("T", "\\123.45.67.89\TEST", "MYTESTUSER", "mytestuser")
Public Shared Function MapDrive(ByVal DriveLetter As String, ByVal Path As String, ByVal Username As String, ByVal Password As String) As Boolean
Dim ReturnValue As Boolean = False
Dim p As New System.Diagnostics.Process()
p.StartInfo.UseShellExecute = False
p.StartInfo.CreateNoWindow = True
p.StartInfo.RedirectStandardError = True
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.FileName = "net.exe"
p.StartInfo.Arguments = " use " & DriveLetter & ": " & Path & " /user:" & Username & " " & Password & " /persistent:yes"
p.Start()
p.WaitForExit()
Dim ErrorMessage As String = p.StandardError.ReadToEnd()
Dim OuputMessage As String = p.StandardOutput.ReadToEnd()
Dim StoreFile As System.IO.Directory
Dim Files As String()
Dim File As String
If ErrorMessage.Length > 0 Then
Throw New Exception("Error:" & ErrorMessage)
Else
ReturnValue = True
End If
Files = StoreFile.GetFiles("T:\FINDTHIS\", "*")
For Each File In Files
HttpContext.Current.Trace.Warn(File)
Next
Return ReturnValue
End Function
Aren't mapped drives particular to the user that is running the net command?
Your asp.net page usually runs under a different identity to the current user's. This means that your code might possibly map the network path successfully the first time you run it. Then when you run it the second time you will get that error.
But then you are looking in vain to delete the mapping for that letter in your cmd window since the drive was not mapped via your user identity (under which your cmd window is running after all)
Then there's also the permissions needed to run the net command, although that might have thrown a different error.