My client has some internet shortcuts (*.url) on his desktop and I want to get their URL through a VB application and use them as variables.
Any idea how can I do that?
There's a sample on MSDN for *.lnk and *.appref-ms-files.
But seems to work for *.url-files too.
Quote from the site:
To check if a file is a shortcut and to resolve a shortcut path, the
COM Library Microsoft Shell Controls And Automation is used. This
library is added to the References of the Visual Studio project.
Code:
Public Function IsShortcut(strPath As String) As Boolean
If Not File.Exists(strPath) Then
Return False
End If
Dim directory As String = Path.GetDirectoryName(strPath)
Dim strFile As String = Path.GetFileName(strPath)
Dim shell As Shell32.Shell = New Shell32.Shell()
Dim folder As Shell32.Folder = shell.NameSpace(directory)
Dim folderItem As Shell32.FolderItem = folder.ParseName(strFile)
If folderItem IsNot Nothing Then
Return folderItem.IsLink
End If
Return False
End Function
Public Function ResolveShortcut(strPath As String) As String
If IsShortcut(strPath) Then
Dim directory As String = Path.GetDirectoryName(strPath)
Dim strFile As String = Path.GetFileName(strPath)
Dim shell As Shell32.Shell = New Shell32.Shell()
Dim folder As Shell32.Folder = shell.NameSpace(directory)
Dim folderItem As Shell32.FolderItem = folder.ParseName(strFile)
Dim link As Shell32.ShellLinkObject = folderItem.GetLink
Return link.Path
End If
Return String.Empty
End Function
Related
I am using a Word dotm file as a template for a SharePoint content type. This word-template contains a Form, opened by a statement in the Document_New() event. A combobox on that form contains the value of a content type property. VBA is used to set the combobox text value via Document.ContentTypeProperties:
Me.cmbComboBox.Text = ThisDocument.ContentTypeProperties("NameOfContentTypeProperty")
This works in Word 2016 on Windows. But in Word 2016 on MacOS this call results in the following error:
Run-time error 5948 This command is not available on this platform.
It seems that this property of the Document object is not available on MacOS.
Does anyone know how to read and write these content type properties in VBA Word 2016 on MacOS?
I managed to read and write the content type properties by editing the XML of the document using the following functions. This works on both Mac and PC.
Function getContentTypeProperty(strElementName As String, docDocument As Word.Document) As String
Dim xmlNode As CustomXMLNode
Dim xmlPart As CustomXMLPart
Set xmlPart = docDocument.CustomXMLParts.SelectByNamespace("http://schemas.microsoft.com/office/2006/metadata/properties").Item(1)
Set xmlNode = xmlPart.SelectSingleNode("/ns0:properties/documentManagement/ns3:" & strElementName)
If xmlNode Is Nothing Then
getContentTypeProperty = ""
Else
getContentTypeProperty = xmlNode.Text
End If
End Function
Function setContentTypeProperty(strElementName As String, docDocument As Word.Document, strValue As String) As Boolean
Dim xmlNode As CustomXMLNode
Dim xmlPart As CustomXMLPart
Set xmlPart = docDocument.CustomXMLParts.SelectByNamespace("http://schemas.microsoft.com/office/2006/metadata/properties").Item(1)
Set xmlNode = xmlPart.SelectSingleNode("/ns0:properties/documentManagement/ns3:" & strElementName)
If xmlNode Is Nothing Then
setContentTypeProperty = False
Else
If getAttributeValueByName(xmlNode.Attributes, "nil") = "true" Then setAttributeValueByName xmlNode.Attributes, "nil", "false"
xmlNode.Text = strValue
setContentTypeProperty = True
End If
End Function
Function getAttributeValueByName(xmlAttributes As CustomXMLNodes, strAttributeName As String) As String
Dim xmlAttribute As CustomXMLNode
Dim strValue As String
For Each xmlAttribute In xmlAttributes
If xmlAttribute.BaseName = strAttributeName Then strValue = xmlAttribute.NodeValue
Next
getAttributeValueByName = strValue
End Function
If the command doesn't exist for Mac you might have to use AppleScript. Unfortunately, I can't help you with AppleScript and I can't find any documentation from MS about what is or isn't available on a Mac.
Here is a compiler directive that will allow you to run different code on Mac or PC.
'Test the conditional compiler constant #Mac
#If Mac Then
'I am a Mac
Me.cmbComboBox.Text = AppleScriptTask ("MyAppleScriptFile.applescript", "myapplescripthandler", "my parameter string")
#Else
'I am Windows
Me.cmbComboBox.Text = ThisDocument.ContentTypeProperties("NameOfContentTypeProperty")
#End If
I'm having a problem with using FileSystemObject.CopyFile. I think I'm using it correctly, from the forums I've read, but I am still getting the following compiler error:
ArgumentException was unhandled: Value does not fall within expected range
Here is the code:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fso As New Scripting.FileSystemObject
Dim testfolderchk
testfolderchk = Dir("C:\Test\")
Dim inforeader As System.IO.FileInfo
Dim filedestinationcheck = Dir("C:\Test2\")
If testfolderchk <> "" Then
If Microsoft.VisualBasic.Left(testfolderchk, 4) = "test" Then
inforeader = My.Computer.FileSystem.GetFileInfo("C:\Test" & testfolderchk)
filetime = (inforeader.LastWriteTime)
If testfolderchk = filedestinationcheck Then GoTo skipfile
If testfolderchk = filedestinationcheck2 Then GoTo skipfile
Else : GoTo skipfile
End If
End If
fso.CopyFile(testfolderchk, filedestinationcheck, True)
As suggested in the comments you should scrap the use of FileSystemObject and use instead the System.IO namespace, specifically FileInfo:
Provides properties and instance methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of FileStream objects. This class cannot be inherited.
With FileInfo you can use the method CopyTo (String, Boolean):
Copies an existing file to a new file, allowing the overwriting of an existing file.
I have drafted up a bit of code to show you what I mean:
Dim folderToCheck As String = "C:\Test"
Dim destinationFolder As String = "C:\Test2"
Dim file As IO.FileInfo = New IO.FileInfo(IO.Path.Combine(folderToCheck, "test.txt"))
Dim filetime As Date = file.LastWriteTime
file.CopyTo(IO.Path.Combine(destinationFolder, file.Name), True)
Note the use of Path.Combine:
Combines two strings into a path.
I have a simple setup project that is no longer working and it seems like a windows update is the cause. I am using Visual Studio 2010 on Windows 7. The project is 64bit. It still works on some computers but it does not work on any computers that have had updates recently.
Here is the original code:
Dim appPath As String = Registry.GetValue("HKEY_CURRENT_USER\SOFTWARE\Our Company Inc.\SoftwareName.exe", "Path", "Not Found")
appPath &= "Colorbar.col"
Dim sid : sid = "S-1-1-0"
Dim objWMI : objWMI = GetObject("winmgmts://./root\cimv2")
Dim objSID : objSID = objWMI.Get("Win32_SID='" & sid & "'")
Dim userAccount As String = objSID.AccountName
Dim fileInfo As IO.FileInfo = New IO.FileInfo(appPath)
Dim fileAcl As New FileSecurity
fileAcl.AddAccessRule(New FileSystemAccessRule(userAccount, FileSystemRights.FullControl, AccessControlType.Allow))
fileInfo.SetAccessControl(fileAcl)
I have put the key value pair of "Path" and "[TARGETDIR]" in the registry editor and have the output from this installer class (the code above) in the Install and Commit custom actions.
This code that used to work now returns "Exception has been thrown by the target of an invocation -> C:\Windows\SYSWOW64\Colorbar.col"
I have checked the registry when this message appears and the path is correct so I don't know where SYSWOW64 is coming from.
I have tried to change getting the appPath using this code:
Dim regKey As RegistryKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)
regKey = regKey.OpenSubKey("SOFTWARE\Our Company Inc.\SoftwareName.exe")
Dim appPath As String = regKey.GetValue("Path").ToString
This returns an "Object reference not set to an instance of an object" error.
I have made a test Windows Form application and put both versions of code in a button event. Everything works as expected. Any ideas why the code does not work in a setup project anymore and what I can do to get it working again?
Thanks in advance.
Finally have it working again. I got around using the registry by using the custom action's CustomActionData and setting it to:
/name="[TARGETDIR]\"
I was then able to access it in my installer class by using this line of code:
Dim appPath As String = Context.Parameters.Item("name")
Once the path was set, everything else worked as expected. The final code looks like this:
Public Overrides Sub Commit(ByVal stateSaver As System.Collections.IDictionary)
MyBase.Commit(stateSaver)
Dim appPath As String = Context.Parameters.Item("name")
appPath = appPath.Remove(appPath.Length - 1)
appPath &= "Colorbar.col"
Dim sid : sid = "S-1-1-0"
Dim objWMI : objWMI = GetObject("winmgmts://./root\cimv2")
Dim objSID : objSID = objWMI.Get("Win32_SID='" & sid & "'")
Dim userAccount As String = objSID.AccountName
Dim fileInfo As IO.FileInfo = New IO.FileInfo(appPath)
Dim fileAcl As New FileSecurity
fileAcl.AddAccessRule(New FileSystemAccessRule(userAccount, FileSystemRights.FullControl, AccessControlType.Allow))
fileInfo.SetAccessControl(fileAcl)
End Sub
I have been asked to create a console application which polls an active Directory. (C.\Temp\Input)
When a file comes in with (filename).SUCCESS, filename is retrieve in order to run a SQL query. So
IF fileextension = SUCCESS
Runs SQL Query using filename to change a value in the SQL Table.
Moves Original file to c:\temp\Input\Processed
Any help or hints would be much appreciated.
UPDATED:
Hi, With a few looks at various sites iv come up with the below. Forgetting the SQL for now, im only after the Filename and the moving of files but im getting an IO Exception that the file is already in use:
Imports System.IO
Imports System.String
Module Module1
Dim fileName As String = "C:\temp\Input\NR12345.success"
Dim pathname As String = "C:\temp\Input\"
Dim result As String
Dim sourceDir As String = "C:\temp\Input\"
Dim processedDir As String = "C:\temp\Input\Processed\"
Dim fList As String() = Directory.GetFiles(sourceDir, "*.success")
Sub Main()
result = Path.GetFileName(fileName)
Console.WriteLine("GetFileName('{0}') returns '{1}'", fileName, result)
result = Path.GetFileName(pathname)
Console.WriteLine("GetFileName('{0}') returns '{1}'", pathname, result)
Call MySub()
End Sub
Sub MySub()
'Move Files
For Each f As String In fList
'Remove path from the file name.
Dim fName As String = f.Substring(sourceDir.Length = 0)
Dim sourceFile = Path.Combine(sourceDir, fName)
Dim processedFileDir = Path.Combine(processedDir, fName)
' Use the Path.Combine method to safely append the file name to the path.
' Will overwrite if the destination file already exists.
File.Copy(Path.Combine(sourceDir, fName), Path.Combine(processedDir, fName), True)
'File.Copy(sourceFile, processedFileDir)
Next f
End Sub
End Module
I've used this before:
The FileWather Class
Really useful for polling directories for changes in structure and file details etc.
You can then use this to get an extension of a file and, if it meets your criteria, perform some actions.
These links come with examples so enjoy!!
Sub MySub()
'Move Files
For Each f As String In fList
Dim fInfo As FileInfo = New FileInfo(f)
Dim fName As String = fInfo.Name
Dim processedFileDir = Path.Combine(processedDir, fName)
' Use the Path.Combine method to safely append the file name to the path.
' Will overwrite if the destination file already exists.
File.Copy(fInfo.FullName, processedFileDir, True)
Next f
End Sub
I am trying to locate a file from a program, in VB.NET
Dim exeName As String = "explorer.exe"
Dim params As String = "/e,""c:\test"",/select,""C:\test\a.txt"""
Dim processInfo As New ProcessStartInfo(exeName, params)
Process.Start(processInfo)
It opens the containing directory "c:\" but doesn't go inside to "c:\test", I would like to have the file selected...
Dim filePath As String = "C:\test\a.txt" 'Example file
Process.Start("explorer.exe", "/select," & filePath) 'Starts explorer.exe and selects desired file
You don't need the folder path in there after the /e, try this for your params:
Dim params As String = "/e, /select,""C:\temp\file.txt"""