We have an app that uses a sqlexpress db. We need our customers to be able to swap the database for this app out for another sqlexpress db fairly easily. So we came up with a small launcher app that allows them to choose the db they want from a drop down list. It then detaches the current db and attaches the db that they chose and launches the program.

I tried to automate the set up of the multiple databases. Our process is to install the initial db and then detach and rename the .mdf and .ldf files. We then run our software and it gets a fresh copy of the db. So I added a new db button that when clicked does exactly that. In windows xp this works without problem. However in windows vista and 7 I get an exception that folder access is denied for renaming the .ldf file. The .mdf file renames without issue. I tried manually renaming the two files to see if it was a permissions issue with the DATA folder in sqlserver. With this test I found that I can simply right click and rename the .mdf file, but the .ldf causes the UAC prompt to come up so that I can grant it permission to be renamed.

I'm assuming that the UAC prompt is my problem but when I try to rename the file programmatically I do not get the prompt, just an exception.

What is the best way to deal with the UAC?

Thanks

Dani AI

Generated

Short summary and practical fixes (builds on and )

Your symptom (the .mdf can be renamed but the .ldf triggers UAC / access denied on Vista/7) is exactly the sort of scenario where ClickOnce elevation and Windows file-protection collide. Editing the app manifest to request elevation will break ClickOnce publishing, so the manifest route is not a reliable fix for a ClickOnce-deployed launcher. (learn.microsoft.com)

Workarounds that avoid elevating the ClickOnce process

  • Let SQL Server do the file work. Detach/attach or perform a RESTORE so the SQL service performs file I/O under its service account instead of your UI process. Typical flow: EXEC sp_detach_db 'MyDb' then CREATE DATABASE MyDb ... FOR ATTACH ( FILENAME='C:\path\MyDb.mdf', LOG ON (FILENAME='C:\path\MyDb_log.ldf') );. This avoids UAC because the service, not the interactive user, touches the files. (documentation.help)
  • Move your database files out of protected folders (do not use Program Files). Use a machine-wide data folder such as C:\ProgramData\YourApp\DBs or a dedicated data path and grant the SQL service account access to that folder (service SIDs like NT SERVICE\MSSQLSERVER / NT SERVICE\MSSQL$InstanceName are commonly used). That lets non-elevated code copy/prepare files in a location the service can attach later. (learn.microsoft.com)

Diagnostics and a minimally-invasive helper

  • Before renaming, check whether SQL still has a handle on the .ldf: use Process Explorer or Sysinternals Handle to find/close handles or confirm detach completed. That confirms if the exception is a lock vs. an ACL/UAC block. (learn.microsoft.com)
  • If you must perform privileged filesystem changes from the UI, ship a small out-of-band helper (MSI/installer installs a Windows service or an EXE with an embedded manifest) that runs elevated and exposes a safe API (local named pipe / WCF). The ClickOnce app can call that helper; elevation is requested at install time, not via ClickOnce. Microsoft guidance also recommends moving admin tasks into a separate elevated process. (learn.microsoft.com)

Example: launch an external helper (this triggers a UAC prompt when run)

var psi = new ProcessStartInfo("MyHelper.exe") { Verb = "runas", UseShellExecute = true };
Process.Start(psi);

TL;DR — for ClickOnce: do not rely on manifest elevation. Prefer SQL-driven attach/restore or a small per-machine privileged helper and keep DB files out of Program Files; use Process Explorer to prove whether the .ldf is still locked before trying to rename.

Recommended Answers

All 4 Replies

You need to change the projects manifest file a bit.

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <applicationRequestMinimum>
        <PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
        <defaultAssemblyRequest permissionSetReference="Custom" />
      </applicationRequestMinimum>
      <!-- Add these lines if missing, else change level from 'AsInvoker' to 'requireAdministrator' -->
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v2">
        <!-- UAC Manifest Options -->
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</asmv1:assembly>

Thank you for the reply. I tried this but received an error when I went to publish. I'm deploying as a clickonce app and it says that:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

is not available for clickonce deployment. Is there something else I need to do along with this?

If this has been helpful, please mark this thread as solved.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.