i use vb.net To dev winform app. I can take blockreference, block name"Tab1". Now i want Get this block To edit block attribute, but i don't know how to do that,i search on gg but have no result.
Dim appProgID As String = "Autocad.Application"
Dim fname As String = "C:\Users\Kid\Downloads\IDEA FOR TOOL\TEST\TABLE ATTRIBUTE.dwg"
Dim AcadType As Type = Type.GetTypeFromProgID(appProgID)
Dim AcadApp As Object = Activator.CreateInstance(AcadType)
Dim visargs() As Object = New Object(0) {}
visargs(0) = False
AcadApp.GetType().InvokeMember("Visible", BindingFlags.SetProperty, Nothing, AcadApp, visargs, Nothing)
Dim AcadDocs As Object = AcadApp.GetType().InvokeMember(
"Documents", BindingFlags.GetProperty, Nothing, AcadApp, Nothing)
Dim args() As Object = New Object(1) {}
args(0) = fname
args(1) = False
Dim AcDoc As Object = AcadDocs.GetType.InvokeMember(
"Open", BindingFlags.InvokeMethod, Nothing, AcadDocs, args, Nothing)
AcadApp.GetType.InvokeMember(
"ActiveDocument", BindingFlags.GetProperty, Nothing, AcadApp, Nothing, Nothing)
AcDoc = AcadApp.GetType.InvokeMember(
"ActiveDocument", BindingFlags.GetProperty, Nothing, AcadApp, Nothing, Nothing)
Dim AcadModel As Object = AcDoc.GetType.InvokeMember("modelspace", BindingFlags.GetProperty, Nothing, AcDoc, Nothing)
Dim entity As Object
For Each entity In AcadModel
If TypeName(entity) = "IAcadBlockReference" Then
'here i want to take this block has name "tab1"
End If
Next
You don't need to use InvokeMember, VB.NET supports late binding.
Dim acadType As Type = Type.GetTypeFromProgID("AutoCAD.Application")
Dim acadApp = Activator.CreateInstance(acadType)
acadApp.Visible = true
Dim doc = acadApp.Documents.Open("C:\Users\Kid\Downloads\IDEA FOR TOOL\TEST\TABLE ATTRIBUTE.dwg")
Dim entity
For Each entity In doc.ModelSpace
If entity.ObjectName = "AcDbBlockReference" AndAlso _
String.Equals(entity.Name, "Tab1", StringComparison.OrdinalIgnoreCase) Then
Dim att
For Each att In entity.GetAttributes()
If att.TagString = "A" Then
att.TextString = "Your value"
End If
Next
End If
Next
If you want to have autocompletion, you need to download the ObjectARX SDK and add the following COM references to your VS project:
C:\ObjectARX 20..\inc-x64\Autodesk.AutoCAD.Interop.dll
C:\ObjectARX 20..\inc-x64\Autodesk.AutoCAD.Interop.Common.dll
Then you will be able to use typed variables like this:
Dim acadApp As AcadApplication = Activator.CreateInstance(acadType)
Related
I want to protect an Excel Sheet.
I tried officeapp.protect("mypassowrd") but it's not working.
Dim docPath As String =
Path.Combine(My.Application.Info.DirectoryPath,"CURRICULUM.xlsx")
Dim officeapp As New Microsoft.Office.Interop.Excel.Application
officeapp = CreateObject("Excel.Application")
Dim workbook As Object = officeapp.Workbooks.Add(docPath)
officeapp.Visible = True
With officeapp
.Range("A" + (10).ToString).Value = "i want to protect this rows"
.Range("B" + (10).ToString`).Value = "i want to protect this rows"
.Range("C" + (10).ToString).Value = "i want to protect this rows"
End With
officeapp = Nothing
workbook = Nothing
officeapp.protect("mypassowrd")
Me.Refresh()
There is method inside
Excel.Application
Dim objExcel As New Excel.Application
objExcel.ActiveWorkbook.SaveAs()
Sub SaveAs(Optional Filename As Object = Nothing,
Optional FileFormat As Object = Nothing,
Optional Password As Object = Nothing,
Optional WriteResPassword As Object = Nothing,
Optional ReadOnlyRecommended As Object = Nothing,
Optional CreateBackup As Object = Nothing,
Optional AccessMode As Excel.XlSaveAsAccessMode = xlNoChange,
Optional ConflictResolution As Object = Nothing,
Optional AddToMru As Object = Nothing,
Optional TextCodepage As Object = Nothing,
Optional TextVisualLayout As Object = Nothing,
Optional Local As Object = Nothing)
Member of Excel._Workbook
I'm getting an error everytime I try to upload a XML file to an specific server.
It returns "Invalid character in a Base-64 string". Here the code I'm using to sign:
Public Sub Assinar03(ByVal strArqXMLAssinar As String, ByVal strUri As String, ByVal x509Certificado As X509Certificate2, ByVal strArqXMLAssinado As String)
Dim SR As StreamReader = Nothing
SR = File.OpenText(strArqXMLAssinar)
Dim vXMLString As String = SR.ReadToEnd()
SR.Close()
Dim _xnome As String = String.Empty
Dim _serial As String = String.Empty
If x509Certificado IsNot Nothing Then
_xnome = x509Certificado.Subject.ToString()
_serial = x509Certificado.SerialNumber
End If
Dim _X509Cert As New X509Certificate2()
Dim store As New X509Store("MY", StoreLocation.CurrentUser)
store.Open(OpenFlags.[ReadOnly] Or OpenFlags.OpenExistingOnly)
Dim collection As X509Certificate2Collection = DirectCast(store.Certificates, X509Certificate2Collection)
Dim collection1 As X509Certificate2Collection = DirectCast(collection.Find(X509FindType.FindBySerialNumber, _serial, False), X509Certificate2Collection)
If collection1.Count > 0 Then
_X509Cert = Nothing
For i As Integer = 0 To collection1.Count - 1
If DateTime.Now < collection1(i).NotAfter OrElse Not _X509Cert Is Nothing AndAlso _X509Cert.NotAfter < collection1(i).NotAfter Then
_X509Cert = collection1(i)
End If
Next
If _X509Cert Is Nothing Then _X509Cert = collection1(0)
Dim doc As New XmlDocument()
doc.PreserveWhitespace = False
doc.LoadXml(vXMLString)
Dim qtdeRefUri As Integer = doc.GetElementsByTagName(strUri).Count
Dim reference As New Reference()
Dim keyInfo As New KeyInfo()
Dim signedXml As New SignedXml(doc)
signedXml.SigningKey = _X509Cert.PrivateKey
Dim _Uri As XmlAttributeCollection = doc.GetElementsByTagName(strUri).Item(0).Attributes
For Each _atributo As XmlAttribute In _Uri
If _atributo.Name.ToLower.Trim = "Id".ToLower.Trim Then
reference.Uri = "#" + _atributo.InnerText
End If
Next
If reference.Uri Is Nothing Then reference.Uri = ""
reference.DigestMethod = SignedXml.XmlDsigSHA1Url
'--------------------------------------------------
Dim env As New XmlDsigEnvelopedSignatureTransform()
env.Algorithm = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
reference.AddTransform(env)
'--------------------------
Dim c14 As New XmlDsigC14NTransform(False)
c14.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
reference.AddTransform(c14)
'--------------------------
signedXml.AddReference(reference)
keyInfo.AddClause(New KeyInfoX509Data(_X509Cert))
'--------------------------
signedXml.KeyInfo = keyInfo
signedXml.ComputeSignature()
'--
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
XMLDoc = New XmlDocument()
XMLDoc.PreserveWhitespace = False
XMLDoc = doc
Me.vXMLStringAssinado = XMLDoc.OuterXml
'-----------
Dim SW_2 As StreamWriter = File.CreateText(strArqXMLAssinado)
SW_2.Write(Me.vXMLStringAssinado)
SW_2.Close()
'-----------
End If
SR.Close()
End Sub
Is there something else I should add to the code?
The manual tells me to follow the instructions from https://www.w3.org/TR/xmldsig-core/
Turns out it was a line break when saving the document. I set the .PreserveWhitespace property to true before saving the .xml file and not it seems to be working.
In Silverlight, I use a Dynamic class. I want to call boolean function before set property, for example :
Private _MyVar as Object
Public Property MyVar as Object
Get
return _MyVar
End Get
Set(value as Object)
If IsUpdateProp(value,"MyVar") Then _myVar = value
End Set
End Property
Private Function IsUpdateProp(value as Object, key as string) as Boolean
If value Is Nothing AndAlso GetValueProperty(key) Is Nothing
OrElse (value IsNot Nothing AndAlso
GetValueProperty(key) IsNot Nothing AndAlso
value.Equals(GetValueProperty(key))) Then
Return False
End If
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(key))
Return True`
End Function
I want to make this with reflection, my code :
Dim dp As DynamicProperty = properties(i)
Dim fb As FieldBuilder = tb.DefineField("_" & dp.Name, dp.Type,
FieldAttributes.Private)
Dim pb As PropertyBuilder = tb.DefineProperty(dp.Name,
PropertyAttributes.HasDefault, dp.Type, Nothing)
Dim isModify = GetType(Dynamic.DynamicClass).GetMethod("SetModifyField",
New Type() {GetType(Object), GetType(String)})
Dim mbSet As MethodBuilder = tb.DefineMethod("set_" & dp.Name,
MethodAttributes.Public Or
MethodAttributes.SpecialName Or
MethodAttributes.HideBySig,
Nothing, New Type() {dp.Type})
Dim genSet As ILGenerator = mbSet.GetILGenerator()
Dim mLabel = genSet.DefineLabel
genSet.Emit(OpCodes.Nop)
genSet.Emit(OpCodes.Ldarg_0)
genSet.Emit(OpCodes.Ldarg_1)
genSet.Emit(OpCodes.Box, dp.Type)
genSet.Emit(OpCodes.Ldstr, dp.Name)
genSet.Emit(OpCodes.Call, isModify)
genSet.Emit(OpCodes.Call, GetType(Convert).GetMethod("ToBoolean",
New Type() {GetType(Object)}))
genSet.Emit(OpCodes.Stloc_0)
genSet.Emit(OpCodes.Ldloc_0)
genSet.Emit(OpCodes.Brfalse_S, mLabel)
genSet.Emit(OpCodes.Ldarg_0)
genSet.Emit(OpCodes.Ldarg_1)
genSet.Emit(OpCodes.Stfld, fb)
genSet.MarkLabel(mLabel)
genSet.Emit(OpCodes.Nop)
genSet.Emit(OpCodes.Nop)
genSet.Emit(OpCodes.Ret)
At runtime, when I call setvalue on my property I get this error message:
System.Security.VerificationException: Cette opération pourrait déstabiliser le runtime." & vbCrLf & " à DynamicClass1.set_MyVar(Nullable`1 )
Thanks
I've been trying to create a function that returns an object of type. This function below is currently inside my dataclass and can be called from any object that inherits the dataclass. My problem is when I try and return my object. It populates just fine while I am inside the function. When I get back out to the calling object its all empty like it's a new object.
Here's the function....
Public Overloads Function GetClassFromDB(ByVal ID As Integer) As Object
Try
Dim BaseObject As New Object
Dim objDerived As Type = MyBase.GetType()
Dim TableName As String = String.Empty
Dim SQL As New LottoPayload.SQLiDataClass
Dim SQLString As String = String.Empty
Dim SQLCommand As SQLiteCommand = Nothing
Dim SQLConnection As SQLiteConnection = Nothing
Dim SQLiteDRObj As SQLiteDataReader = Nothing
Dim SQLResultsTable As New DataTable
'Create an instance of the base object
BaseObject = Activator.CreateInstance(objDerived)
'Get the tablename from the object
TableName = objDerived.GetProperty("TableName").GetValue(BaseObject, Nothing).ToString
SQLString = "SELECT * FROM " & TableName & " WHERE ID = '" & ID.ToString & "' LIMIT 1"
SQLConnection = SQL.GetSqlConnection()
SQLConnection.Open()
SQLCommand = New SQLiteCommand(SQLConnection)
SQLCommand.CommandText = SQLString
SQLiteDRObj = SQLCommand.ExecuteReader()
SQLResultsTable.Load(SQLiteDRObj)
If SQLResultsTable.Rows.Count > 0 Then
For Each Row As DataRow In SQLResultsTable.Rows
For Each Column As DataColumn In Row.Table.Columns
Dim ColumnName As String = Column.ColumnName.ToString
Console.WriteLine(Row.Item(ColumnName))
Dim ColumnValue As Object = Row.Item(ColumnName)
Console.WriteLine(Column.DataType.Name & " ")
Select Case Column.DataType.Name
Case "Int64"
Dim ConvertedValue As Integer
Integer.TryParse(ColumnValue.ToString, ConvertedValue)
objDerived.GetProperty(ColumnName).SetValue(BaseObject, ConvertedValue, Nothing)
Case "Double"
Dim ConvertedValue As Double
Double.TryParse(ColumnValue.ToString, ConvertedValue)
objDerived.GetProperty(ColumnName).SetValue(BaseObject, ConvertedValue, Nothing)
Case "String"
Dim ConvertedValue As String
ConvertedValue = ColumnValue.ToString
objDerived.GetProperty(ColumnName).SetValue(BaseObject, ConvertedValue, Nothing)
Case Else
Dim ConvertedValue As String
ConvertedValue = "NotSet"
objDerived.GetProperty(ColumnName).SetValue(BaseObject, ConvertedValue, Nothing)
End Select
Next
Next
End If
Return objDerived
SQLiteDRObj.Close()
SQLConnection.Close()
SQLConnection.Dispose()
'Return False
Catch ex As Exception
Return False
End Try
End Function
and this is how it would be called.
Dim objResults As New myapp.objResult
Dim ID As Integer = 3
objResults.GetClassFromDB(ID)
Question #1 - When I return the object from GetClassFromDB objResults is empty eventhough it had data up until the Return objDerived. Why is this the case?
Question #2 - Is there a way I can eliminate that Select Case area and consolidate the code by using reflection?
Thanks in advance for the help.
Shouldn't you be returning BaseObject rather than objDerived, given that objDerived is actually a Type object that represents the type of the object created rather than the object itself? Maybe it would be clearer if you didn't use appalling names like objDerived in the first place.
The problem is that your method returns an object, but you are not assigning it to a variable anywhere. You need to assign the return value of the method to a variable
Dim someVariable As Object = objResults.GetClassFromDB(ID)
Also, your method is strange in that it returns an object if the code runs successfully but a boolean if there is an exception, which you silently swallow (also a bad practice).
You are returning the wrong object. objDerived is a Type, not the object that you are setting. You need to return BaseObject. Also, realize that your code to close and dispose the SqlCommand and Connection won't be hit since it's after the return operator. It's best here to wrap the connection and command in Using clauses which will ensure they will be disposed once they go out of scope. See if the following works:
Public Overloads Function GetClassFromDB(ByVal ID As Integer) As Object
Try
Dim BaseObject As New Object
Dim objDerived As Type = MyBase.GetType()
Dim TableName As String = String.Empty
Dim SQL As New LottoPayload.SQLiDataClass
Dim SQLString As String = String.Empty
Using SQLConnection As SQLiteConnection = Nothing
Using SQLCommand As SQLiteCommand = Nothing
Dim SQLiteDRObj As SQLiteDataReader = Nothing
Dim SQLResultsTable As New DataTable
'Create an instance of the base object
BaseObject = Activator.CreateInstance(objDerived)
'Get the tablename from the object
TableName = objDerived.GetProperty("TableName").GetValue(BaseObject, Nothing).ToString
SQLString = "SELECT * FROM " & TableName & " WHERE ID = '" & ID.ToString & "' LIMIT 1"
SQLConnection = SQL.GetSqlConnection()
SQLConnection.Open()
SQLCommand = New SQLiteCommand(SQLConnection)
SQLCommand.CommandText = SQLString
SQLiteDRObj = SQLCommand.ExecuteReader()
SQLResultsTable.Load(SQLiteDRObj)
If SQLResultsTable.Rows.Count > 0 Then
For Each Row As DataRow In SQLResultsTable.Rows
For Each Column As DataColumn In Row.Table.Columns
Dim ColumnName As String = Column.ColumnName.ToString
Console.WriteLine(Row.Item(ColumnName))
Dim ColumnValue As Object = Row.Item(ColumnName)
Console.WriteLine(Column.DataType.Name & " ")
Select Case Column.DataType.Name
Case "Int64"
Dim ConvertedValue As Integer
Integer.TryParse(ColumnValue.ToString, ConvertedValue)
objDerived.GetProperty(ColumnName).SetValue(BaseObject, ConvertedValue, Nothing)
Case "Double"
Dim ConvertedValue As Double
Double.TryParse(ColumnValue.ToString, ConvertedValue)
objDerived.GetProperty(ColumnName).SetValue(BaseObject, ConvertedValue, Nothing)
Case "String"
Dim ConvertedValue As String
ConvertedValue = ColumnValue.ToString
objDerived.GetProperty(ColumnName).SetValue(BaseObject, ConvertedValue, Nothing)
Case Else
Dim ConvertedValue As String
ConvertedValue = "NotSet"
objDerived.GetProperty(ColumnName).SetValue(BaseObject, ConvertedValue, Nothing)
End Select
Next
Next
End If
End Using ' Sql Command
End Using ' Sql Connection
Return BaseObject
'Return False
Catch ex As Exception
Return False
End Try
End Function
End Class
From your second screen shot, you don't appear to be setting anything to the return of the GetClassFromDB(ID) method. It should probably be something like:
Dim result = objResults.GetClassFromDB(ID)
' Do something with result
This function loops all properties of an object to create the updatequery to save te object to the DB.
We had to make some changes to it because of the introduction of nullable properties.
If the property is nullable we would like to check the 'HasValue' property.
This does works when it has a value. When the property has no value we get an 'Non-static method requires a target'-error at the CBool-line
Any suggestions?
An other way to check the 'HasValue'-prop of a property using reflection?
Thanks.
Private Function GetUpdateQuery(ByVal obj As Object, ByRef params As List(Of SqlParameter), Optional ByVal excl As String() = Nothing) As String
Dim sql As String = String.Empty
Dim props As PropertyInfo() = obj.GetType().GetProperties
If excl Is Nothing Then
excl = New String() {}
End If
For Each prop As PropertyInfo In props
Try
If Not excl.Contains(prop.Name) And prop.CanWrite = True Then
sql &= String.Format("{0} = #{1},", prop.Name, prop.Name)
Dim param As SqlParameter
Dim value As Object
If prop.PropertyType.IsGenericType AndAlso prop.PropertyType.GetGenericTypeDefinition() = GetType(Nullable(Of )) Then
If CBool(prop.PropertyType.GetProperty("HasValue").GetValue(prop.GetValue(obj, Nothing), Nothing)) Then
value = prop.GetValue(obj, Nothing)
Else
value = DBNull.Value
End If
Else
If prop.GetValue(obj, Nothing) = Nothing Then
value = DBNull.Value
Else
value = prop.GetValue(obj, Nothing)
End If
End If
param = ConnSql.CreateParameter("#" & prop.Name, value)
params.Add(param)
End If
Catch ex As Exception
End Try
Next
sql = sql.Substring(0, sql.Length - 1)
Return sql
End Function
You do not need the following If. You can remove it.
If prop.PropertyType.IsGenericType AndAlso prop.PropertyType.GetGenericTypeDefinition() = GetType(Nullable(Of )) Then
BUT you do need to fix the following If:
If prop.GetValue(obj, Nothing) = Nothing Then
to
If prop.GetValue(obj, Nothing) IS Nothing Then
--
Complete code:
Private Function GetUpdateQuery(ByVal obj As Object, ByRef params As List(Of SqlParameter), Optional ByVal excl As String() = Nothing) As String
Dim sql As String = String.Empty
Dim props As PropertyInfo() = obj.GetType().GetProperties
If excl Is Nothing Then
excl = New String() {}
End If
For Each prop As PropertyInfo In props
If Not excl.Contains(prop.Name) And prop.CanWrite = True Then
sql &= String.Format("{0} = #{1},", prop.Name, prop.Name)
Dim param As SqlParameter
Dim value As Object
If prop.GetValue(obj, Nothing) Is Nothing Then
value = DBNull.Value
Else
value = prop.GetValue(obj, Nothing)
End If
param = ConnSql.CreateParameter("#" & prop.Name, value)
params.Add(param)
End If
Next
sql = sql.Substring(0, sql.Length - 1)
Return sql
End Function