Programmatically create a SQL Server Compact database on the client machines - c#

I have recently started experimenting with SQL Server Compact and EF6. I am currently using the model first approach and generating my classes and tables from it. I am curious though, about one thing. How can I get my program to dynamically create the database. It exists on my machine as I created it with the SQL Server Compact/SQLite toolkit, but when the program is deployed to client computers, the database will need to be created.
I would want to prompt them on first run for a good location, then create the entire DB schema and just use that in the future. I looked into this guide but vs started complaining about it not working because I didn't use a code-first approach.
If you need more info let me know! Thanks.

I have a little app I'm working on using SQL CE and EF and I deploy the template database when the app is installed (clickonce). Then I use a spash screen on application start to either load a previously created database or let the user create a new one.
When they create a new db I simply prompt them for a location and copy the template database out to their desired location with their desired name. I've also set it up to use the deployed database without giving them the opportunity have multiple database files.
We are dealing with a few pieces here as follows:
SQL CE database file
My stock/template .sdf file sits in my project folder and is included in the project within Visual Studio (I'm using 2015). Rightclick on the file in the Solution Explorer and select properties you want to set the following:
Build Action - Content
Copy to Output Directory - Copy always
Create global variable
Either use an existing module file or create a new one that looks like this:
Public Module Globals
Friend g_recipeData As RecipeEntities
End Module
Create setting for last file path
Rightclick on your project name in the solution explorer and pick Properties. Click the Settings tab and add a new setting as follows:
Name: lastpath
Type: String
Scope: User
Value:
Create splash screen form (frmSplash)
Mine looks like this:
Controls on the form are as follows:
txtFile
cmdSelectDatabase
cmdNew
cmdOpen
cmdExit
Splash Screen (frmSplash) Code
Region "Form Methods"
Private Sub OnFormLoad() Handles Me.Load
txtFile.Text = My.Settings.lastpath
If txtFile.Text <> "" Then
cmdOpen.Enabled = True
cmdOpen.Select()
Else
cmdNew.Select()
End If
End Sub
Private Sub FileSelect()
Try
Dim openFileDialog As New OpenFileDialog()
openFileDialog.Filter = "sdf files (*.sdf)|*.sdf|All files (*.*)|*.*"
openFileDialog.FilterIndex = 1
openFileDialog.RestoreDirectory = True
Dim result As DialogResult = openFileDialog.ShowDialog(Me)
If result = DialogResult.Cancel Then
cmdSelectDatabase.Select()
Exit Sub
End If
txtFile.Text = openFileDialog.FileName
If txtFile.Text <> "" Then
cmdOpen.Enabled = True
cmdOpen.Select()
My.Settings.lastpath = openFileDialog.FileName
My.Settings.Save()
Else
cmdOpen.Enabled = False
cmdSelectDatabase.Select()
End If
Catch ex As Exception
MessageBox.Show(ex.Message.ToString, "Application Error")
Application.Exit()
Finally
End Try
End Sub
Private Sub SetConnectionString()
Try
Dim providerName As String = "System.Data.SqlServerCe.4.0"
Dim datasource As String = txtFile.Text
Dim sqlCeBuilder As New SqlCeConnectionStringBuilder
sqlCeBuilder.DataSource = datasource
sqlCeBuilder.PersistSecurityInfo = True
g_SQLCeConnectionString = sqlCeBuilder.ConnectionString
Dim providerString As String = sqlCeBuilder.ToString()
Dim entityBuilder As New EntityConnectionStringBuilder()
entityBuilder.Provider = providerName
entityBuilder.ProviderConnectionString = providerString
entityBuilder.Metadata = "res://*/RecipeModel.csdl|res://*/RecipeModel.ssdl|res://*/RecipeModel.msl"
Dim c As System.Configuration.Configuration = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetExecutingAssembly().Location)
Dim section As ConnectionStringsSection = DirectCast(c.GetSection("connectionStrings"), ConnectionStringsSection)
g_EntityConnectionString = entityBuilder.ConnectionString
section.ConnectionStrings("RecipeEntities").ConnectionString = g_EntityConnectionString
c.Save(ConfigurationSaveMode.Modified)
ConfigurationManager.RefreshSection("connectionStrings")
Catch ex As Exception
MessageBox.Show(ex.Message.ToString, "Application Error")
Application.Exit()
End Try
End Sub
Private Sub CreateDatabase()
Try
Dim saveFileDialog As New SaveFileDialog()
saveFileDialog.Filter = "sdf files (*.sdf)|*.sdf"
saveFileDialog.Title = "Create Database"
saveFileDialog.FilterIndex = 1
If saveFileDialog.ShowDialog() = DialogResult.OK Then
File.Copy(Path.Combine(ApplicationDeployment.CurrentDeployment.DataDirectory, "rw.sdf"), saveFileDialog.FileName, True)
Dim strPathandFile As String = saveFileDialog.FileName
txtFile.Text = strPathandFile
My.Settings.lastpath = strPathandFile
My.Settings.Save()
cmdOpen.Enabled = True
End If
Catch ex As Exception
MessageBox.Show(ex.Message.ToString, "Application Error")
Application.Exit()
End Try
End Sub
Private Sub LoadMainApplication()
Try
Dim objNewForm As New FrmMain
objNewForm.Show()
Me.Close()
Catch ex As Exception
MessageBox.Show(ex.Message.ToString, "Application Error")
Application.Exit()
End Try
End Sub
End Region
Region "Event Handlers"
Private Sub cmdSelectDatabase_Click(sender As Object,
e As EventArgs) Handles cmdSelectDatabase.Click
FileSelect()
cmdOpen.Select()
End Sub
Private Sub cmdCancel_Click(sender As Object, e As EventArgs) Handles cmdExit.Click
Me.Close()
End Sub
Private Sub cmdOk_Click(sender As Object, e As EventArgs) Handles cmdOpen.Click
Me.Cursor = Cursors.WaitCursor
SetConnectionString()
LoadMainApplication()
Me.Cursor = Cursors.Default
End Sub
Private Sub txtFile_Validated(sender As Object, e As EventArgs) Handles txtFile.Validated
If txtFile.Text.Length = 0 Then
cmdOpen.Enabled = False
Else
cmdOpen.Enabled = True
End If
End Sub
Private Sub cmdNew_Click(sender As Object,
e As EventArgs) Handles cmdNew.Click
CreateDatabase()
SetConnectionString()
LoadMainApplication()
End Sub
Private Sub CatchEnterKey(ByVal sender As Object,
ByVal e As System.Windows.Forms.KeyPressEventArgs) _
Handles txtFile.KeyPress, txtPassword.KeyPress
If e.KeyChar = ChrW(Keys.Enter) Then
cmdOk_Click(sender, e)
e.Handled = True
Exit Sub
End If
End Sub
Set global variable value
On the form of your main application (frmMain above) add the following to the constructor:
Public Sub New()
InitializeComponent()
g_recipeData = New RecipeEntities
End Sub
If you perform the above action when you create the variable in the module file then the connection string for the entity is set and you can't change it. You must set the connection string in app.config (using the above code) first and then the entity will use desired connection string when instantiated.
I think that's the basics for now. I highly recommend you reading through it again now that I'm done. I made some corrections and even added a step for the lastpath setting. Just hit me up if something isn't working or is confusing and I'll do my best to help. Good luck!

Related

TesseractEngine does not release the traineddata file

After I run the following code I can not delete the *.traineddata file in datapath folder, until I completely closes the program.
Shared Function GetOcrText(ByVal imagePath As String,
ByVal datapath As String,
ByVal languages As IEnumerable(Of String)) As String
Dim languagesStr = String.Join("+", languages)
Dim resultText As String = ""
Using engine = New TesseractEngine(datapath, languagesStr, EngineMode.Default)
Using img = Pix.LoadFromFile(imagePath)
Using page = engine.Process(img)
resultText = page.GetText()
End Using
End Using
End Using
Return resultText
End Function
Am I wrong about something?
What should I do to be able to delete the file?
Use 3.2.0-alpha4 version of .Net wrapper for tesseract-ocr.
I tried your code with this version and everything works fine.

Trigering Essbase Macro with C#

I'm trying to automatize some Excel reports. Currently I need to retrieve some data from an Essbase Server, in order to achieve this I've created a macro to retrieve and set data in an Excel sheet, my VBA code is the following:
Option Explicit
Declare Function EssVRetrieve Lib "ESSEXCLN.XLL" (ByVal sheetName As Variant, ByVal range As Variant, ByVal lockflag As Variant) As Long
Declare Function EssVConnect Lib "ESSEXCLN.XLL" (ByVal sheetName As Variant, ByVal userName As Variant, ByVal password As Variant, ByVal server As Variant, ByVal application As Variant, ByVal database As Variant) As Long
Declare Function EssVDisconnect Lib "ESSEXCLN.XLL" (ByVal sheetName As Variant) As Long
Sub Essbase_Update_Pulls()
Dim rangeString As String
rangeString = "B3:AC5033"
MsgBox ("Starting macro")
Dim wbSrc As Workbook
Dim m As Variant
Dim mySheetname As Variant, myUserName As Variant, myPassword As Variant, myServer, myApp As Variant, myDB As Variant
Dim lockflag As Integer
Dim myrng As range
Dim x As Integer
Dim y As Integer
Dim z As Integer
Dim strMsgTxt As String
Dim blnRetVal As Boolean
Set wbSrc = ActiveWorkbook
Set myrng = range(rangeString)
lockflag = 1
MsgBox ("Data set")
mySheetname = "Sheet"
myServer = "Server"
myApp = "App"
myDB = "DB"
myUserName = "User"
myPassword = "Pass"
MsgBox ("Trying connection")
x = EssVConnect(mySheetname, myUserName, myPassword, myServer, myApp, myDB)
MsgBox (CStr(x))
If x < 0 Then
blnRetVal = False
strMsgTxt = "Essbase Login - Local Failure"
MsgBox (strMsgTxt)
ElseIf x > 0 Then
blnRetVal = False
strMsgTxt = "Essbase Login - Server Failure"
MsgBox (strMsgTxt)
Else
blnRetVal = True
strMsgTxt = "Success"
MsgBox ("Connection Succeeded")
y = EssVRetrieve(mySheetname, myrng, lockflag)
If y = 0 Then
MsgBox ("Retrieve successful.")
z = EssVDisconnect(mySheetname)
If z = 0 Then
MsgBox ("Disconnect Succeed.")
Else
MsgBox ("Disconnect failed.")
End If
Else
MsgBox ("Retrieve failed.")
End If
End If
End Sub
Variable x is supposed to return the status code (0 is success any other is failed).
So here comes the trick, whenever I run this macro within Excel it runs perfectly, however when I call it from C# using xlApp.Run("Essbase_Update_Pulls"); it returns a status code of -3.
Doing some research I found out that whenever an Excel Application is created in code it doesn't have the add-ins loaded, so they have to be manually loaded
https://community.oracle.com/thread/2480398 .
I iterated over the xlApp.AddIns and found that the "essexcln.xll" was correctly installed so I have no idea what to do now. Also I found out that Add-Ins can be added during runtime but this just causes an exception, here is the source:
http://www.network54.com/Forum/58296/thread/957392331/Visual+Basic-Excel+Api+call+to+Essbase
Found out that excel isn't loading all the dll's and xll's required to connect to de Essbase server. In order to make it work it is necessary to start excel as a process and the acquire the instance and relate it to the interop class. I found the solution here:Excel interop loading XLLs and DLLs. The user pretty much had the same problem but with Bloomberg. I would just add that in the SearchExcelInterop method it needs a Thread.Sleep() to wait for Excel to load properly, in my case it threw a StackOverflowException.

Using Windows Service to Create,Update,Delete CSV File using C# or VB.net

I am creating a windows service to save current username and logon time in a CSV file. But when I install the service, the file is just created, not details are written to it, and that file is set to read-only mode. what is the problem in my code?
My code:
Imports System.IO
Imports System.Text
Imports System.DirectoryServices
Imports System.DirectoryServices.AccountManagement
Imports System.Diagnostics
Public Class LoginService1
Protected Overrides Sub OnStart(ByVal args() As String)
Dim win As System.Security.Principal.WindowsIdentity
win = System.Security.Principal.WindowsIdentity.GetCurrent()
Dim Logon_UserName = win.Name.Substring(win.Name.IndexOf("\") + 1)
Dim pc As New PrincipalContext(ContextType.Machine, My.Computer.Name)
Dim uc As UserPrincipal = UserPrincipal.FindByIdentity(pc, Logon_UserName)
Dim str As String = ""
Try
Dim sr As New StreamReader("c:\logondetails.csv")
str = sr.ReadToEnd()
sr.Close()
sr.Dispose()
Catch ex As Exception
End Try
Try
Dim sw As New StreamWriter("c:\logondetails.csv")
Str += Logon_UserName & "," & uc.LastLogon.Value.ToString
sw.WriteLine(str)
sw.Close()
sw.Dispose()
Catch ex As Exception
End Try
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.'
End Sub
End Class
There are many ways to fix what you are doing.
For 1, you dont need to read in the entire file to append to the end of it. For example
using(var stream = File.AppendText(fileName))
{
stream.Write(string);
stream.Close();
}
But you are going to have issues with concurrent access to the file. You'd be better off using a logging framework, such as log4net or microsoft logging block, and then just
Logger.Info(yourstring);
and be done with it. The framework will handle the file access issues.

How to set a custom Icon of an Outlook folder?

Is there any way to set a custom Icon of an Outlook folder or subfolder using Outlook object model?
As from Outlook 2010 you can use MAPIFolder.SetCUstomIcon as described above.
I have had the same challenge recently and found a nice snippet of VBA code at
Change Outlook folders colors possible?:
joelandre Jan 12, 2015 at 9:13 PM
Unzip the file icons.zip to C:\icons
Define the code below as Visual Basic Macros
Adapt the function ColorizeOutlookFolders according to your needs Text
Function GetFolder(ByVal FolderPath As String) As Outlook.folder
' Returns an Outlook folder object basing on the folder path
'
Dim TempFolder As Outlook.folder
Dim FoldersArray As Variant
Dim i As Integer
On Error GoTo GetFolder_Error
'Remove Leading slashes in the folder path
If Left(FolderPath, 2) = "\\" Then
FolderPath = Right(FolderPath, Len(FolderPath) - 2)
End If
'Convert folderpath to array
FoldersArray = Split(FolderPath, "\")
Set TempFolder = Application.Session.Folders.Item(FoldersArray(0))
If Not TempFolder Is Nothing Then
For i = 1 To UBound(FoldersArray, 1)
Dim SubFolders As Outlook.Folders
Set SubFolders = TempFolder.Folders
Set TempFolder = SubFolders.Item(FoldersArray(i))
If TempFolder Is Nothing Then
Set GetFolder = Nothing
End If
Next
End If
'Return the TempFolder
Set GetFolder = TempFolder
Exit Function GetFolder_Error:
Set GetFolder = Nothing
Exit Function End Function Sub ColorizeOneFolder(FolderPath As String, FolderColour As String)
Dim myPic As IPictureDisp
Dim folder As Outlook.folder
Set folder = GetFolder(FolderPath)
Set myPic = LoadPicture("C:\icons\" + FolderColour + ".ico")
If Not (folder Is Nothing) Then
' set a custom icon to the folder
folder.SetCustomIcon myPic
'Debug.Print "setting colour to " + FolderPath + " as " + FolderColour
End If End Sub
Sub ColorizeFolderAndSubFolders(strFolderPath As String, strFolderColour As String)
' this procedure colorizes the foler given by strFolderPath and all subfolfers
Dim olProjectRootFolder As Outlook.folder
Set olProjectRootFolder = GetFolder(strFolderPath)
Dim i As Long
Dim olNewFolder As Outlook.MAPIFolder
Dim olTempFolder As Outlook.MAPIFolder
Dim strTempFolderPath As String
' colorize folder
Call ColorizeOneFolder(strFolderPath, strFolderColour)
' Loop through the items in the current folder.
For i = olProjectRootFolder.Folders.Count To 1 Step -1
Set olTempFolder = olProjectRootFolder.Folders(i)
strTempFolderPath = olTempFolder.FolderPath
'prints the folder path and name in the VB Editor's Immediate window
'Debug.Print sTempFolderPath
' colorize folder
Call ColorizeOneFolder(strTempFolderPath, strFolderColour)
Next
For Each olNewFolder In olProjectRootFolder.Folders
' recursive call
'Debug.Print olNewFolder.FolderPath
Call ColorizeFolderAndSubFolders(olNewFolder.FolderPath, strFolderColour)
Next
End Sub
Sub ColorizeOutlookFolders()
Call ColorizeFolderAndSubFolders("\\Personal\Documents\000-Mgmt-CH\100-People", "blue")
Call ColorizeFolderAndSubFolders("\\Personal\Documents\000-Mgmt-CH\200-Projects","red")
Call ColorizeFolderAndSubFolders("\\Personal\Documents\000-Mgmt-CH\500-Meeting", "green")
Call ColorizeFolderAndSubFolders("\\Personal\Documents\000-Mgmt-CH\800-Product", "magenta")
Call ColorizeFolderAndSubFolders("\\Personal\Documents\000-Mgmt-CH\600-Departments", "grey")
Call ColorizeFolderAndSubFolders("\\Mailbox - Dan Wilson\Inbox\Customers", "grey")
End Sub
In the object ThisOutlookSession, define the following function:
Private Sub Application_Startup()
ColorizeOutlookFolders
End Sub
and
In order to NOT color sub-folders, you can use the function
ColorizeOneFolder instead of ColorizeFolderAndSubFolders e.g.
Sub ColorizeOutlookFolders()
Call ColorizeOneFolder ("\\Personal\Documents\000-Mgmt-CH\100-People", "blue")
Call ColorizeOneFolder ("\\Personal\Documents\000-Mgmt-CH\200-Projects", "red")
Call ColorizeOneFolder ("\\Personal\Documents\000-Mgmt-CH\500-Meeting", "green")
Call ColorizeOneFolder ("\\Personal\Documents\000-Mgmt-CH\800-Product", "magenta")
Call ColorizeOneFolder ("\\Personal\Documents\000-Mgmt-CH\600-Departments", "grey")
Call ColorizeOneFolder ("\\Mailbox - Dan Wilson\Inbox\Customers", "grey")
End Sub
When you move sub-folders between folders, they should retain their
color only until the next time you restart Outlook.
From what I have read this is unfortunately not possible in Outlook 2007.
It is possible in Outlook 2010 using MAPIFolder.SetCustomIcon. See MSDN for more details: http://msdn.microsoft.com/en-us/library/ff184775.aspx
Switching the list of MAPIFolder methods between 2010 and 2007 on the following MSDN webpage shows the SetCustomIcon method for 2010 only: http://msdn.microsoft.com/en-us/library/bb645002.aspx

IO / HTTP error in Uploadify

I am trying to get uploadify to work. When I try and upload something the browse functionality works fine but there is a breif pause and then I get either an "http error" or an "IO error".
The progress bar doesn't display, which made me think it might be a path issue, but the swf file is in the same location as the images / scripts which it appears to be finding OK.
Anyone have any experience with this?
Did you use a generic handler (.ashx) for receiving the file? Here is my code
Public Class Video_File_Upload
Implements System.Web.IHttpHandler
'Dim File_Path_Chapter_Video As String = "XXX/"
Dim Directory_Videos As String = System.Configuration.ConfigurationManager.AppSettings("Videos_Save")
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.ContentType = "text/plain"
context.Response.Expires = -1
Try
Dim postedFile As HttpPostedFile = context.Request.Files("Filedata")
Dim filename As String = postedFile.FileName
'string folderName = context.Request.QueryString["FolderName"];
Dim NOF As String
Dim CheckFilePath As String
Dim MapPath As String
NOF = Convert.ToString(context.Request("NOF"))
CheckFilePath = Directory_Videos & NOF
If Directory.Exists(CheckFilePath) = False Then
Directory.CreateDirectory(CheckFilePath)
End If
MapPath = Directory_Videos & NOF & "/" & filename
postedFile.SaveAs(MapPath)
Catch
End Try
End Sub
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
Then you have to put this line in the upload setting: "uploadScript:Video_File_Upload.ashx"

Categories