При использовании функции SQL Server Express 2005's User Instance со строкой подключения как это:
<add name="Default" connectionString="Data Source=.\SQLExpress;
AttachDbFilename=C:\My App\Data\MyApp.mdf;
Initial Catalog=MyApp;
User Instance=True;
MultipleActiveResultSets=true;
Trusted_Connection=Yes;" />
Мы находим, что не можем скопировать файлы базы данных MyApp.mdf и MyApp_Log.ldf (потому что они заблокированы), даже после остановки услуг SqlExpress, и должны обратиться к установке услуг SqlExpress от автоматического до ручного режима запуска и затем перезапуска машины, прежде чем мы сможем затем скопировать файлы.
Это было мое понимание, что остановка услуг SqlExpress должна остановить все пользовательские экземпляры также, которые должны выпустить блокировки на тех файлах. Но это, кажется, не имеет место - кто-либо мог пролить некоторый свет на то, как остановить пользовательский экземпляр, такой, что это - файлы базы данных, больше не блокируются?
Обновление
Хорошо, я прекратил быть ленивым и разжег Проводник Процесса. Блокировка была сохранена sqlserver.exe - но существует два экземпляра SQL-сервера:
sqlserver.exe PID: 4680 User Name: DefaultAppPool
sqlserver.exe PID: 4644 User Name: NETWORK SERVICE
Файл открыт экземпляром sqlserver.exe с PID: 4680
Остановка "SQL Server (SQLEXPRESS)" сервис, избавленный процесс с PID: 4644, но оставленный PID: 4 680 один.
Наблюдением как владельца остающегося процесса был DefaultAppPool, следующая вещь, которую я попробовал, останавливала IIS (эта база данных используется из приложения ASP.NET). К сожалению, это не уничтожило процесс прочь также.
Вручную уничтожение остающегося процесса SQL-сервера действительно удаляет открытый дескриптор файла на файлах базы данных, позволяя им копироваться/перемещаться.
К сожалению, я хочу копировать/восстанавливать те файлы в некоторых пред/сообщение задачи установки установщика WiX - как таковой, я надеялся, что мог бы быть способ достигнуть этого, остановив сервис окон, скорее затем имея необходимость выйти из оболочки для уничтожения всех экземпляров sqlserver.exe, поскольку это создает некоторые проблемы:
У кого-либо есть дальнейшие мысли о том, как завершить работу экземпляров SQL-сервера, связанного с определенным пользовательским экземпляром?
Используйте «Утилиту SQL Server Express» (SSEUtil.exe) или команду, чтобы отсоединить базу данных, используемую SSEUtil.
Утилита SQL Server Express, SSEUtil - это инструмент, который позволяет легко взаимодействовать с SQL Server, http://www.microsoft.com/downloads/details.aspx? FamilyID = fa87e828-173f-472e-a85c-27ed01cf6b02 & DisplayLang = ru
Кроме того, тайм-аут по умолчанию для остановки службы после закрытия последнего соединения составляет один час. В окне разработки вы можете изменить это значение на пять минут (минимально допустимый).
Кроме того, у вас может быть открытое соединение через подключения к данным Server Explorer в Visual Studio, поэтому обязательно отключитесь от любой существующей базы данных.
H:\Tools\SQL Server Express Utility>sseutil -l
1. master
2. tempdb
3. model
4. msdb
5. C:\DEV_\APP\VISUAL STUDIO 2008\PROJECTS\MISSICO.LIBRARY.1\CLIENTS\CORE.DATA.C
LIENT\BIN\DEBUG\CORE.DATA.CLIENT.MDF
H:\Tools\SQL Server Express Utility>sseutil -d C:\DEV*
Failed to detach 'C:\DEV_\APP\VISUAL STUDIO 2008\PROJECTS\MISSICO.LIBRARY.1\CLIE
NTS\CORE.DATA.CLIENT\BIN\DEBUG\CORE.DATA.CLIENT.MDF'
H:\Tools\SQL Server Express Utility>sseutil -l
1. master
2. tempdb
3. model
4. msdb
H:\Tools\SQL Server Express Utility>
Используя .NET Refector, следующая команда используется для отсоединения базы данных.
string.Format("USE master\nIF EXISTS (SELECT * FROM sysdatabases WHERE name = N'{0}')\nBEGIN\n\tALTER DATABASE [{1}] SET OFFLINE WITH ROLLBACK IMMEDIATE\n\tEXEC sp_detach_db [{1}]\nEND", dbName, str);
Я использовал следующий вспомогательный метод для отсоединения файлов MDF, прикрепленных к SQL Server, в модульных тестах (так что SQ Server снимает блокировки с файлов MDF и LDF, и модульный тест может очищать после себя) ...
private static void DetachDatabase(DbProviderFactory dbProviderFactory, string connectionString)
{
using (var connection = dbProviderFactory.CreateConnection())
{
if (connection is SqlConnection)
{
SqlConnection.ClearAllPools();
// convert the connection string (to connect to 'master' db), extract original database name
var sb = dbProviderFactory.CreateConnectionStringBuilder();
sb.ConnectionString = connectionString;
sb.Remove("AttachDBFilename");
var databaseName = sb["database"].ToString();
sb["database"] = "master";
connectionString = sb.ToString();
// detach the original database now
connection.ConnectionString = connectionString;
connection.Open();
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = "sp_detach_db";
cmd.CommandType = CommandType.StoredProcedure;
var p = cmd.CreateParameter();
p.ParameterName = "@dbname";
p.DbType = DbType.String;
p.Value = databaseName;
cmd.Parameters.Add(p);
p = cmd.CreateParameter();
p.ParameterName = "@skipchecks";
p.DbType = DbType.String;
p.Value = "true";
cmd.Parameters.Add(p);
p = cmd.CreateParameter();
p.ParameterName = "@keepfulltextindexfile";
p.DbType = DbType.String;
p.Value = "false";
cmd.Parameters.Add(p);
cmd.ExecuteNonQuery();
}
}
}
}
Примечания:
Возможно, это не то, что вы ищете, но бесплатный Инструмент Unlocker имеет интерфейс командной строки, который можно запустить из WIX. (Некоторое время я использовал unlocker и нашел его стабильным и очень хорошим в том, что у него получается лучше всего - разблокировка файлов.)
Unlocker может разблокировать и переместить / удалить практически любой файл.
Обратной стороной этого является то, что приложения, которым требуется блокировка файла, больше не будут иметь ее. (Но иногда все еще отлично работает.Обратите внимание, что это не убивает процесс, у которого есть блокировка. Он просто снимает блокировку. (Возможно, перезапуска служб sql, которые вы останавливаете, будет достаточно для повторной блокировки и / или правильной работы.)
Вы можете получить Unlocker отсюда: http: //www.emptyloop. com / unlocker /
Чтобы увидеть параметры командной строки, запустите unlocker -H
Вот они для удобства:
Unlocker 1.8.8 Command line usage: Unlocker.exe Object [Option] Object: Complete path including drive to a file or folder Options: /H or -H or /? or -?: Display command line usage /S or -S: Unlock object without showing the GUI /L or -L: Object is a text file containing the list of files to unlock /LU or -LU: Similar to /L with a unicode list of files to unlock /O or -O: Outputs Unlocker-Log.txt log file in Unlocker directory /D or -D: Delete file /R Object2 or -R Object2: Rename file, if /L or /LU is set object2 points to a text file containing the new name of files /M Object2 or -M Object2: Move file, if /L or /LU is set object2 points a text file containing the new location of files
Предполагается, что вашей целью было заменить C: \ My App \ Data \ MyApp.mdf с файлом из установщика, вам понадобится что-то вроде unlocker C: \ My App \ Data \ MyApp.mdf -S -D
. Это приведет к удалению файла, чтобы вы могли скопировать его в новый.