For example, I deleted a record on a table on the database and my database is MS Aaccess. Any backup mechanisms that I can refer to? So that when I need a rollback of the database I just restore it quickly from code.
MS Access is the file based database, right? in my understanding, that means, when the connection is closed and the file is not in use, you can copy that file to another location.
Here I assume the application has such privileges on the file system.
Also, I agree with Morten Martner's answer, if the database type is MS SQL Server, then you will definitely need SMO library use.
I'm using the following code to backup SQL server databases:
using System;
using System.Collections.Generic;
using System.Data;
using System.Collections;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using System.Text;
namespace Codeworks.SqlServer.BackupDatabase
{
public class BackupCore
{
public static void Execute( string instance, string database, string outputFile )
{
BackupDeviceItem bdi = new BackupDeviceItem( outputFile, DeviceType.File );
Backup bu = new Backup();
bu.Database = database;
bu.Devices.Add( bdi );
bu.Initialize = true;
// add percent complete and complete event handlers
bu.PercentComplete += new PercentCompleteEventHandler(Backup_PercentComplete);
bu.Complete +=new ServerMessageEventHandler(Backup_Complete);
Server server = new Server( instance );
bu.SqlBackup( server );
}
protected static void Backup_PercentComplete( object sender, PercentCompleteEventArgs e )
{
// Console.WriteLine( e.Percent + "% processed." );
}
protected static void Backup_Complete( object sender, ServerMessageEventArgs e )
{
Console.WriteLine( e.ToString() );
}
}
}
You'll need the management libraries from MS for the correct SQL server version, but those are available for download.
If you're a single user of your database, you just need to close your connection and copy it with the file system.
If there are multiple users, then you should use a different method. If you actually have Access available, there's an undocumented command that will make a backup of the tables a Jet/ACE file:
Application.SaveAsText 6, vbNullString, strTargetMDB
Now, since this can only be done with the database open in the Access UI, it requires automating Access and operating on the CurrentDB. Here's an implementation that runs within Access:
Public Function CreateBackup(strMDBName As String, strBackupPath As String, _
Optional bolCompact As Boolean = False) As Boolean
On Error GoTo errHandler
Dim objAccess As Object
Dim strBackupMDB As String
Dim strCompactMDB As String
If Len(Dir(strBackupPath & "\*.*")) = 0 Then ' alternative: use File System Object for this
MkDir strBackupPath
End If
Set objAccess = New Access.Application
objAccess.Application.OpenCurrentDatabase strMDBName
strBackupMDB = "Backup" & Format(Now(), "YYYYMMDDhhnnss") & ".mdb"
Debug.Print strBackupPath & "\" & strBackupMDB
objAccess.Application.SaveAsText 6, vbNullString, strBackupPath & "\" & strBackupMDB
objAccess.Application.Quit
Set objAccess = Nothing
If bolCompact Then
strCompactMDB = strBackupPath & "\" & "c_" & strBackupMDB
Name strBackupPath & "\" & strBackupMDB As strCompactMDB
DBEngine.CompactDatabase strCompactMDB, strBackupPath & "\" & strBackupMDB
Kill strCompactMDB
End If
CreateBackup = (Len(Dir(strBackupPath & "\" & strBackupMDB)) > 0)
exitRoutine:
If Not (objAccess Is Nothing) Then
On Error Resume Next
objAccess.Application.Quit
On Error GoTo 0
Set objAccess = Nothing
End If
Exit Function
errHandler:
Select Case Err.Number
Case 75 ' Path/File access error -- tried to MkDir a folder that already exists
Resume Next
Case Else
MsgBox Err.Number & ": " & Err.Description, vbExclamation, "Error in CreateBackup()"
Resume exitRoutine
End Select
End Function
To run that from C# you'd have to automate Access, and you likely don't want a dependency on Access.
Since I work in Access exclusively, that's the method I use, so I've never programmed the more complicated methods.
If you have exclusive access to the database, you could use JRO CompactDatabase command to compact to a new filename, but if you have exclusive access, you can also use the file system.
So, basically, you've got choices about how to export the data tables to a backup database. You could use DoCmd.TransferDatabase to copy all the data tables, and then copy the relationships, or you could create an empty template database and append the data from each table in turn to a copy of the template (in an order that won't violate RI, of course).
Neither of those sounds anything but messy to me, and that's why I use the SaveAsText method! But if I wasn't running Access, the other two alternatives would be worth doing.
Related
I've written a C# application with .net framework. The purpose is to request data from an online spreadsheet app, do stuff with it, then send back updated data.
I think the best way to trigger the exe would be to use webhooks/callbacks, but I gather this would require runnning my program on a web sever with an external IP address.
Rather than periodically polling the spreadsheet app I would like the app to send emails to a specified account upon certain data changes. Upon receiving the email, VBA code checks that the email is from the app then runs the executable.
To run exe on receipt of email:
Private Sub Application_NewMail()
Dim path As String
Dim shl As Variant
path = "C:\Users\***\Desktop\SmartPlugin.exe"
shl = Shell(path, 1)
End Sub
How do I check the sender? The examples I found online loop through all emails but what I'm after is a method of returning the last email received.
Use Application.NewMailEx event instead - it passes the entry id of the new message as the parameter. Use that entry id to call Application.Session.GetItemfromID.
Got it working.
Private Sub Application_NewMail()
Dim objN As NameSpace
Dim objF As MAPIFolder
Set objN = GetNamespace("MAPI")
Set objF = objN.GetDefaultFolder(olFolderInbox)
Set mlItems = objF.Items
mlItems.Sort "CreationTime", True
Set mlItem = mlItems.Item(1)
Dim path As String
Dim shl As Variant
Dim sndString As String
sndString = CStr(mlItem.SenderName)
If InStr(1, sndString, "SmartSheet", vbTextCompare) > 0 Then
path = "C:\Users\Alex Rose\Desktop\SmartPlugin.exe"
shl = Shell(path, 1)
End If
End Sub
Is there any way to delete history & cookies of Microsoft Edge browser using VBScript or .net?
Like Internet Explorer, deleting the history form "%AppData%\Local\Microsoft\Windows\History" folder or Rundll32 commands?
Rundll32 commands
Delete Cookies:
rundll32.exe,InetCpl.cpl,ClearMyTracksByProcess 2
Delete History:
rundll32.exe,InetCpl.cpl,ClearMyTracksByProcess 1
Edit:
Found an solution for clearing cookie http://winhelp2002.mvps.org/cookies.htm. Deleting files from following 4 folders will clear cookies without affecting history and cache.
1. \Users\user name\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\#!001\MicrosoftEdge\Cookies
2. \Users\user name\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\#!002\MicrosoftEdge\Cookies
3. \Users\user name\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\#!121\MicrosoftEdge\Cookies
4. \Users\user name\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\MicrosoftEdge\Cookies
Still need help to clear history without affecting cookie and cache
This is not Safe But First You need To Close Microsoft Edge browser, Then you should delete All Sub_Folders and Files are in :
"C:\Users\[username]\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"
Change [username] with your own Windows Username.
VB Script Code :
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder("C:\Users\[username]\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe")
for each f in folder.Files
On Error Resume Next
name = f.name
f.Delete True
If Err Then
WScript.Echo "Error deleting:" & Name & " - " & Err.Description
Else
WScript.Echo "Deleted:" & Name
End If
On Error GoTo 0
Next
For Each f In folder.SubFolders
On Error Resume Next
name = f.name
f.Delete True
If Err Then
WScript.Echo "Error deleting:" & Name & " - " & Err.Description
Else
WScript.Echo "Deleted:" & Name
End If
On Error GoTo 0
Next
Note : Run This Source AS ADMIN
Another Way :
Call WshShell.Run("powershell -command Get-AppXPackage -AllUsers -Name Microsoft.MicrosoftEdge | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “$($_.InstallLocation)\AppXManifest.xml” -Verbose}")
RUN AS ADMIN TOO
Is it possible to ask Excel to start a C# method?
How would you implement such a call in Excel?
(i.e. instead of programming in VB, I would like to program in C#)
I can imagine using a VB-macro to start a C# application in the background but maybe you know a nicer way?
For example, the C#-code shall be executed upon a click in a particular Excel cell.
Well you could open a program via VBA. This VBA script gets called by clicking on the Excel-Cell:
var Path = "MYPROGRAMPATH"
var Argument = "MYARGUMENT"
x = Shell("""" & Path & """ """ & Argument & """", vbNormalFocus)
To react on a cell change, use the following event:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'YOUR CODE
End Sub
Then program your C# application and let it determine the arguments.
Your program should react according to the filtered arguments.
This can be done with the Environment.GetCommandLineArgs-Method.
public static void Main()
{
Console.WriteLine();
// Invoke this sample with an arbitrary set of command line arguments.
String[] arguments = Environment.GetCommandLineArgs();
Console.WriteLine("GetCommandLineArgs: {0}", String.Join(", ", arguments));
//Handling of arguments here, switch-case, if-else, ...
}
I've found a solution to the VBA macro:
Sub Button1_Click()
Dim pathStr As String
Dim argumentStr As String
pathStr = "C:/Users/.../Desktop/temp/Trial02.exe"
argumentStr = "Any argument string"
Call Shell("""" & pathStr & """ """ & argumentStr & """", vbNormalFocus)
End Sub
I'm writing a program that moves docs from one app to another in ApplicationXtender (AX). The AX full-featured client already has such a program (Migration Wizard) that can handle the task, so I created a function that launches it using Process.Start() and supplying the arguments necessary to automate it. When I call the function from a console app or windows form app, the Migration Wizard works perfectly. But the process must be initiated by an event in a web-based workflow project, so I wrote a web service that contains the same function, and then I use an invoke web service control in the workflow to start it. When I consume the function from the web service, the process doesn't complete. I can see it hanging in the task manager. I'm pretty sure it has to do with the user settings in IIS, but I'm not familiar enough with IIS to make any significant difference. I've configured the anonymous authentication's user identity in IIS to launch with a specific user with full rights to AX, and set the DefaultAppPool to run as Local System, but neither worked. I'm thinking I may need to impersonate the user, but I don't know how to do that. Any suggestions?
For reference, here is my code:
Consume Service Code-
Sub Main()
Dim dbName As String
Dim appName As String
Dim preSalesNum As String
Console.WriteLine("Database: ")
dbName = Console.ReadLine
Console.WriteLine("")
Console.WriteLine("Application")
appName = Console.ReadLine
Console.WriteLine("")
Console.WriteLine("Pre-Sales Number:")
preSalesNum = Console.ReadLine
Console.WriteLine("")
MoveDocs.MoveDocs(dbName, appName, preSalesNum)
End Sub
MoveDocs Function (inside of a separate class)-
Public Shared Function MoveDocs(ByVal dbName As String, ByVal appName As String,
ByVal preSalesNum As String) As String
Try
Dim sourceApp As String
If appName = "PRE_SALES_PROJECTS" Then
sourceApp = "PROJECTS"
Else
sourceApp = "LOOSE-FURNITURE"
End If
Dim argsString As String = "/SD " & dbName & " /SU username /SP password /SA
" & appName & " /DD " & dbName & " /DU username /DP password /DA " &
sourceApp & " /S " & """" & preSalesNum & """" & " /A"
Dim procProp As New System.Diagnostics.ProcessStartInfo
With procProp
.FileName = "C:\Program Files (x86)\XtenderSolutions\Content
Management\MigrateWiz32.exe"
.Arguments = argsString
End With
Dim proc As System.Diagnostics.Process =
System.Diagnostics.Process.Start(procProp)
Return argsString
Catch ex As Exception
Return ex.ToString()
End Try
End Function
The MoveDocs() function in the service.asmx file is identical to the one above, minus the 'shared' modifier in the declaration. The app works, the web service doesn't.
ProcessStartInfo has properties for username, password and domain. There's more info on MSDN -
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.password.aspx
People claim the following VB script works for changing network adapter names. However I am having a decidedly difficult time trying to convert this to a c# appliaction that can do the same thing. The problem I seem to be facing is that calls to the NetworkInterface.Name is readonly.
Option Explicit
Const NETWORK_CONNECTIONS = &H31&
Dim sOldName= WScript.Arguments(0)
Dim sNewName= WScript.Arguments(1)
Dim objShell, objFolder, colItems, objItem
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(NETWORK_CONNECTIONS)
Set colItems = objFolder.Items
For Each objItem in colItems
If objItem.Name = sOldName Then
objItem.Name =sNewName
End If
Next
I found this which explains it a bit more: http://blogs.technet.com/b/heyscriptingguy/archive/2005/05/11/how-can-i-rename-a-local-area-connection.aspx.
Ok, so there are special folders where the NIC names are stored and you access those folders by binding to the them via the SHELL. How then do you do something like this in c#?
You can change the name of a NIC easily through the registry if you know how the registry structure works.
You will need the NetworkAdapters GUID in order to locate which path to open. To get the network adapter GUID I recommend first querying the WMI "Win32_NetworkAdapter" class. There is a GUID property along with all the other properties needed to identify specific adapters.
You will notice this GUID in the registry path: {4D36E972-E325-11CE-BFC1-08002BE10318}Visit link for information on it:
http://technet.microsoft.com/en-us/library/cc780532(v=ws.10).aspx
string fRegistryKey = string.Format(#"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\{0}\Connection", NIC_GUID);
RegistryKey RegistryKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, #"\\" + Server.Name);
RegistryKey = RegistryKey.OpenSubKey(fRegistryKey, true); //true is for WriteAble.
RegistryKey.SetValue("Name", "<DesiredAdapterName>");
By design the windows UI will not allow for duplicate NIC names. However, you can force duplicate NIC names via the registry. We have done tests, there seem to be nothing critically effected by having duplicate names. Windows seems to still function fine. You just want to be wary about scripting against NIC names if you don’t incorporate anti-duplicate name logic.
To create uniqueness you can use the adapter index property associated with the WMI query.
You can use the System.Management assembly and use this class.
Follow the sample here - http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/727c8766-8189-4ad6-956d-958e52b97c05/
You can also create a VB.NET dll with the functionality you need and reference and call it from your C# code.
Here is a console app demonstrating the code (I tested and it works :)
Option Explicit On
Module Module1
Sub Main()
Const NETWORK_CONNECTIONS = &H31&
Dim sOldName = "Local Area Connection"
Dim sNewName = "Network"
Dim objShell, objFolder, colItems, objItem
objShell = CreateObject("Shell.Application")
objFolder = objShell.Namespace(NETWORK_CONNECTIONS)
colItems = objFolder.Items
For Each objItem In colItems
Console.WriteLine(objItem.Name)
If objItem.Name = sOldName Then
objItem.Name = sNewName
End If
Console.WriteLine(objItem.Name)
Next
End Sub
End Module
It prints out:
Local Area Connection
Network